A widow in typography is the one lowly word that gets displayed on a line of its own within a heading. Typographers and designers often go nuts when they see the main headings on a website have widows so here’s an easy fix to appease them:
Open up the functions.php file within your WordPress theme: and add the following code:
/** * remove_widows() * filter the_title() to remove any chance of a typographic widow * typographic widows * @param string $title * @return string $title; */ function remove_widows($title){ $title_length = strlen($title); if(strpos($title, 'a href=') > 0){ // this is a link so // work out where the anchor text starts and ends $start_of_text = strpos($link, '">'); $end_of_text = strpos($link, '</a>'); $end_of_text = ($title_length - $end_of_text); $anchor_text = substr($title, $start_of_text, $end_of_text); } else{ $start_of_text = 0; $end_of_text = $title_length; $anchor_text = $title; } // convert the title into an array of words $anchor_array = explode(' ', $anchor_text); // Provided there's multiple words in the anchor text // then join all words (except the last two) together by a space. // Join the last two with an which is where the // magic happens if(sizeof($anchor_array) > 1){ $last_word = array_pop($anchor_array); $title_new = join(' ', $anchor_array) . ' ' . $last_word; $title = substr_replace($title, $title_new, $start_of_text, $end_of_text); } return $title; } add_filter('the_title', 'remove_widows');
Explanation
This code basically takes WordPress’s the_title()
function and pre-filters it so that the last two words are separated not with a space but with a
instead (which is the HTML code for a space). This tricks the browser into not breaking up the word.
This code will come into action wherever the you use the_title()
in your WordPress theme. Note: this won’t fix widows on any headings (<h2>, <h3>, <h4>, etc) in your body copy (which is echoed in your theme with the the_content()
function).
Semantics
Another solution would be to wrap the last two words in a HTML tag like a span
tag and then set the CSS of that element e.g.:
h1 span{ white-space: nowrap; }
but that involves extra HTML and extra CSS.
Can you improve the code?
Have you spotted an error or think you can improve upon the function? Let me know in the comments.
I would just use a regular expression for this:
preg_replace( “/\s(?=\S+$)/”, “ ”, $title );
The regular expression:
\s(?=\S+$)
Looks for a space (\s), and then does a look-ahead ( (?=…) ) for a string of non-space characters (\S+) followed by the end-of-string boundary ($). This pattern will only be satisfied by the last space in any string, and so will therefore replace:
“this is a title”
with:
“this is a title”
Thanks for the code suggestion – James. I didn’t even contemplate using a regex but it does make sense to.
A great addition to your code would be a regex that checked for the last space that comes before each closing block level tags (like p, li, h1-6, etc) which could then be applied to WordPress’s the_content() function and could eliminate widows from the body copy too.