在用户界面元素中使用图标很有帮助。 除了元素标签外,图标还有助于增强用户对用户元素意图的理解。 但我不得不说,我在浏览网页时注意到了一些图标错位现象。 即使图标的对齐方式正确,图标在元素的排版样式发生变化时也往往无法很好地响应。
我注意到了一些现实世界的例子,我想分享一下我对如何改进它们的看法。 我希望这些技术可以帮助其他人构建更好地适应排版变化的用户界面元素,同时保持设计的原始目标。
示例 1 — 网站消息
我在一个流行的媒体网站上找到了这个消息示例。 图标的位置看起来还不错。 但是,当更改一些元素的样式属性(如 font-size
和 line-height
)时,它就开始崩溃了。
发现的问题
- 该图标使用相对单位(
rem
)从左侧边缘进行absolute
定位。 - 由于图标已从流中移除,因此父元素被赋予了更大的
padding-left
值以帮助进行整体间距 - 理想情况下,我们的 padding-x 是一致的,无论是否存在图标,一切看起来都很好。 - 图标(它是 SVG)也以
rem
为单位进行尺寸设置 - 如果其父元素的font-size
发生变化,这将不允许进行相应的调整大小。
建议

我们希望图标的顶部边缘位于蓝色虚线处,但我们经常发现图标的顶部边缘位于红色虚线处。
您是否曾经在一些文本旁边插入一个图标,但它就是无法与文本的顶部对齐? 您可以使用类似 position: relative; top: 0.2em
的方法将图标移动到适当位置。 这足够有效,但如果将来排版样式发生变化,您的图标可能会看起来错位。
我们可以更可靠地定位我们的图标。 让我们使用元素的基线距离(从一条线的基线到下一条线的基线之间的距离)来帮助解决这个问题。

基线距离为 font-size * line-height。
我们将把它存储在一个 CSS 自定义属性中。
--baselineDistance: calc(var(--fontSize) * var(--lineHeight));
然后,我们可以使用 (基线距离 - 字体大小) / 2 的结果向下移动图标。
--iconOffset: calc((var(--baselineDistance) - var(--fontSize)) / 2);
对于 font-size
为 1rem
(16px
) 且 line-height
为 1.5
的情况,我们的图标将向下移动 4 像素。
- 基线距离 =
16px
* 1.5 =24px
- 图标偏移量 = (
24px
–16px
) / 2 =4px
演示:前后
示例 2 — 无序列表
我找到的第二个例子是一个无序列表。 它使用 ::before
伪元素通过网页字体(Font Awesome)显示其图标。 关于有序列表和无序列表的样式设置,有很多 很棒 的 文章,因此我不会详细介绍相对较新的 ::marker
伪元素等等。 网页字体通常与图标对齐配合得很好,具体取决于使用的图标。
发现的问题
- 没有使用
absolute
定位 - 在使用伪元素时,我们通常不会像第一个示例那样使用 flexbox,而absolute
定位在这里很出色。 - 列表项使用
padding
和负text-indent
的组合来帮助布局 - 当考虑多行文本和图标可扩展性时,我永远无法使其正常工作。
建议
由于我们还将在解决方案中使用伪元素,因此我们将利用 absolute
定位。 此示例的图标大小略大于其相邻的副本(大约 2 倍)。 因此,我们将改变计算图标 top
位置的方式。 我们的图标中心应垂直与第一行的中心对齐。
从计算基线距离开始。
--baselineDistance: calc(var(--fontSize) * var(--lineHeight));
使用 (基线距离 - 图标大小) / 2 的结果向下移动图标。
--iconOffset: calc((var(--baselineDistance) - var(--iconSize)) / 2);
因此,对于 font-size
为 1rem
(16px
),line-height
为 1.6
且图标大小为副本的 2 倍 (32px
) 的情况,我们的图标将获得 -3.2 像素的 top 值。
- 基线距离 =
16px
* 1.6 =25.6px
- 图标偏移量 = (
25.6px
–32px
) / 2 =-3.2px
对于 font-size
为 2rem
(32px
),line-height
为 1.2
且图标为 64px
的情况,我们的图标将获得 -12.8 像素的 top 值。
- 基线距离 =
32px
* 1.2 =38.4px
- 图标偏移量 = (
38.4px
–64px
) / 2 =-12.8px
演示:前后
结论
对于用户界面图标,我们有很多选项和技术。 我们有 SVG、网页字体、静态图像、::marker
和 list-style-type
。 甚至可以使用 background-color
和 clip-path
来实现一些有趣的图标效果。 执行一些简单的计算可以帮助以更优雅的方式对齐和缩放图标,从而产生更可靠的实现。
另请参阅:之前关于将图标与文本对齐的讨论。
非常棒的工作,我一直想要这样的东西,但我计划自己做类似的东西。 谢谢你让我的工作更容易了:):):)<3
❤️
没有一个示例修复提供了良好的对齐(Android、Chrome),因此这篇文章有点难理解。
我没有 Android,但使用 Browserstack,我发现 Pixel 6 和 Galaxy 20 Chrome 浏览器中的 after 演示效果正常。