Fixing orphans on responsive websites

By Michael Argentini
Managing Partner, Technology and Design

In a previous blog article I talked about our recent migration to Ghost as the publishing platform for our blog. One of the needs we had was for a user experience that was as good as something we'd create for ourselves. So the attention to detail was important. During QA testing we discovered that Ghost doesn't allow markup or HTML entities in post titles, so we had no way of controlling orphans.

An Orphan Looks Like
This

Yuck. In the example above, I'd include "Like" on the second line, so it looked like this:

An Orphan Looks
Like This

Much better. So I wrote a Javascript function to correct orphans based on a desired length of 8 characters or more. The code requires jQuery, but what Javascript doesn't these days?

Basically, it scans an object with the selector "h1.posttitle_fynydd_blog a" or "h1.articletitle_fynydd_blog" and fixes orphans using non-breaking spaces. It evaluates whether the output device is a phone or not (based on a virtual viewport width of 375 points) and if so, it cuts the desired size in half. It only processes the text if the overall length is greater than the desired orphan size * 2 AND there are 3 or more words. It will keep appending orphans until a desired length is reached. I also added a hack to handle fixing "OS X" wrapping anywhere.

I can see this evolving to better handle in-line wrapping, like processing proper names (perhaps based on a dictionary or capitalization rules).

You can see this at work on our blog (right here!).

<script type="text/javascript">

    // THANK YOU FYNYDD!
    // http://fynydd.com

    // Process and adjust text orphans in blog titles
    function FixOrphans()
    {
        $("h1.posttitle_fynydd_blog a, h1.articletitle_fynydd_blog").each(function() {

            // How big should an orphan be (in characters)?
            var DesiredOrphanSize = 8;

            // Revert previously altered title orphans
            $(this).html($(this).html().replace('&nbsp;', ' '));

            // Hack to fix "OS X" in-line wrapping
            $(this).html($(this).html().replace(' OS X', ' OS&nbsp;X'));

            // Get viewport size for mobile detection
            var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);

            // Create word array to evaluate lengths
            var wordArray = $(this).text().split(" ");

            // Only process if overall title length > desired orphan size * 2 AND there are 3 or more words
            if (wordArray.length > 2 && $(this).text().length > (DesiredOrphanSize * 2))
            {
                for (var wordindex = wordArray.length - 1; wordindex > 0; wordindex--)
                {
                    // If the last word < desired character count, fix orphan...
                    if (wordArray[wordindex].replace('&nbsp;', ' ').length < (w > 375 ? DesiredOrphanSize : DesiredOrphanSize / 2))
                    {
                        wordArray[wordindex - 1] += "&nbsp;" + wordArray[wordindex];
                        wordArray.pop();
                    }

                    if (wordArray[wordArray.length - 1].replace('&nbsp;', ' ').length >= (w > 375 ? DesiredOrphanSize : DesiredOrphanSize / 2))
                    {
                        wordindex = 0;
                    }
                }

                $(this).html(wordArray.join(" "));
            }

        });
    }

    $(document).ready(function() {

        $(window).resize(function() {
            FixOrphans();
        });

        FixOrphans();

    });

</script>

Article last updated on 4/21/2018