插入换行

问题

假如要实现一个类似如下图的一个定义列表,每一行都是一个名值对。

HTML 代码结构如下:

<dl>
  <dt>Name:dt>
  <dd>Muskdd>
  <dt>Email:dt>
  <dd>[email protected]dd>
  <dt>Location:dt>
  <dd>Earthdd>
dl>

在没有添加自定义样式前,定义列表默认的样式如下图:

显然,由于

由于是块级元素,所有的名和值均独占一行。要让
在同一行显示,很容易想到把它们都改成行内元素。CSS 如下:

dt, dd {
  display: inline;
}
dd {
  margin: 0;
  font-weight: bold;
}

通过 display:inline 把两者改成行内元素,以及修改了一些默认样式后,结果定义列表变成如下图所示:

显然,我们在每个

标签后面还缺一个换行,还未完全实现,那么接下来会探讨如何去插入换行。

如何插入换行

首先 ,如果我们不在乎使用
标签进行换行,那么最直接的方法就是在每个

标签后面添加一个
标签进行换行。比如这样:

...
<dt>Name:dt>
<dd>Musk<br />dd>
...

上面的这个方法显然过于简单粗暴,后期的可维护性也不好,那有没有其他的方法?

实际上,有一个 Unicode 字符是专门代表换行符的:0x000A。在 CSS 中,这个字符可以写作 "\000A",或简化为 "\A"。我们可以把其作为 ::after 伪元素的内容,添加到每个

元素的尾部,代码如下:

dd::after {
  content: "\A";
}

但是,我们把这段代码尝试运行之后,发现并没有变化。这是为什么呢?这段代码所做的实际是在 HTML 结构中的所有关闭标签

之前添加了换行符,但在 HTML 中,这些换行符会与相邻的其他空白符进行合并。空白符合并通常是一件好事情,否则我们要把 HTML 文档的源代码整理进一行。但有时候我们希望保留源代码中的一些空白符和换行。这里我们就需要这么处理,通常会使用 white-space: pre;。这里我们也是这么做,但只对伪元素生成的换行符设置这个样式。代码如下:

dt, dd {
  display: inline;
}
dd {
  margin: 0;
  font-weight: bold;
}
dd::after {
  content: "\A";
  white-space: pre;
}

这时候亲手测试一下,发现这个办法渲染的定义列表结果跟想要实现的效果一模一样。但这个这个方法还不够健壮,假设定义列表中的

对应多个
,那么这多个
标签后都会插入换行,显得不太好。

...
<dt>Email:dt>
<dd>[email protected]dd>
<dd>[email protected]dd>
...


这时我们可能会想到:不将换行符放在

后面,而是放在
前面:

dt::before {
  content: "\A";
  white-space: pre;
}

但这会导致第一行变为空行,为了规避这个问题,可以尝试使用以下这些选择符来替代单纯的 dt

  • dt:not(:first-child)
  • dt ~ dt
  • dd + dt

最后我们采用最后一种方法,因为假设多个

对应一个值的场景下,它也可以正常显示,另外两者在就会有问题。除此之外,我们还可以在多个
之间插入一个逗号,那么最终 CSS 代码如下:

dd + dt::before {
  content: "\A";
  white-space: pre;
}
dd + dd::before {
  content: ", ";
  font-weight: normal;
}

最终的渲染效果如下:

你可能感兴趣的:(CSS)