【问题标题】:Create line numbers on pre with CSS only仅使用 CSS 在 pre 上创建行号
【发布时间】:2016-11-28 10:41:27
【问题描述】:

我尝试在每行前面使用行号来设置代码前置框的样式。我更喜欢只用 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 解决方案的兼容性如何?

【问题讨论】:

  • 为什么不用OL标签?
  • @Graham 如果我告诉你我完全忘记了,你会相信我吗? :P :P

标签: html css css-counter


【解决方案1】:

为什么计数器不增加?

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

counter-reset: line;

计数器何时创建?

来自W3C Specs

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

counter-set 和 counter-increment 属性操纵现有计数器的值。他们只有在元素上还没有给定名称的计数器时才创建新的计数器

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


计数器如何知道当前值?

再次来自W3C Specs

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

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

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


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

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

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


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

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


浏览器支持如何?

浏览器对 CSS 计数器的支持非常好。这在 CSS 和 support for it is available even in 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>

【讨论】:

  • 不错;我总是错误地认为我们必须在非伪元素上定义counter-increment;我根本没有意识到在父元素上使用counter-reset(包装'counted-elements')也会起作用。 CSS 的未解之谜! :)
  • @DavidThomas:我终于完全充实了它。以防万一你感兴趣:)
  • 行号不同宽度时,如何稍微优化一下,让所有的条垂直对齐更好?
  • @MaxPeng:给伪元素一个width,它的宽度足以容纳所有可能的编号值,这将使它们更好地对齐(如here)。但问题是您必须根据您期望的最大值分配任意宽度。
【解决方案2】:

你必须在你的 span 中增加 line

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

看看这个更新的jsfiddle

【讨论】:

  • 它可以,但是当我的&lt;span&gt;计数超过10,000时,需要几十秒。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2014-04-06
    • 2020-04-19
    • 2016-04-06
    • 2021-01-07
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    相关资源
    最近更新 更多