How to select nth line of text (CSS/JS)

I found a JavaScript library called lining.js to help with this if anyone is interested. It enables CSS syntax like this:

<style>
  .poem .line[first] { /* `.poem::first-line`*/ }
  .poem .line[last] { /* `.poem::last-line` */ }
  .poem .line[index="5"] { /* `.poem::nth-line(5)` */ }
  .poem .line:nth-of-type(-n+2) { /* `.poem::nth-line(-n+2)` */ }
  .poem .line:nth-last-of-type(2n) { /* `.poem:::nth-last-line(2n)` */ }
</style>

(Github)


If each line is a separate <li> or <p> you can select that, using CSS.

:nth-child(N)

Taken from sitepoint.com, works in in Opera 9.5+, Safari 4+, FF3.5+

Description

This pseudo-class matches elements on the basis of their positions within a parent element’s list of child elements. The pseudo-class accepts an argument, N, which can be a keyword, a number, or a number expression of the form an+b. For more information, see Understanding :nth-child Pseudo-class Expressions.

If N is a number or a number expression, :nth-child(N) matches elements that are preceded by N-1 siblings in the document tree.

The following example selectors are equivalent, and will match odd-numbered table rows:

tr:nth-child(2n+1) {
  ⋮ declarations
}
tr:nth-child(odd) {
  ⋮ declarations
}

This example selector will match the first three rows of any table:

tr:nth-child(-n+3) {
  ⋮ declarations
}

This example selector will match any paragraph that’s the first child element of its parent element:

p:nth-child(1) {
  ⋮ declarations
}

This is, of course, equivalent to the selector p:first-child.

Example

This example selector will match odd-numbered table rows:

tr:nth-child(odd) {
  ⋮ declarations
}

You can also use jQuery.


Interesting. You can do something like that with JavaScript:

$(function(){ 
  var p = $('p'); 
  var words = p.text().split(' '); 
  var text = ''; 
  $.each(words, function(i, w){
                   if($.trim(w)) text = text + '<span>' + w + '</span> ' }
        ); //each word 
  p.html(text); 
  $(window).resize(function(){ 

    var line = 0; 
    var prevTop = -15; 
    $('span', p).each(function(){ 
      var word = $(this); 
      var top = word.offset().top; 
      if(top!=prevTop){ 
        prevTop=top; 
        line++; 
      } 
      word.attr('class', 'line' + line); 
    });//each 

  });//resize 

  $(window).resize(); //first one
});

Basically, we wrap each word with a span, and add a class based on the position of the span, whenever the window resizes. I'm sure it can be done more efficiently, but it works as a proof of concept. Of course, for even/odd lines, you can simplify the code.

Edge cases: I didn't test it where the class changes the size or width of the words. It may end up very wrong.

Here it is in action: https://jsbin.com/piwizateni/1/edit?html,css,js,output