2

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?

1 Answer 1

5

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>

Sign up to request clarification or add additional context in comments.

7 Comments

Whoa, that seems nice, but can you elaborate in the answer on how the numbers are all on the side, and how this actually works!?
@xxh the width:0 is the trick. It will force a line break so each number is on a line then I simply position it on the left using absolute
I'm going to definitely try this right away, I'll report back if anything weird happens.
You learn something new every day I guess; would've never thought of this. Nice job, thank you!
Doesn't work with line wrapping though. The wrapped lines still increment the counter.
|