仅使用 CSS 在 pre 上创建行号

新手上路,请多包涵

我尝试在每行前面设置一个带有行号的代码预框。我更喜欢只用 CSS 来做。这就是我所做的

 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>

但是,所有行的编号都是 1。增量不起作用。这是一个 jsfiddle

  1. 我做错了什么?
  2. 这个纯 CSS 解决方案的浏览器兼容性如何?

原文由 Tasos 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 987
2 个回答

为什么计数器不增加?

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

 counter-reset: line;


什么时候创建计数器?

来自 W3C 规范

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

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

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


计数器如何知道当前值?

再次来自 W3C 规范

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

然后该元素 _从文档顺序中紧接在前的元素继承计数器值_。

这里因为计数器只在伪元素中创建,它的父元素( span )不知道它的创建,所以这个 span 的兄弟姐妹不继承计数器.因为它甚至没有继承任何计数器,所以它也没有从前面的元素中获取当前值。


为什么在父工作上创建计数器?

当在 pre 标记级别创建计数器时,计数器将传递给它的每个子元素(即每个 span 以及每个 span:before 会知道或继承这个计数器)现在 span:before 中的递增语句只会递增它从父级接收的计数器的值。

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


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

正如您所猜测的那样,当没有现有计数器时,计数器增量属性 会创建 一个新计数器,因此在 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>

原文由 Harry 发布,翻译遵循 CC BY-SA 4.0 许可协议

您必须在您的范围内递增 line

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

看看这个更新的 jsfiddle

原文由 Huelfe 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏