VISION

这才是设计:Medium如何雕琢下划线

这才叫设计:看Medium如何精雕细琢下划线

本文作者Marcin Wichary是Medium设计师,前Google用户体验设计师。

对于计算机来说,在屏幕上画一条水平线似乎再容易不过了,但是,简单的事情却往往内藏玄机,排版工艺就是个精细活儿,原本只需花一晚上就能优化的Medium下划线外观最终足足用了一个月的时间。

回顾历史

为了强调某个词语,过去常采用斜体或粗体的形式,而下划线则显得有些土鳖,但它的易用性让其得以频繁使用。

在 20 世纪的打字机时代,刻板的等宽字体与单色打字机色带让下划线成为了唯一理想的文字强调方式:先退格,再在同样的地方打出下划线。

然后互联网来了,下划线搭配蓝色字体成为了可点击链接的标志,也许这种方式会慢慢消失——前不久Google就清除了所有超链接下的下划线——但我坚信至完全消失还需要一段时间。

不幸的是,在这几年的网页排版技术发展中——更好的 CSS 属性、对国际化更多的支持、自定义字体——下划线还是原来老样子,只有极小的可定制性。

开始工作

在某个周二的早晨,我醒来后发现 Chrome 下的 Medium 链接是这样的:

Chrome 下的 Medium 链接

丑陋至极!无法忍受!再看看其它浏览器,虽然好一些,但都差强人意:

其它浏览器下的 Medium 链接

我在加入 Medium 后不久,便开始罗列出网页排版中可改进的地方,那天 Chrome 下划线问题立刻就被我列为首要事务。

无品牌锤子

我从计算机历史以及前人经验中获得了很多灵感。

上图拍摄于计算机历史博物馆中的 IBM 1401 维修实验室,其中的手提箱装满了 19 世纪 50 年代操作计算机所需的全部工具,除了锤子,其它大多数物品都印有官方商标。

在那个时代,计算机仍然是电动机械式,它的外围设备包括打卡机、链式打印机、读带机,操作它们既要动脑,也要动手,即使你的最终目的就是捣鼓无形的代码。

Web 设计常常也是如此:用十分有限的工具、复杂而邋遢的方法解决简单的问题,因为并没有一个简单方法让浏览器给你想要的下划线,但是我们可以采取迂回战术。

在找到答案之前,先来看看问题所在。

找到完美的下划线

完美的下划线应该既可见又不唐突——让用户意识到哪些文字是可点击的,同时又不需要对其投入太多注意力。它应该被放在离文字一段恰当距离的地方,当有下行字母占位时,下划线要紧贴其后:

技术上,开发者可以:

  • 改变下划线宽度(支持半像素/视网膜技术)
  • 改变下划线与文字的距离
  • 改变下划线颜色
  • 清除字母的下伸部分
  • 对已访问链接采取不同的样式

开启头脑风暴

下面是我与身边的前端工程师们想出来的办法:

1. 默认方式

默认的 text-decoration:underline 还不够好,我觉得读者应该得到更好的东西。

2. 高级 CSS 属性

比如,text-decoration-skip 与 text-underline-position,然而大多数浏览器并不支持它们,在短期内也不会支持。

3. 使用 border-bottom 与 box-shadow

用 border-bottom 修改下划线算是自上世纪 90 年代以来的 CSS 技巧之一了,它能让我们自定义颜色,但线与文字距离太远,下图中的 border-bottom 下划线感觉就像在两行文字之间:

也有可能突破该限制,只需设置 display: inline-block 再减小 height 或 line-height 即可,但有一个致命的弱点——链接文字不能换行。所以,它对常规页面文字根本行不通。(另外,border-bottom 不能显示两个以下的视网膜像素)

使用 box-shadow 也有类似的限制。

4. 定制下划线字体

我们平时见到的斜体与粗体其实具有各自独立的字母形状以保持字体的视觉完整性:

既然如此,那为什么不能定制一个独立的下划线字体让下划线成为字形的一部分呢?

虽然看似很有戏,但在我们这里却有如下问题:

  • 应用一款独立字体能增大页面加载耗时
  • 无法改变下划线的位置、宽度与颜色
  • 字体授权问题
  • 定制字体不太容易

5. 使用<canvas>

HTML canvas 标签能控制单个像素,所以我们可以自定义宽度、颜色,甚至在字母的下伸部分周围绘制,然而问题是无法知道链接文字什么时候换行,目前并没有精确测量换行文字的工具,用 JavaScript 实现开销太大。
(该方案的另一个版本是,定制一款只有下划线的字体,再将它绘制到文字上,最终因为与上文同样的原因而被否决)

6. 使用 background-image 及渐变

虽然看似与下划线无关,但 background-image 支持换行文字,灵活性强,还支持视网膜像素,也能在行内使用 data 协议,更能利用渐变进行合成。

于是,我们的最终方案是:一个细小的 1px 或 2px 高渐变,水平拉伸,垂直放置。

7. 清除字母的下伸部分

我的同事想出来了一个虽机灵但不切实际的办法——应用白色 text-shadow 或 text-stroke 来模拟下划线与文字间的间隙。

不幸的是,为了取得最佳效果,需要放置多层阴影,代价太大,而 text-stroke 则会遮盖下划线里面部分,所以最终我们决定暂时把这事放一放。

8. 事情变得复杂了

据我观察,

  • 作者会在5个地方用上链接:body,H1,H2,图片说明,文章引文
  • 大多数链接是白色背景上的黑字,有些会放在图片上
  • 视网膜与非视网膜像素显示
  • 我们给平板与手机调整了字体大小
  • 对于某些语言会采用默认系统字体
  • 有些用户会放大或缩小网页
  • 有些用户使用不常见的浏览器

在接下来几周,

  • 得到通用公式而不是特定数值——如果未来要改变字体或大小,调整下划线的位置就容易多了
  • 限定我们使用的浏览器,为不支持的浏览器提供默认样式
  • 简化代码,减小网页大小以及后期维护成本

然后,事儿就这么成了

没有烟花,没有香槟,在经过 31 天的讨论、尝试、错误与再尝试后,我的代码评审员们发来了四个字母:LGTM(Looks Good To Me)

在 Chrome 下最终的前后效果对比图: