使用 HTML 和 CSS 创建标签云
标签云是与某个术语或标签相关的链接列表。它们常见于博客和网站中,用于直观地突出热门话题:热门词汇/类别的字体较大,而冷门话题的字体较小。
无需了解其效率和可用性(或缺乏可用性)的细节,标签/词云引人注目且美观,是可视化网站或文章整体内容的好方法。
在本文中,我们将学习如何使用 HTML 和 CSS 创建标签云。需要注意的是,每个词条的权重/流行度必须使用不同的语言预先计算。我们将专注于演示。
基本 HTML 结构
正如我们之前提到的,标签云是一个链接列表。因此,从语义的角度来看,使用无序列表(<ul>
)是合理的,因为这些词条不会按流行度排序……否则,它将是一个相当无趣的云。
每个列表项内都会有一个指向标签/术语搜索页面的链接。这将引导我们形成一个基本而直接的结构:
<ul>
<li><a href="/tag/word1">Word1</a></li>
<li><a href="/tag/word2">Word2</a></li>
<li><a href="/tag/word3">Word3</a></li>
<!-- ... -->
</ul>
每个单词的流行度(或权重)将被预先计算,并且应该将其添加到<li>
或中的每个项目中<a>.
,我们将选择将其放在链接上,但它可以在列表项级别。
权重越高意味着标签越受欢迎,应该以较大的字体显示:
<ul>
<li><a href="/tag/word1" data-weight="3">Word1</a></li>
<li><a href="/tag/word2" data-weight="7">Word2</a></li>
<li><a href="/tag/word3" data-weight="4">Word3</a></li>
<!-- ... -->
</ul>
注意:另一种方法是使用
data-count
anddata-total
直接在 CSS 中计算权重。这在标准下是可行的,但目前还没有浏览器支持(我们稍后会看到)。为了避免这种情况,我们可以为每个标签添加两个数据属性:data-weight
anddata-count
。这样效果会更好。为了简单起见,我们只关注一个数据属性:data-weight.
这样,我们就几乎完成了 HTML 结构 - 稍后会有一些更改,但我们不要超越自己 - 我们仍然想稍微调整一下<ul>
以添加一些属性:
class
:这将有助于确定要将哪些列表设置为云的样式。role
:这是一个导航组件;我们希望屏幕阅读器和其他辅助技术(AT)能够识别它。aria-label
:用于为 AT 提供“标题”或描述。
role="navigation"
注意:如果列表位于标签内,我们可以跳过<nav>
。aria-label,
我们可以使用aria-labelledby
来指向导航标题。
让我们扩展示例中的 HTML,同时包括 Web 开发术语,以使其成为更现实的示例:
<ul class="cloud" role="navigation" aria-label="Webdev tag cloud">
<li><a data-weight="4" href="/tag/http">HTTP</a></li>
<li><a data-weight="2" href="/tag/ember">Ember</a></li>
<li><a data-weight="5" href="/tag/sass">Sass</a></li>
<li><a data-weight="8" href="/tag/html">HTML</a></li>
<li><a data-weight="6" href="/tag/flexbox">FlexBox</a></li>
<li><a data-weight="4" href="/tag/api">API</a></li>
<li><a data-weight="5" href="/tag/vuejs">VueJS</a></li>
<li><a data-weight="6" href="/tag/grid">Grid</a></li>
<li><a data-weight="3" href="/tag/rest">Rest</a></li>
<li><a data-weight="9" href="/tag/javascript">JavaScript</a></li>
<li><a data-weight="3" href="/tag/animation">Animation</a></li>
<li><a data-weight="7" href="/tag/react">React</a></li>
<li><a data-weight="8" href="/tag/css">CSS</a></li>
<li><a data-weight="1" href="/tag/cache">Cache</a></li>
<li><a data-weight="3" href="/tag/less">Less</a></li>
</ul>
我们的标签云现在看起来是这样的:
它只是一个简单的链接列表,没有任何样式或任何令人瞠目结舌的功能......让我们改变它。
标签云的样式
这些是我们将使用 CSS 添加的功能:
- 删除列表外观并使其内联。
- 使标签的字体大小直接取决于
data-weight.
- 在标签旁边添加标签的重量。
- 提供“随机化”标签的颜色。
:hover
为和状态添加动画:focus
,提供一种可访问的替代方法来避免运动。
造型<ul>
首先,我们删除列表项中的圆圈,并删除列表缩进,list-style
并将 apadding-left
设为零:
list-style: none;
padding-left: 0;
然后,我们将ul
的显示设置为Flexbox,将项目垂直和水平居中对齐,并通过换行确保所有元素都可见:
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
添加line-height
以确保一些垂直单词间距后,最终的样式ul
如下所示:
ul.cloud {
list-style: none;
padding-left: 0;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
line-height: 2.5rem;
}
我们的标签云看起来仍然不太像标签云:
根据权重/受欢迎程度调整标签大小
让我们先对链接进行一些样式设计:
ul.cloud a {
color: #a33;
display: block;
font-size: 1.5rem;
padding: 0.125rem 0.25rem;
text-decoration: none;
position: relative;
}
使用上述样式,所有标签/单词将呈红色,并具有 1.5 rem 的固定大小:
我们希望根据属性设置字体大小data-weight
。那么……该怎么做呢?
attr()
Web 标准包含一种使用函数从 CSS 读取 HTML 数据属性的方法。我们可以data-weight
通过如下方式读取 的值:
attr([attribute-name] [attribute-unit]? [, default-value]?)
不幸的是,目前任何浏览器都不支持该符号和功能。相反,attr()
它只会返回一个字符串,并且只能在content
属性中使用。
如果标准符号有效,我们可以读取带有权重(或总数和计数,如上所述)的数据属性,将它们保存到CSS 变量中,然后直接对它们进行操作,如下所示:
ul.cloud a {
--size: attr(data-weight number, 2);
font-size: calc(var(--size) * 1rem);
}
……但我们不能这么做。相反,我们可以添加一组基于属性( data-attribute)的选择器的 CSS 规则。
ul.cloud a[data-weight="1"] { --size: 1; }
ul.cloud a[data-weight="2"] { --size: 2; }
ul.cloud a[data-weight="3"] { --size: 3; }
ul.cloud a[data-weight="4"] { --size: 4; }
ul.cloud a[data-weight="5"] { --size: 5; }
ul.cloud a[data-weight="6"] { --size: 6; }
ul.cloud a[data-weight="7"] { --size: 7; }
ul.cloud a[data-weight="8"] { --size: 8; }
ul.cloud a[data-weight="9"] { --size: 9; }
ul.cloud a {
--size: 4;
font-size: calc(var(--size) * 0.25rem + 0.5rem);
/* ... */
}
将其与计算字体大小的新函数(保留原始函数会导致尺寸过大)相结合,可以得到一个基本的标签云:
这只是我们的第一次迭代。只需添加几行 CSS,我们就可以为组件添加更多功能(和特色)。
在标签旁边添加标签的受欢迎程度
许多标签云不仅显示术语,还显示其旁边的权重/值。
content
我们得到了值。它位于我们用来指定字体大小的数据属性中。在伪元素中显示数据属性非常简单,例如::after
:
ul.cloud[data-show-value] a::after {
content: " (" attr(data-weight) ")";
font-size: 1rem;
}
我们在云端添加了一个属性选择器:[data-show-value]
。这是设计使然。添加后,只有当列表包含数据属性 时,才会显示值/数量/重量data-show-value
。如果没有,则不会显示数字。
这样,我们就为我们的 Web 组件添加了自定义功能:
- 添加
data-show-value
:显示数字 - 删除/不添加
data-show-value
:不显示数字。
注意:数据属性
data-show-value
是一个布尔值,其工作方式类似于controls
标签video
:一旦出现,它就会激活功能,即使传递的值是“false”。
添加后data-show-value
我们的词云将如下所示:
我们将在演示的剩余部分停用/删除该属性。
添加颜色
单色云看起来有点单调。我们要添加一些颜色来让它更生动。我们将尝试两种不同的方法。
使用“随机”颜色
CSS 中没有随机性(尽管可以模拟)。我们要做的是使用以下选择器,根据标签的顺序为其添加不同的颜色:
ul.cloud li:nth-child(2n+1) a { --color: #181; }
ul.cloud li:nth-child(3n+1) a { --color: #33a; }
ul.cloud li:nth-child(4n+1) a { --color: #c38; }
这样,我们将在现有的红色中添加一些绿色、蓝色和紫色。它们会遵循一定的模式,但用户可能不太容易察觉:
使用相同颜色的不同色调
与 TagCrowd 的做法类似(见第一张图片),我们可以通过增加对比度来突出显示热门标签。在浅色背景上,可以通过将标签颜色调深来实现。
HSL 颜色格式对此非常方便。但更快捷的方案是,将标签设置为与data-weight
(转换为 CSS 变量--size
)成反比的半透明状态:
ul.cloud a {
opacity: calc((15 - (9 - var(--size))) / 15);
/* ... */
}
使用此代码(而不是上一节中的代码),标签云如下所示:
自定义大纲
触摸 时outline
务必格外小心。它是可访问性的关键属性,错误的值可能会使残障人士难以使用该组件(或整个网站)。
在这种情况下,我们将添加与文本相同颜色的边框,替换(而不是删除)焦点上的默认轮廓。
ul.cloud a:focus {
outline: 1px dashed;
}
再次强调:修改大纲时务必格外小心。此部分为可选。
添加动画
为了增加一些交互性,我们将添加一个简单的动画:当用户关注或悬停在其中一个链接上时,背景将水平改变颜色。
因为它是一个依赖于状态的动画,所以我们将使用transition
而不是animation
属性。
我们将添加一个::before
没有宽度的伪元素,并且在:focus
或上:hover
,我们将宽度更新为容器的 100%,从而创建微交互。
CSS代码或伪元素和状态行为是:
ul.cloud a::before {
content: "";
position: absolute;
top: 0;
left: 50%;
width: 0;
height: 100%;
background: var(--color);
transform: translate(-50%, 0);
opacity: 0.15;
transition: width 0.25s;
}
ul.cloud a:focus::before,
ul.cloud a:hover::before {
width: 100%;
}
关于动画,最后还有一点:用户可能不喜欢这些动画,并将它们禁用。如果出现这种情况,务必尊重用户的偏好并移除这些动画。
这可以通过[ prefers-reduced-motion
]媒体功能]( https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion ) 实现。
@media (prefers-reduced-motion) {
ul.cloud * {
transition: none !important;
}
}
这样,我们的标签云就完成了!以下是包含以上所有代码的演示:
结论
创建标签云的方法有很多种:使用 HTML 和 CSS、使用列表、不使用列表、使用 JavaScript……所有(或大多数)方法都有效且美观。
我不会声称上面描述的方法是最好的,但它可能是你能找到的最简单的云之一。而且相当完整:不同的变体,可自定义,HTML 和 CSS 代码量不到 100 行……正是这种简单性和潜力让它如此美观。
而且它还有改进和扩展的空间,这总是令人欣慰的。所以,如果你按照这篇文章尝试构建一个词/标签云,请分享一个演示链接!
文章来源:https://dev.to/alvaromontoro/create-a-tag-cloud-with-html-and-css-1e90