Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a first word of the last line of text? (<h1> - <h6>, <p> elements)

I need to add a little horizontal line under each of the h1 - h6 elements on the site I am building. I am currently adding an after element:

h1, h2, h3, h4, h5, h6 {
  text-transform: uppercase;
  color: #000;
  margin-top: 0;
  margin-bottom: 2rem;
  font-weight: 800;
  color: #333;
  display: inline-block;
  position: relative;
  text-rendering: optimizeLegibility;
  font-family: $altfont;
  position: relative;
  &:after {
    content: '';
    position: absolute;
    bottom:0;
    left:0;
    width: 60px;
    height: 4px;
    background-color: $yellow;
  }
}

I also have a small jQuery function to make sure that the after element is always 20px below the element:

$(function () {
    $('h1, h2, h3, h4, h5, h6').each(function () {

            x = parseInt($(this).css('font-size'));
            $(this).css('line-height', (x + 20) + 'px');

    });
});

this works if the h1 has text-align left - when the text wraps into 2 or more lines, the after element will show up under the first word of the last line.

The problem is, if the text is center aligned, or right aligned, the after element will show up under the h1 element but not under the first word of the last line. Is this something that can be done with JS/JQuery?

Here is a pic of what happens. In the second example, I would like the yellow line to show up under the word "Slice".

enter image description here

like image 849
Varin Avatar asked Nov 27 '22 02:11

Varin


1 Answers

EDIT

This was a nice challenge!
It takes 4 loops to achieve what you ask.

  1. To add a span on each words.
  2. To find the offset of the span on the last line.
  3. To remove spans on all lines except the last.
  4. To remove spans on all words except the first.

CodePen

See comments in code (I left all my debugging console.logs).

$(function () {
  $('h1, h2, h3, h4, h5, h6').each(function () {

    x = parseInt($(this).css('font-size'));
    $(this).css('line-height', (x + 20) + 'px');

    findWord($(this));

  });

  function findWord(el){

    // Get the word array.
    var wordArr = el.html().split(" ");

    // Cycle words to add span on each words.
    for(i=0;i<wordArr.length;i++){
      console.log(wordArr[i]);
      wordArr[i] = "<span class='underliner'>"+wordArr[i]+"</span>";
    }

    // Update HTML.
    el.html(wordArr.join(" "));

    // Find the offset of the last line.
    var biggestOffset=0;
    el.find(".underliner").each(function(){
      console.log($(this).offset().top);
      if($(this).offset().top>biggestOffset){
        biggestOffset=$(this).offset().top;
      }
    });

    console.log("biggestOffset: "+biggestOffset);

    // Remove span on NOT the last line
    el.find(".underliner").each(function(){
      if($(this).offset().top<biggestOffset){
        $(this).replaceWith($(this).html());
      }
    });

    // On the last line, remove all spans except on the first word
    el.find(".underliner").not(":eq(0)").each(function(){
      $(this).replaceWith($(this).html());
    });
  }
});
h1, h2, h3, h4, h5, h6 {
  text-transform: uppercase;
  color: #000;
  margin-top: 0;
  margin-bottom: 2rem;
  font-weight: 800;
  /*color: #333;*/
  display: inline-block;
  position: relative;
  text-rendering: optimizeLegibility;
  font-family: $altfont;
  position: relative;
  
  text-align:center;  /* ADDED */
  
  /* REMOVED */
  /*&:after {
    content: '';
    position: absolute;
    bottom:0;
    left:0;
    width: 60px;
    height: 4px;
    background-color: &yellow;
  }*/
}

.underliner{
  text-decoration:underline;
  text-decoration-color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1>This is a quite long H1 that will certainly wrap</h1>
<h2>This is a quite long H2 that will certainly wrap</h2>
<h3>This is a quite long H3 that will certainly wrap</h3>
<h4>This is a quite long H4 that will certainly wrap</h4>
<h5>This is a quite long H5 that will certainly wrap</h5>
<h6>This is a quite long H6 that will certainly wrap</h6>




First answer
(misread the question...)


Since you already use jQuery...

You can add $(this).append($("<div class='smallBar'>").css({"top":x+10})) to the script...
And use CSS to define smallBar the same way you did for the after pseudo element.

CodePen

$(function () {
  $('h1, h2, h3, h4, h5, h6').each(function () {

    x = parseInt($(this).css('font-size'));
    $(this).css('line-height', (x + 20) + 'px');
    $(this).append($("<div class='smallBar'>").css({"top":x+10}))

  });
});
h1, h2, h3, h4, h5, h6 {
  text-transform: uppercase;
  color: #000;
  margin-top: 0;
  margin-bottom: 2rem;
  font-weight: 800;
  /*color: #333;*/
  display: inline-block;
  position: relative;
  text-rendering: optimizeLegibility;
  font-family: $altfont;
  position: relative;
  /*&:after {
    content: '';
    position: absolute;
    bottom:0;
    left:0;
    width: 60px;
    height: 4px;
    background-color: &yellow;
  }*/
}
.smallBar{
  position: absolute;
    top:0;
    left:0;
    width: 60px;
    height: 4px;
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>This is a quite long H1 that will certainly wrap</h1>
<h2>This is a quite long H2 that will certainly wrap</h2>
<h3>This is a quite long H3 that will certainly wrap</h3>
<h4>This is a quite long H4 that will certainly wrap</h4>
<h5>This is a quite long H5 that will certainly wrap</h5>
<h6>This is a quite long H6 that will certainly wrap</h6>
like image 51
Louys Patrice Bessette Avatar answered Nov 28 '22 15:11

Louys Patrice Bessette