“Typography is the foundation of Web Design”

Performing a Google search for this phrase will yield scores of articles elucidating the value and importance of typography in web-design. After all, even with the proliferation of video and audio content on the internet, virtually every user interface relies on text to deliver and interact with content. In fact, the majority of actual web content is still textual.

There are numerous typographical principles that should be observed when designing and delivering textual content or text-based interface elements. Many of these principles can be addressed with thoughtful and deliberate usage of CSS declarations. In this article, we will cover one method of handling, what are known in typography as, widows.

What are Widows?

Mozilla Developer Network informs us of the traditional meaning of a widow in printing:

“In typography, a widow is the last line of a paragraph that appears alone at the top of a page. (The paragraph is continued from a prior page.)”
https://developer.mozilla.org/en-US/docs/Web/CSS/white-space

As the science of typography has progressed, especially with the advent of hypertext (the “HT” in “HTML”), the term widow has been expanded to refer to single words, or graphical elements, that have been dropped onto their own lines:

“A widow is a very short line – usually one word, or the end of a hyphenated word – at the end of a paragraph or column. A widow is considered poor typography because it leaves too much white space between paragraphs or at the bottom of a page. This interrupts the reader’s eye and diminishes readability.” —Ilene Strizver (fonts.com)

In addition to widows in textual content, web designers and developers often face issues in delivering dynamically rendered user interface elements. For example, how can we handle design elements like icons that are placed after textual elements when we cannot be sure of the rendered text, the text size or the available screen space?

Example (widowed arrow icon):

Here is a link to some other content
>

Sometimes there is just enough room to render the text on one line, but the accompanying iconography is broken-down to the next line. This is common in navigation bars and other areas where horizontal space is limited.

How Do We Fix This?

To solve this problem, the CSS specification and all major browser support a CSS property named white-space.

There are several valid values for this property that tell a browser how to handle the display of white space within a particular HTML element, however, the one we will focus on for the purposes of preventing widows in content or interactive elements is nowrap.

Consider our example above (widowed arrow icon). Our markup may look something like this:

<a href="our-content.html">
    Here is a link to some other content &gt;
</a>

Without knowing for sure that this text will be rendered into a horizontal space large enough to display the text and the arrow (greater-than symbol), we want to ensure that if it does break onto two lines, that at least one word breaks onto the second line along with the arrow.

We can accomplish this with the following markup and styles:

HTML

<a href="our-content.html">
    Here is a link to some other
    <span class="text-nowrap">content &gt;</span>
</a>

CSS
.text-nowrap {
    white-space: nowrap;
}

Note: The text-nowrap HTML class name is provided out-of-the-box in any Liferay theme that includes the Alloy UI framework—which includes Bootstrap 3.
After applying these markup and style enhancements, our previous example will be rendered like this:

Here is a link to some other
content >


We can also use this same approach to prevent widows in text content (in this case, wrapping the last three words in a span with the text-nowrap class applied):

Before

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus massa velit, luctus ut tristique eu, varius eu nisl. Pellentesque posuere erat eget posuere vehicula. Proin turpis ipsum, congue eget suscipit id, volutpat porttitor libero. Pellentesque suscipit vel velit in cursus. Suspendisse luctus venenatis dapibus. Aenean pulvinar lacus dolor, iaculis dignissim est. Pellentesque posuere erat eget posuere vehicula. Proin turpis ipsum, congue eget suscipit id, volutpat porttitor.

After

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus massa velit, luctus ut tristique eu, varius eu nisl. Pellentesque posuere erat eget posuere vehicula. Proin turpis ipsum, congue eget suscipit id, volutpat porttitor libero. Pellentesque suscipit vel velit in cursus. Suspendisse luctus venenatis dapibus. Aenean pulvinar lacus dolor, iaculis dignissim est. Pellentesque posuere erat eget posuere vehicula. Proin turpis ipsum, congue eget suscipit id,
volutpat porttitor.

Liferay Solutions

While applying this technique is relatively simple and straightforward when dealing with specific blocks of markup, how can we apply it to content that is dynamically rendered from web content structures or Liferay navigation items into web content Templates or Application Display Templates (ADTs)?

Hand-coding HTML

Where possible, within the context of HTML content fields for example, simply applying the text-nowrap span to last few words in a piece of HTML content is the simplest approach.

When this is not possible, however, like when we are applying markup to text content within the context of a Web Content template or ADT, we can use Freemarker macros.

Freemarker Macros

Freemarker macros are tailor-made for this type of situation. By declaring a macro that accepts the text, the desired number of words to preserve on a line, and even an optional icon or custom HTML class name, we can prevent widows in most (if not all) dynamic rendering scenarios.

Macros can either be included inline in individual templates (in the case of Web Content templates or ADTs), or imported from an .ftl file via Freemarker’s include directive within the context of themes or portlets.

The preventWidows Freemarker Macro

<#macro preventWidows text class="text-nowrap" icon="" preserveCount="2">
    <#compress>
        <#local preserveCount = preserveCount?number>
        <#local isIcon = icon != "">
        <#local textSplit = text?split(" ")>
        <#local textCount = textSplit?size>
        <#local textPost = "">
        <#local textPre = "">

        <#local textPre = textSplit[0..<textCount - preserveCount]?join(" ")>
        <#local textPost = textSplit[textCount - preserveCount..<textCount]?join(" ")>

        ${textPre?trim}
        <span class="${class}">
            ${textPost?trim}<#if isIcon> ${icon}</#if>
        </span>
    </#compress>
</#macro>

Our macro includes a required text parameter as well as optional parameters for class, icon and preserveCount. (With class defaulting to Bootstrap’s text-nowrap class and preserveCount defaulting to “3”.)

This macro essentially splits the value of the text parameter into an array of words (by splitting on empty spaces) and then uses the preserveCount value to separate the desired number of words to preserve from the rest of the string. These two portions are then joined together into two separate variables: textPre and textPost. By then returning the first part of the string (textPre) as is, and wrapping the second part of the string (textPost) in a nowrap span, we can prevent widows in our rendered content.

Usage example (link with trailing icon):


<a href="${link_href}"${link_target}>
    <@preventWidows
        text=link_text
        icon='<i class="icon icon-chevron-right"></i>'
        preserveCount="1"
    />
</a>

Usage example (text content without icon):

<@preventWidows text=body_text preserveCount="3" />

While the problem of widows in block text seems trivial, remember that as we learned above, “Typography is the foundation of web design.” Furthermore, in cases like the one we’ve outlined above, with our link and trailing icon, solving this particular problem becomes imperative.

Hopefully this approach will allow you to solve similar problems in your own Liferay Portal implementations quickly and easily.

If you have questions on how you can best implement high-quality user interfaces in Liferay DXP and/or need help with your Liferay DXP implementation, please engage with us via comments on this blog post, or reach out to us at https://www.xtivia.com/contact/ or [email protected].

Additional Reading

You can learn more about the importance of typography in web design by visiting Smashing Magazine’s article on the subject or by reviewing The Elements of Typographic Style Applied to the Web, and learn about rags, widows, and orphans at fonts.com. You can also learn more about Freemaker macros in the Freemarker Documentation.

Share This