行高玩转!

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的各个阶段提供云产品。立即开始使用 $200 免费信用额度!

CSS 中的 行高 属性控制文本行之间的间距。它通常设置为无单位值(例如 line-height: 1.4;),使其与字体大小成比例。它对于排版控制至关重要。太低会导致行之间挤在一起;太高会导致行之间过分分开。两者都会影响可读性。但您可能已经知道这一点。

在这篇文章中,我们将重点关注一些技巧。如果您知道(或能够计算出)line-height 的精确值,您可以做一些很棒的事情!

为每行文本设置不同的颜色

没有 ::nth-line()不幸的是。我们甚至不能可靠地使用 <span>,因为有许多不同的因素会导致文本在不同的位置断开。

有一种方法,虽然是非标准的,但可以使用元素的背景作为文本的背景。

.text {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

还有一个技巧,您可以使用 linear-gradient() 和颜色停止点,这样颜色不会渐变到另一种颜色,而是突然结束,另一种颜色开始。假设我们知道行高是 22px,我们可以使渐变断点正好位于该位置。

.text {
  background-image: linear-gradient(
    to bottom,
    #9588DD,
    #9588DD 22px,
    #DD88C8 22px,
    #DD88C8 44px,
    #D3DD88 44px,
    #D3DD88 66px,
    #88B0DD 66px,
    #88B0DD);
}

组合这两个技巧

在不支持文本背景剪裁的浏览器(如 Firefox)中,您将在文本后面看到实心的彩色条。也许这很酷,您喜欢它。也许您更愿意只回退到实心颜色文本。在这种情况下,您可以使用 @supports 仅在支持的情况下应用它。

此外,由于您会反复使用行高值,因此将其变量化可能很有用。我将在本文中使用 SCSS,但这将来使用真正的 CSS 变量会很酷,这样您甚至可以在渲染后更改它并观察它继续工作。

$lh: 1.4em;

body {
  font-size: 1em;
  line-height: $lh;
}

@supports (-webkit-background-clip: text) {
  p {
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-image: linear-gradient(
      to bottom,
      #9588DD,
      #9588DD $lh,
      #DD88C8 $lh,
      #DD88C8 $lh*2,
      #D3DD88 $lh*2,
      #D3DD88 $lh*3,
      #88B0DD $lh*3,
      #88B0DD);
  }
}

在元素的顶部使用此行为最容易。下面是一个示例,其中前几行被修改以强调。

.text {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(
    to bottom,
    rgba(white, 0.8),
    rgba(white, 0.8) $lh,
    rgba(white, 0.6) $lh,
    rgba(white, 0.6) $lh*2,
    rgba(white, 0.4) $lh*2,
    rgba(white, 0.4) $lh*3,
    rgba(white, 0.2) $lh*3,
    rgba(white, 0.2));
}

如果我们试图定位任意数量文本的最后几行,则会变得更加困难。在这种情况下,我们需要第一个彩色条从顶部延伸到一直到底部减去几行。幸运的是,我们可以使用 calc() 来做到这一点!

.text {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(
    to bottom,
    rgba(white, 0.8),
    rgba(white, 0.8) calc(100% - 66px),
    rgba(white, 0.6) calc(100% - 66px),
    rgba(white, 0.6) calc(100% - 44px),
    rgba(white, 0.4) calc(100% - 44px),
    rgba(white, 0.4) calc(100% - 22px),
    rgba(white, 0.2) calc(100% - 22px),
    rgba(white, 0.2));
  background-position: bottom center;
}

还有其他方法可以实现这种效果,例如叠加伪元素渐变(使用 pointer-events: none; 以免造成干扰)。

文本之间的线条

使用与上述实心颜色停止点技术类似的技术,我们可以创建一个 1px 线性渐变,该渐变以已知的 line-height 精确重复。最简单的方法是使用 repeating-linear-gradient(),并确保所有其他元素都能很好地协同工作(例如基于行高的填充)。

.parent {
  padding: $lh*2;
  background: #082838;
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(white, 0)   0,
    rgba(white, 0)   $lh/1em*16px-1,
    rgba(white, 0.1) $lh/1em*16px-1,
    rgba(white, 0.1) $lh/1em*16px
  );
}

为了获得 1px 线,我们需要知道 line-height 是多少像素,然后减去 1。目标是渐变以已知的行高精确重复,因此该空间中的最后一个像素可以是线。由于我们将正文字体大小保留为 1em,因此它为 16px。由于 line-height 以 ems 设置,我们可以除以 1em 删除单位,然后乘以 16px,并在需要时减去 1。

每行放置一张图片

如果您知道确切的 line-height,还可以做的一件事是使 background-size 与其匹配,至少在垂直轴上。然后,您可以将其垂直重复,它将以每行一张图片的方式对齐。

.text
  background-image: url(image.svg);
  background-size: $lh $lh;
  background-repeat: repeat-y;
  padding-left: $lh*2;
}

演示

查看 CodePen 上 Chris Coyier (@chriscoyier) 的 一行文本不同的颜色