必须用<ul>包裹标签云,因其语义化表达无序关键词集合,支持屏幕阅读器识别和SEO索引;禁用<div>堆砌,避免丢失语义、损害无障碍与搜索可见性。

必须用 <ul> 包裹,别用 <div> 堆标签
标签云不是视觉装饰,而是语义化的关键词集合。用 <ul class="tag-cloud"> 是唯一合理结构——它告诉屏幕阅读器“这是一组无序关键词”,也让搜索引擎能提取每个 <a> 的文本和 href 作为可索引内容。用 <div> 套一堆 <span> 或 <a>,等于主动放弃语义、SEO 和无障碍支持。
常见错误包括:
- 在
<ul>内写 HTML 注释或换行符,生成空白文本节点,破坏inline-flex布局 - 把所有标签塞进一个
<div class="cloud">,结果爬虫根本识别不出这是关键词列表 - 用
<p>或<section>替代<ul>,丢失集合关系,CSS 选择器也难维护
data-weight 必须归一化为 1–4 整数档
原始词频(比如 “React” 出现 237 次,“TypeScript” 出现 89 次)不能直接当 data-weight 值用。否则 CSS 映射时小词字体缩到 0.3em、大词冲到 2.5em,视觉失衡且移动端极易溢出。
正确做法是后端或 JS 归一化:
立即学习“前端免费学习笔记(深入)”;
- 取所有词频最大值
maxFreq - 对每个词计算
Math.round((freq / maxFreq) * 4) - 用
Math.min(4, Math.max(1, ...))强制截断,确保值始终在 1–4 范围内 - 避免
Math.log(freq + 1):对 freq=1 和 freq=5 输出几乎一样,调试时完全看不出差异
最终 HTML 示例:<a href="/tag/react" data-weight="4">React</a>,<a href="/tag/typescript" data-weight="2">TypeScript</a>
布局用 inline-flex 还是 inline-block?看兼容性需求
两者都能实现水平排列+自动换行,但行为差异直接影响调试效率和上线稳定性:
-
inline-flex:支持gap和justify-content,代码更干净;但 Safari 14.1 及更早版本有flex-wrap: wrap换行错位 bug -
inline-block:IE11 完全支持,兼容性稳;但需处理元素间空白符间隙——给容器设font-size: 0,再给每个标签单独设font-size: 1rem - 禁用
float: left:父容器易塌陷,响应式断点下换行位置不可控,现代 CSS 已无保留理由
CSS 示例(inline-block 方案):
.tag-cloud { font-size: 0; text-align: center; }<br>.tag-cloud a { display: inline-block; font-size: 1rem; margin: 0.3em 0.5em; }
字号必须用 em 或 clamp(),禁用 px
px 字号在系统缩放、高对比度模式、字体偏好设置下会失效,直接损害可访问性。浏览器缩放 200% 时,font-size: 14px 仍显示为 14 像素,而用户实际需要的是相对视觉尺寸。
推荐方案:
- 简单场景:用
em分档映射,例如a[data-weight="1"] { font-size: 0.85em; }、a[data-weight="4"] { font-size: 1.4em; } - 响应式更强场景:用
clamp(0.85em, 1rem + 0.2vw, 1.4em),兼顾小屏可读与大屏张力 - 动态注入时:JS 设置 CSS 自定义属性
--weight,再用font-size: clamp(12px, calc(12px + var(--weight) * 6px), 20px),注意--weight必须是归一化后的 0–1 值
别在容器上设 font-size: 0 后又用 em ——这会让子元素的 em 相对于 0 计算,结果全是 0。
最常被忽略的一点:权重归一化必须在数据进入 DOM 前完成。如果 API 返回的频次已经是归一化值(比如 0.23、0.87),就别再除一遍最大值——那会导致所有 data-weight 变成 1,整个云扁平化。



















