Search code examples
csscss-counter

Is it possible to count lines of text in CSS


I am looking for a possible way, solely using CSS that could allow one to increment a CSS counter for every line of text within a DOM element.

This question is similar, but not the same as this SO question.

Using this as an example:

<p>Here is a basic "hello world" program, written in Rust:</p>
<code>
fn main() {
    println!("Hello, world!");
}
</code>

With white space preservation:

code {
    white-space: pre-wrap;
}

I am looking for a way that I could make this appear with a line number before each line of text (or just before each newline character).

1. | fn main() {
2. |    println!("Hello, world!");
3. | }

I was thinking that I could use pseudo-selectors, CSS counters, contents: , and a few other ideas, to make it happen, but I have no way to select each line.

I know that there are the ::first-letter and ::first-line pseudo-elements, but after looking everywhere I could find no mention of something like an nth-line(), or ::line selectors.

Does anyone know of any obscure CSS trick that could make this possible?


Solution

  • If the number of lines will be limited, you can try something like below:

    code {
        white-space: pre-wrap;
        position: relative;
        padding-left: 5ch; /* the space for the numbers */
        display: block;
        overflow: hidden; /* hide the non needed numbers */
        border: 1px solid;
    }
    code::before,
    code::after {
      content: "1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14."; /* and so on*/
      position: absolute;
      width: 0; /* force a line break */
      top: 0;
      left: 0;
    }
    
    code::after {
      content: "| | | | | | | | | | | | | | | | | |"; /* and so on*/
      left: 3ch; /* a small offset to not overlap the numbers */
    }
    <p>Here is a basic "hello world" program, written in Rust:</p>
    <code>
    fn main() {
        println!("Hello, world!");
    }
    </code>
    Another code block:
    <code>
    fn main() {
        let mut a = 0;
        let mut b = 2;
    
        println!("Hello, world!");
    
        for i in 0..5) {
            a += b;
        }
    
        println!("{}", a);
    }
    </code>