在pre上使用CSS创建行号 [英] Create line numbers on pre with CSS only

查看:507
本文介绍了在pre上使用CSS创建行号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试为每行前面的行号编写代码前缀。我喜欢只使用CSS。这是我做的



  pre {background:#303030;颜色:#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;} before 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解决方案的浏览器兼容性是什么?


解决方案

计数器为什么不增加

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

  counter-reset:line; 








W3C规范


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

计数器设置和计数器递增属性操作现有计数器的值。



$

b $ b

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






计数器如何知道当前值?
$ b

再次从 W3C规范


如果元素具有先前的同级,则 必须继承所有兄弟的计数器 。否则,如果元素有父级,则 必须继承所有父级的计数器



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


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






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



pre 标签级别,然后将计数器传递给其每个子元素(即每个 span ,每个 span:before 会知道或继承这个计数器),现在 span:before 之前的增量语句只会增加它从父母。



现在由于 span 继承了它先前的兄弟,他们也将从文档顺序中的前面的元素继承当前值,因此它从1到2,3等保持上升。






为什么在span或pre work上使用计数器递增?



-increment属性 创建新计数器。因此,在 span 将在遇到的第一个span上创建一个计数器。现在,由于 span 的每个兄弟节点继承此计数器,因此它不会每次都创建一个新节点,而只是继承前一个元素的值。因此,这种方法将工作,但总是最好使用 counter-reset 语句显式地创建计数器。






浏览器如何支持?



CSS计数器的浏览器支持令人难以置信。这不是CSS中的新功能,支持它也可在IE8中使用。 / p>




演示



div class =snippetdata-lang =jsdata-hide =truedata-console =truedata-babel =false>

  pre {background:#303030;颜色:#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>< ; lorem ipsum< / span>< span>& gt;& gt; lorem ipsum< / span>< span> lorem ipsum,\< / span>< span> lorem ipsum< / span>< span>& gt;& lorem ipsum< / span>< span> lorem ipsum< / span>< span> lorem ipsum< / span>< span> lorem ipsum< / span>< span> lorem ipsum< / span> lorem ipsum< / span>< span> lorem ipsum< / span>< span> lorem ipsum< / span>< / pre>   


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?

解决方案

Why does the the counter not increment?

You are not resetting or creating the counter at the parent tag level. If you add the following line to the pre selector, the code will work fine. When you don't create the counter (using a counter-reset) at the parent level, each element would create its own counter and then increment it.

counter-reset: line;


When does a counter get created?

From the W3C Specs:

The counter-reset property creates new counters on an element.

The counter-set and counter-increment properties manipulate the value of existing counters. They only create new counters if there is no counter of the given name on the element yet.

In this case what happens is that we haven't created a counter by using the counter-reset property and so the counter-increment property in the span:before pseudo-element selector would create a counter of the given name and increment it.


How does the counter get to know the current value?

Again from the W3C Specs:

If an element has a previous sibling, it must inherit all of the sibling’s counters. Otherwise, if the element has a parent, it must inherit all of the parent’s counters. Otherwise, the element must have an empty set of counters.

The element then inherits counter values from the immediately preceding element in document order.

Here since the counter is only created in the pseudo-element, its parent (the span) is not aware of its creation and so the siblings of this span doesn't inherit the counter. Since it doesn't even inherit any counter, it doesn't get the current value from the preceding element either.


Why does creating the counter on parent work?

When the counter is created at the pre tag level, the counter is then passed on to each of its children elements (that is, each span and in turn each span:before would know about or inherit this counter) and now the increment statements in the span:before would only increment the value of the counter which it received from the parent.

Now since each span inherits the line counter from its previous sibling, they will also inherit current value from the preceding element in the document order and thus it keeps going up from 1 to 2, 3 etc.


Why does using counter-increment on span or pre work?

As you've guessed, the counter-increment property creates a new counter when there is no existing counter and so adding counter-increment: line on the span will create a counter on the first span that is encountered. Now, since each sibling of the span inherits this counter, it doesn't create a new one every time and rather just inherits the value from the preceding element. Thus this approach will work but it is always better to create the counter explicitly using a counter-reset statement.


How is the browser support?

Browser support for CSS counters is unbelievably good. It is not a new thing in CSS and support for it is available even in IE8.


Demo:

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>

这篇关于在pre上使用CSS创建行号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆