使用排版对齐和缩放来改进 UI 元素的图标

Avatar of Marcel Moreau
Marcel Moreau

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费积分!

在用户界面元素中使用图标很有帮助。 除了元素标签外,图标还有助于增强用户对用户元素意图的理解。 但我不得不说,我在浏览网页时注意到了一些图标错位现象。 即使图标的对齐方式正确,图标在元素的排版样式发生变化时也往往无法很好地响应。

我注意到了一些现实世界的例子,我想分享一下我对如何改进它们的看法。 我希望这些技术可以帮助其他人构建更好地适应排版变化的用户界面元素,同时保持设计的原始目标。

示例 1 — 网站消息

我在一个流行的媒体网站上找到了这个消息示例。 图标的位置看起来还不错。 但是,当更改一些元素的样式属性(如 font-sizeline-height)时,它就开始崩溃了。

发现的问题

  • 该图标使用相对单位(rem)从左侧边缘进行 absolute 定位。
  • 由于图标已从流中移除,因此父元素被赋予了更大的 padding-left 值以帮助进行整体间距 - 理想情况下,我们的 padding-x 是一致的,无论是否存在图标,一切看起来都很好。
  • 图标(它是 SVG)也以 rem 为单位进行尺寸设置 - 如果其父元素的 font-size 发生变化,这将不允许进行相应的调整大小。

建议

Screenshot of the site messaging element. It is overlayed with a red-dashed line indicating the icon's top edge and a blue-dashed line indicating the text's topmost point. The red-dashed line is slightly higher than the blue-dashed line.
指出对齐图标和排版的问题。

我们希望图标的顶部边缘位于蓝色虚线处,但我们经常发现图标的顶部边缘位于红色虚线处。

您是否曾经在一些文本旁边插入一个图标,但它就是无法与文本的顶部对齐? 您可以使用类似 position: relative; top: 0.2em 的方法将图标移动到适当位置。 这足够有效,但如果将来排版样式发生变化,您的图标可能会看起来错位。

我们可以更可靠地定位我们的图标。 让我们使用元素的基线距离(从一条线的基线到下一条线的基线之间的距离)来帮助解决这个问题。

Screenshot of the site messaging element. It is overlayed with arrows indicating the baseline distance from the baseline of one line to the next line's baseline.
计算基线距离。

基线距离为 font-size * line-height

我们将把它存储在一个 CSS 自定义属性中。

--baselineDistance: calc(var(--fontSize) * var(--lineHeight));

然后,我们可以使用 (基线距离 - 字体大小) / 2 的结果向下移动图标。

--iconOffset: calc((var(--baselineDistance) - var(--fontSize)) / 2);

对于 font-size1rem (16px) 且 line-height1.5 的情况,我们的图标将向下移动 4 像素。

  • 基线距离 = 16px * 1.5 = 24px
  • 图标偏移量 = (24px16px) / 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-size1rem (16px),line-height1.6 且图标大小为副本的 2 倍 (32px) 的情况,我们的图标将获得 -3.2 像素的 top 值。

  • 基线距离 = 16px * 1.6 = 25.6px
  • 图标偏移量 = (25.6px32px) / 2 = -3.2px

对于 font-size2rem (32px),line-height1.2 且图标为 64px 的情况,我们的图标将获得 -12.8 像素的 top 值。

  • 基线距离 = 32px * 1.2 = 38.4px
  • 图标偏移量 = (38.4px64px) / 2 = -12.8px

演示:前后

结论

对于用户界面图标,我们有很多选项和技术。 我们有 SVG、网页字体、静态图像、::markerlist-style-type。 甚至可以使用 background-colorclip-path 来实现一些有趣的图标效果。 执行一些简单的计算可以帮助以更优雅的方式对齐和缩放图标,从而产生更可靠的实现。

另请参阅:之前关于将图标与文本对齐的讨论。