17

My objective is to print a text file line by line and append the line number at the beginning. Like so:

<div id="wrapper">
  <div class="line">1: asdf</div>
  <div class="line">2: asdfasdf</div>
  <div class="line">3: asdfasdfasdfasdf</div>
  <div class="line">4: asdf</div>
</div>

n is a variable in CSS responsible for an element's index within its parent and within a child selector you can perform operations on it, eg. nth-child(2n + 3)

Is there any way to grab this variable and insert it as plain text? Essentially like this:

.line:before {
  content: n;
}

I know I can accomplish this with SASS which is what I'm using, I was just wondering if there's some way to pull it off with vanilla CSS.

Harry
  • 87,580
  • 25
  • 202
  • 214
JackHasaKeyboard
  • 1,599
  • 1
  • 16
  • 29

1 Answers1

32

Yes, you could do this using CSS counters. CSS counters can be created and incremented when a matching selector is encountered. For this case, we can create a counter at the .wrapper element's level and then increment the counter value whenever a new .line element is encountered.

The counter-reset property is used to create the counter whereas the counter-increment is used to increment the value. The value of the counter can then be assigned to the pseudo-element through the content property with value as counter(counter-name).

As Aaron Lavers points out in his comment, CSS counters are not a new thing and is supported from IE8 itself.

#wrapper {
  counter-reset: line-number;
}
.line {
  counter-increment: line-number;
}
.line:before {
  content: counter(line-number)": ";
}
<div id="wrapper">
  <div class="line">asdf</div>
  <div class="line">asdfasdf</div>
  <div class="line">asdfasdfasdfasdf</div>
  <div class="line">asdf</div>
</div>

We can also set styles for the output value, increment the value by a number more than 1, start with the base value as a number different than 0 etc.

.wrapper {
  counter-reset: line-number 2; /* specifying a number in counter-reset means set the starting value as that number */
}
.line {
  counter-increment: line-number 2; /* specifying a number in counter-increment means increment the counter by that much every time */
}
.line:before {
  content: counter(line-number, lower-roman)": "; /* the second parameter represents the style of the output value */
}

#wrapper2.wrapper .line:before {
  content: counter(line-number, decimal-leading-zero)": ";
}
<h3>Lower Roman Style with Base Value as 2 and increments of 2</h3>
<div id="wrapper" class="wrapper">
  <div class="line">asdf</div>
  <div class="line">asdfasdf</div>
  <div class="line">asdfasdfasdfasdf</div>
  <div class="line">asdf</div>
</div>

<h3>Decimal Leading Zero Style with Base Value as 2 and increments of 2</h3>
<div id="wrapper2" class="wrapper">
  <div class="line">asdf</div>
  <div class="line">asdfasdf</div>
  <div class="line">asdfasdfasdfasdf</div>
  <div class="line">asdf</div>
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 4
    Huh, TIL. This even has full browser support http://caniuse.com/#feat=css-counters – Aaron Lavers Jun 15 '16 at 08:42
  • 3
    Yes @AaronLavers. CSS counters are very rarely used and the no. of materials on the internet about it are also very low. It could possibly be because the nesting of elements has a high impact on the correct working of counters. – Harry Jun 15 '16 at 08:44