71

I try to style a code pre box with line numbers in front of each line. I prefer to do it with CSS only. This is what I have done

pre {
  background: #303030;
  color: #f1f1f1;
  padding: 10px 16px;
  border-radius: 2px;
  border-top: 4px solid #00aeef;
  -moz-box-shadow: inset 0 0 10px #000;
  box-shadow: inset 0 0 10px #000;
}
pre span {
  display: block;
  line-height: 1.5rem;
}
pre span:before {
  counter-increment: line;
  content: counter(line);
  display: inline-block;
  border-right: 1px solid #ddd;
  padding: 0 .5em;
  margin-right: .5em;
  color: #888
}
<pre>
  <span>lorem ipsum</span>
  <span>&gt;&gt; lorem ipsum</span>
  <span>lorem ipsum,\ </span>
  <span>lorem ipsum.</span>
  <span>&gt;&gt; lorem ipsum</span>
  <span>lorem ipsum</span>
  <span>lorem ipsum</span>
  <span>lorem ipsum</span>
</pre>

However, all the lines have the number 1. The increment doesn't work. Here is a jsfiddle

  1. What I am doing wrong?
  2. What is the browser compatibility with this CSS only solution?
4

3 回答 3

89

为什么计数器不增加?

您不是在父标签级别重置或创建计数器。如果您将以下行添加到pre选择器中,则代码将正常工作。当您不在counter-reset父级别创建计数器(使用 a )时,每个元素都会创建自己的计数器,然后将其递增。

counter-reset: line;

什么时候创建计数器?

来自W3C 规范

counter-reset 属性在元素上创建新的计数器。

counter-set 和 counter-increment 属性操纵现有计数器的值。如果元素上还没有给定名称的计数器,它们只会创建新的计数器。

在这种情况下,我们没有使用counter-reset属性创建计数器,因此伪元素选择器counter-increment中的属性将创建一个给定名称的计数器并递增它。span:before


计数器如何知道当前值?

再次来自W3C 规范

如果一个元素有一个先前的兄弟,它必须继承所有兄弟的 counters。否则,如果元素有父元素,它必须继承所有父元素的 counters。否则,该元素必须有一组空的计数器。

然后该元素从文档顺序中的前一个元素继承计数器值

这里由于计数器只在伪元素中创建,它的父级(the span)不知道它的创建,因此 this 的兄弟姐妹span不会继承计数器。由于它甚至没有继承任何计数器,因此它也不会从前面的元素中获取当前值。


为什么在父项上创建计数器有效?

当计数器在pre标签级别创建时,计数器随后被传递给它的每个子元素(也就是说,每个子元素span都会span:before知道或继承这个计数器),现在增量语句span:before只会增加它从父级接收到的计数器的值。

现在,由于每个都从其前一个兄弟span继承了line计数器,因此它们还将从文档顺序中的前一个元素继承当前值,因此它不断从 1 上升到 2、3 等。


为什么在跨度或预工作上使用反增量?

正如您所猜到的,counter-increment 属性在没有现有计数器时创建counter-increment: line一个新计数器,因此添加将在span遇到的第一个跨度上创建一个计数器。现在,由于 的每个兄弟都span继承了这个计数器,所以它不会每次都创建一个新的,而只是继承前一个元素的值。因此,这种方法会起作用,但使用counter-reset语句显式创建计数器总是更好。


浏览器支持如何?

浏览器对 CSS 计数器的支持非常好。它在 CSS 中并不是什么新鲜事物,甚至在 IE8 中也提供了对它的支持


演示:

pre {
  background: #303030;
  color: #f1f1f1;
  padding: 10px 16px;
  border-radius: 2px;
  border-top: 4px solid #00aeef;
  -moz-box-shadow: inset 0 0 10px #000;
  box-shadow: inset 0 0 10px #000;
  counter-reset: line;
}
pre span {
  display: block;
  line-height: 1.5rem;
}
pre span:before {
  counter-increment: line;
  content: counter(line);
  display: inline-block;
  border-right: 1px solid #ddd;
  padding: 0 .5em;
  margin-right: .5em;
  color: #888
}
<pre><span>lorem ipsum</span>
<span>&gt;&gt; lorem ipsum</span>
<span>lorem ipsum,\ </span>
<span>lorem ipsum.</span>
<span>&gt;&gt; lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
<span>lorem ipsum</span>
</pre>

于 2016-11-28T10:43:35.260 回答
2

你必须增加line你的跨度:

pre span {
    display: block;
    line-height: 1.5rem;
    counter-increment: line;
}

看看这个更新的jsfiddle

于 2016-11-28T10:44:24.800 回答
1

嗨,您需要在上一个/更高加载的项目上重置计数器,请查看https://jsfiddle.net/n2xkgt7s/2/ pre { counter-reset: line; }

于 2016-11-28T10:49:23.837 回答