Preventing widows and orphans in websites

19 September, 2014 by Tom Elliott

Widows in typography, when single words get left on their own line at the end of a paragraph or sentence don’t look great.

widow-line-break-example-1

Example of a widow (or orphan if you prefer)

A graphic designer friend recently asked if there was any way to remove widows that were appearing on some some paragraphs in a recent website project as it was annoying the hell out of him.

My initial response was no.

I tried to explain that some aspects of the web are different from print; that text should be allowed to flow naturally and that we have little control over how website content editors or end users determine how content should be displayed. Users for example may change the font size within the browser, CMS controlled content will vary in length and Responsive Web Design will wrap and break text at different points depending on screen resolution.

But what about post codes for example? Or phone numbers? When these are at the end of paragraphs, it will look even worse if they are broken across multiple lines. Single orphaned words are one thing but broken postcodes will look terrible.

The are a number of ways I’ve considered removing widows in the past. None of which are good solutions. These include:

  • Manually inserting line breaks, but this can result in random line breaks as text is resized.
  • Adding or removing content. Now that many sites are responsive, this doesn’t really help us
  • Adding manual   between the two words or strings at the end of a paragraph. This works but no one wants to manually do this on an entire site!

I then figured that if we could automatically replace a regular space with a   between the two words at the end of a paragraph, this would mean they would get treated as a single word and so would break onto a new line together.

Hooray! With a few lines of jQuery code, we can prevent widows and orphans as shown below:

$('p').each(function(){
    var string = $(this).html();
    string = string.replace(/ ([^ ]*)$/,' $1');
    $(this).html(string);
});

This will loop through each paragraph on the page, search for the last space in the string using a Regex pattern and replace the space with a non-breaking-space  . The original paragraph is then replaced with the new string, with the non breaking space between the last two words or two text strings.

Searching through every p tag on the site however might be overkill. You might just want to target a particular paragraph or heading. For example the below will loop through each paragraph within a ‘main-post’ div and each h2 tag:

$('#main-post p, h2').each(function(){
    var string = $(this).html();
    string = string.replace(/ ([^ ]*)$/,' $1');
    $(this).html(string);
});


2 Comments

  • Al says:

    Thanks for the tip – the designers in the office will be very happy!

  • Matthew says:

    Thank you. Very elegant and efficient. I am working on a book selling website with many variable text lengths to where it would be impossible to edit every one. Also things like book titles are non editable. So for book titles this will work well since some can be quite long even without subtitles.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    css.php