Code Snippet

Home » Code Snippets » jQuery » Underline Individual Words

Underline Individual Words

There is no CSS for applying an underline (text-decoration: underline;) only to individual words in a multiple-word element. The best way would be to wrap each word in a span (not the spaces, just the words) in spans and apply underline to those spans. Here's jQuery to do that to h1 elements.

$('h1').each(function() {

	var words = $(this).text().split(' ');

	$(this).empty().html(function() {

		for (i = 0; i < words.length; i++) {
			if (i == 0) {
				$(this).append('<span>' + words[i] + '</span>');
			} else {
				$(this).append(' <span>' + words[i] + '</span>');
			}
		}

	});

});

Then you could do:

h1 span {
  text-decoration: underline;
}

Similar and slightly more robust solution: Lettering.js

Reference URL

Subscribe to The Thread

  1. For the raw JS version:

    var h1s = document.getElementsByTagName('h1');
    for(var i=0; i < h1s.length; i++) {
        var t = h1s[i];
        t.innerHTML = '<span>' + t.innerHTML . split(' ') . join('</span><span>') +  '</span>';
    }

    I believe I reduced the footprint a little too. Although your version is a lot more abstract and uses better maintainable code.

  2. Just a note: If you do a for loop, you should declare the i variable with the var keyword. See here why.

    Furthermore, if this for-loop sees the length is 0, it will never reach the inside of the for loop and breaks off before initiating the code inside. Therefore, your if-else-statement is completely ignored, since only the else case can be true. If will never be reached, because the for loop breaks off before then.

  3. The code in the reference is correct, but that code on this page is missing the span tags within append().

  4. TeMc

    Although the raw JS version isn’t too bad either. There’s some performance to be gained in the jQuery version as wel. Why call $.fn.each, $.fn.empty, $.fn.html and then a dozen times $.fn.append ?

    
    function htmlEsc(txt){
      return txt.replace(/&/g, "&").replace(//g, ">");
    }
    $('h1').each(function() {
    
            var $el = $(this),
                words = $el.text().split(' '),
                newHtml = '',
                i = 0,
                len = words.length;
    
            for ( ; i < len; i++) {
                    if (i < 0) {
                           newHtml += ' '; // space
                    }
                    newHtml += '' + htmlEsc( words[i] ) + '';
            }
    
            $(this).html( newHtml );
    
    });
    

    * the empty() is simply redundant
    * the calls to append() don’t make sense inside html. Either build outside and call $(this).append() a few times, or build it inside and call $(this).html( stuff ); The latter is recommended.
    * You’re using text() to retrieve the value but using html()/append() to put it back. This is very dangerous when working with user input and can also destroy your layout if there is anything like HTML in your titles. You must escape html here when building the strings (or use $.fn.text)
    * Don’t forget ‘var’ instead of i in the for loop. Or move it to the list of vars outside the for-loop, that way you save a few bits in not starting two var statements (those are all one var statement, not how they are separated by a comma.

  5. TeMc

    Although the raw JS version isn’t too bad either. There’s some performance to be gained in the jQuery version as wel. Why call $.fn.each, $.fn.empty, $.fn.html and then a dozen times $.fn.append ?

    
    function htmlEsc(txt){
      return txt.replace(/&/g, "&").replace(//g, ">");
    }
    $('h1').each(function() {
    
            var $el = $(this), words = $el.text().split(' '), newHtml = '',  i = 0,  len = words.length;
    
            for ( ; i < len; i++) {
                    if (i < 0) { newHtml += ' ';  } // add space between words
                    newHtml += '' + htmlEsc( words[i] ) + '';
            }
    
            $(this).html( newHtml );
    });
    

    * the empty() is simply redundant
    * the calls to append() don’t make sense inside html. Either build outside and call $(this).append() a few times, or build it inside and call $(this).html( stuff ); The latter is recommended.
    * You’re using text() to retrieve the value but using html()/append() to put it back. This is very dangerous when working with user input and can also destroy your layout if there is anything like HTML in your titles. You must escape html here when building the strings (or use $.fn.text)
    * Don’t forget ‘var’ instead of i in the for loop. Or move it to the list of vars outside the for-loop, that way you save a few bits in not starting two var statements (those are all one var statement, not how they are separated by a comma.

  6. Ecatherina

    Chris, tell me please how to put in the script, not only h1, but more and h2.
    Thank you in advance , Ecatherina.

  7. i need some css code pls oga

  8. Your tutor is very nice guys…
    like it’s..

Speak, my friend

At this moment, you have an awesome opportunity* to be the person your mother always wanted you to be: kind, helpful, and smart. Do that, and we'll give you a big ol' gold star for the day (literally).

Posting tips:
  • You can use basic HTML
  • When posting code, please turn all
    < characters into &lt;
  • If the code is multi-line, use
    <pre><code></code></pre>
Thank you,
~ The Management ~