在本文中,我们将介绍如何使用SVG和CSS制作完全可访问的图标按钮,而不会用内联<svg>
代码使html膨胀而保留自定义!
但是首先,让我们定义我们要用代码实现的目标,以及我们从图标按钮元素的最终输出中要取得的目标:
- 互动
- 键盘控制
- 无障碍
- 可订制
…我们将仅用HTML和CSS来实现所有这些点!这是魔术,不是吗?
标记
一个<button>
要素就是我们需要的一切,您永远不会这么说吧?
<button aria-label="Download File"></button>
如果您不喜欢使用空元素,则可以使用.sr-only
实用程序类在UI中隐藏内部内容。
<button>
<span class="sr-only">Download File</span>
</button>
您可以选择使用aria-label
属性为按钮或隐藏元素添加均值,而该均值只能由辅助技术读取,这取决于您。使用button
元素,我们已经解决了清单的前三点,因为它是交互式的,键盘可导航,并且默认情况下可访问。无需tabindex或JavaScript代码即可使其可键盘访问。
互动✅键盘控制✅无障碍✅- 可订制
客制化
那么,如何使用CSS中的单个SVG图像更改颜色,大小和添加渐变呢?答案是……使用支持范围非常广泛的mask-*
属性!
唯一的限制是,源图标在透明或白色背景上应为黑色。这是因为mask属性使用纯黑色显示背景的可见部分,而白色或透明色则用于遮盖背景层。
让我们开始向按钮添加一些基本样式以设置定位和框模型:
.IconButton {
width: 56px;
height: 56px;
appearance: none;
border-radius: 50%;
border: 0;
background-color: #000;
cursor: pointer;
padding: 0;
position: relative;
}
现在,我们将使用::pseudo-element
来添加图标。绝对定位的伪元素对于数学上使图标居中很有用,但是同时,它允许我们在需要时将图标光学居中。
.IconButton::before {
/* Positioning related code */
content: "";
display: block;
width: 50%; /* width and height must be always equal */
height: 50%;
background: #000;
pointer-events: none;
/* this allows optical centering if required */
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
现在,我们可以添加我们的魔术代码了。首先,我们需要一个图标,我们需要它作为SVG,因为我们希望它在不降低质量的情况下进行缩放。在本示例中,我们将使用此图标。
使用这些mask-
属性,我们可以将图标设置为元素蒙版,就像使用Sketch,Figma等设计工具一样。让我们添加以下属性:
.IconButton::before {
/* Previous code... */
/* Masking code */
mask-image: url("https://cdn.glitch.com/a10b6199-a788-4cef-8bd8-21f95dbcba93%2Fdownload-cloud.svg?v=1571346192759");
mask-position: center;
mask-repeat: no-repeat;
mask-size: contain;
}
如您所见,我们在这里定义了四件事:
- 遮罩网址:我们的黑色svg图标
- 遮罩位置:设置为始终居中
- 蒙版重复:我们消除了平铺效果。
- 遮罩的大小:我们将其设置为包含在可用空间中,因此该图标将始终完全可见。
您可能已经注意到,这些属性与这些属性相同(并且行为类似)background-
。此处的主要区别在于,该图像用作蒙版,并使我们的元素在图像为黑色的地方“透明”,而图像的白色(或透明)部分用于隐藏背景。这里的图标为白色,因为我们background: #fff;
在伪元素上进行了设置,并且svg图标填充了#000
。
现在,我们应该看到如下所示:
这样,您可以更改背景,添加渐变,并用黑色和透明颜色的渐变填充图标,从而使图标变淡。
在里面,mask-image
您还可以使用Sprite SVG文件中的图标!非常棒且可扩展!
mask-image: url("path/to/sprite.svg#my-icon-id");
让我们看一些使用不同图标并更改::before
背景的示例:
第一个按钮使用全黑svg图标,第二个按钮向添加线性渐变,::pseudo-element
第三个按钮使用图标填充黑色到透明颜色的渐变。与往常一样,您甚至可以设置所需的动画效果,并且可以结合使用自定义属性以从html传递图标路径,并使用javascript使用轻松处理它们.setProperty()
,例如myelement.style.setProperty("--icon", "...");
现在我们可以标记最后一步!🎉
互动✅键盘控制✅无障碍✅可定制✅
现场演示
渐进增强
mask-
所有现代浏览器都很好地支持这些属性,但是如果出于某些奇怪的原因需要支持不支持这些属性的过时浏览器,则可以逐步增强代码以提供最小的UI体验。
请注意,在谈论“最小的UI体验”时,我们的意思是看起来可能并不相同,但是它们可以按预期工作,而不会破坏用户体验。这并不意味着“为旧的浏览器添加大量代码只是为了复制元素的视觉外观”,因为即使现代浏览器也可以下载该代码,但从未使用过。
结论
HTML是可访问的,默认情况下是语义的,而CSS提供了便捷的动态方式来构建我们的界面。如果添加一些自定义属性,则可以拥有一个真正智能的组件,而无需使用javascript或其他库来实现诸如此类的简单任务。
好好享受!🎉