Web Platform Team Blog

Adobe

decor

Making the web awesome

Balancing Text for better readability

balanced-text

Browsers render text without any ability to automatically balance text across lines. For example, when you have text spanning several lines, browsers render it something like this:

  1. Add 1 word at a time to the current line until no more words fit.
  2. Break text at that point and add the next word to a new line.
  3. Repeat until all text has been rendered.

This is designed to efficiently render text using the least number of lines, and it works great for left-aligned text. For example:

The quick brown fox jumped over the lazy dogs

When text is aligned centrally, the same line breaking algorithm is used and each resulting line is centered. This can easily have results which are visually undesirable such as:

The quick brown fox jumped over the lazy dogs

It is more visually pleasing to see multi-line text that is centered to be rendered in a balanced manner like this:

The quick brown fox
jumped over the lazy dogs

This becomes even more of a common problem in responsive design solutions, where the text adjusts to match the width of the viewport. Text that look balanced on on one viewport stops looking good in an another. For example, you may find text rendering like this on smaller screens:

example before

A more balanced rendering of the above text would look more like this:

example after

Current Solutions

Common solutions to this problem are to alter the presentation of the content, or the content itself, to change how it renders. Some ways to do this:

  • manually insert breaks in the text
  • re-word or abbreviate text to change its length
  • alter font-size so text renders longer or shorter

Why Current Solutions Don’t Work Well

These solutions work with printed text. Adobe InDesign has a feature called Balance Ragged Lines that makes this easy for printed text. But these solutions don’t work very well on the web because:

  • width of viewport can change, which can affect container width
  • size of font can change
  • font used by the browser can change
  • content may be edited
  • content may be dynamically loaded (e.g. from a database)

A lot of designers typically attempt to solve this problem by fixing the width occupied by the multiple lines of text. Daniel Mall suggested one such way by using line-breaks manually and setting and unsetting them based on media-queries like so:

  <p>The quick brown fox <br>jumped over the crazy dogs</p>

  @media screen and (min-width: 480px) {
    p br { display: none; }
  }

Thierry Koblenz discusses this topic more in wbr-versus-br. As you can see, this technique requires extra work for the designer and only works for certain layout break points.

A Proposal for Automatic Text Balancing on the Web

I propose we use a text rendering algorithm that would be applied by browser when asked by the designer to do so to automatically balance text across multiple lines, like so:

h1 {
  text-wrap: balance;
}

This would make all h1 elements whenever they span more than 1 line to be automatically rendered such that they have balanced text. As you notice, I only propose an additional value to the existing text-wrap property of CSS.

A detailed explanation one possible algorithm is available in the proposal. Also provided is a demo page with a JavaScript implementation of this proposal.

Next Steps

I would love to have a solution for balanced text be part of the open web tools for designers. We, at Adobe, are planning to propose it to the CSS WG and see if it can be adopted within the Text module for CSS. If you would love to see this in a browser near you, please chime in on the mailing list!

Meanwhile, I have created a jQuery plugin that would allow you to use this on text on the web as a polyfill right now! All you need to do is to call balanceText() on elements you want to apply it on. Please submit pull requests if you find something that can be enhanced and please do let us know any comments you have!

34 Comments

  1. January 30, 2013 at 9:21 am, Pankaj Parashar said:

    How it is different from text-align: justify ??

  2. January 30, 2013 at 9:28 am, Randy Edmunds said:

    @pankaj Justifying your text will only add extra space between words to provide a clean edge on both left and right. Balance Text will change where the text breaks to “balance” it across lines.

    These are independent style decisions, so if this gets implemented in CSS you will be able to do both. Unfortunately, the JavaScript polyfill gets control after browser has already done the justification, so it does not handle both.

  3. January 30, 2013 at 9:43 am, David said:

    What if I want the text to be balanced AND justified ?
    Don’t we need another property ?

  4. January 30, 2013 at 10:14 am, Randy Edmunds said:

    Justifying text uses the text-align property. I am proposing to use the text-wrap property, so it does use a different property.

  5. January 30, 2013 at 10:53 am, Zack said:

    I don’t think authors should have to opt into better line breaking. Just implement it and do it all the time.

  6. January 30, 2013 at 11:10 am, Randy Edmunds said:

    @zack I like the way you think! :) Note that this does require extra processing by the browser, especially on large paragraphs, so we need to be careful not to negatively impact page load time.

  7. January 30, 2013 at 2:25 pm, Garth Braithwaite said:

    Playing around with it, I feel like it is most useful with dynamically generated copy, in a small width, with a larger font. Something like hero banners, short descriptions, or pull quotes.

  8. January 31, 2013 at 5:16 am, Richard Le Poidevin said:

    I think we also need an orphans attribute as we might not always want the lines to balanced to the same length. For instance if you have a paragraph like the HTML5 boilerplate image above you could specify the minimum number of words allowed on the last line and the browser would try to adhere to this.
    Perhaps you’d use:

    p {
    orphans: 3;
    }

    This would mean you want no fewer than three words on the last line. This would provide more control to the layout and allow more consistency.

    On your demo page if I have a form with 5 label, 4 of which are long but don’t quite wrap, but one which is only just long enough to wrap will appear very short.

    Really long label example number one
    Really long label example number one
    Third label example
    which only just wraps
    Really long label example number four
    Really long label example number five

    If we could use orphans, I might set the value to 2 and get
    Really long label example number one
    Really long label example number one
    Third label example which only
    just wraps
    Really long label example number four
    Really long label example number five

    Which is far more balanced for this use case. At the moment I hack this with my CMS to use some nbsp for the last few words.

    http://en.wikipedia.org/wiki/Widows_and_orphans

  9. January 31, 2013 at 8:33 am, Randy Edmunds said:

    @richard Thanks for the detailed response! I proposed this feature on the W3C www-style list yesterday, so you may want to join the technical discussion there: http://lists.w3.org/Archives/Public/www-style/2013Jan/0597.html

  10. February 01, 2013 at 10:25 am, Ondras said:

    Very smart and useful proposal! As far as the algorithm goes, why not http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness ?

  11. February 01, 2013 at 10:56 am, Randy Edmunds said:

    @ondras Thanks for the link. My goal is to get this feature into browsers because it’s been something I’ve wanted for a long time. I proposed an algorithm that I think is more efficient, but I will let the community decide. Also, the JavaScript polyfill I provided is open source, so anyone is welcome to fork it and improve it.

  12. February 02, 2013 at 12:41 am, Joe Denard said:

    Very nice! I was waiting for you guys to get into improving linebreaking on the web, the ones we have now are pretty bad.

    The “add 1 word until the line is filled” guaranteeing the least number of lines is a bit misleading though, since that also depends on spacing. And using an implementation of Knuth-Plass, like Typekit/Adobe recent hire Bram Stein’s Typeset, already results in paragraph with better spacing and a lower number of lines today.

  13. February 02, 2013 at 5:59 am, Ondras said:

    Randy, this might be relevant as well: http://www.bramstein.com/projects/typeset/

  14. February 02, 2013 at 7:47 am, Randy Edmunds said:

    @joe Thank you for the encouragement! That statement is qualified by saying the claim is for the “basic algorithm for rendering text” so I was not trying to be misleading. Yes, there are now many ways to change that algorithm, and hopefully this becomes one more!

  15. February 04, 2013 at 11:17 am, tomeoftom said:

    Incredibly great suggestion. I would *love* this.

  16. February 04, 2013 at 2:25 pm, Travis Northcutt said:

    How would this behave when text-align: left; is set? IMO (I’m open to being shown how I’m wrong), the balanced example is worse when the text is aligned to one side.

  17. February 04, 2013 at 3:40 pm, Randy Edmunds said:

    @travis The behavior (i.e. where the line breaks) is the same for all text-align settings (e.g. left, center, right, justify).

    Since the resulting width of each block of text is calculated independently, it probably doesn’t make sense for an example such as @richard provided above.

  18. February 05, 2013 at 10:04 am, J. Hogue said:

    Great, great idea, and with the success of the algorithm used in InDesign that I have come to miss greatly since working on the web, I’d say you guys are the ones to push it forward. While you are at it, widows, orphans, and more control over minimum characters before and after a hyphen would be very smart to implement, esp. as designers start to use the CSS3 columns module and even newer flex-box features.

  19. February 06, 2013 at 12:28 pm, kelly johnson said:

    Nice idea. But wow, what a math nightmare! Typography is the key… so the algo would have to: count all characters, discern between the space needed for say, a piping symbol versus a capital B, which I guess would happen after it first detects a fixed-width font versus variable like mono-type versus arial, then, it would have to get the available width of the container the text is in, which I would guess mean taking a quick trip through the DOM to know the parent and then read any css applied for width and then some funky math to even it all out!

    At least, that’s what my no-math-mind is thinking…. would be awesome if the resolution of 96px versus 72px for Windows OS and Mac OS wouldn’t even play into the implementation, but would it?

    Either way, a good step in the direction of good ‘ole graphic design instead of some other new ‘feature’ for feature sake and a bullet point on a sales sheet!

  20. February 06, 2013 at 8:01 pm, Randy Edmunds said:

    @kelly Actually, it’s not a nightmare at all. All of those things you mention, including resolution, are already done as part of the text rendering process. The only difference is some new code to figure out where to break the code in more balanced way.

    On the web, the font size, container width, screen resolution, etc. are all variable (not fixed like in the print graphic design world), so this feature greatly simplifies something that takes a lot of work today. This is being proposed to the CSS Spec for everyone to use for free, so there’s no “sales sheet”.

  21. February 08, 2013 at 7:51 am, IM BLIND said:

    For a blog about readability, you have the oddest choice of text color. It appears as an almost white grey on my screen that hardly offers any contrast with the background white. The foreground color on this textarea is even whiter than the main blog text color…

  22. February 08, 2013 at 8:36 am, Alex Dowad said:

    Great idea! But I second the notion that *all* browsers should use a smarter text wrapping algorithm, all the time. With a tight, optimized implementation in a low-level language like C or C++, I don’t think the difference in page load time would be significant. Besides, if a page is very long, the browser just needs to wrap enough text to display the first screenful, and then it can continue working in the background as the user is reading. Additionally, this is the kind of thing which is amenable to parallelization on multi-core CPUs. (Just divide the text up into paragraphs, and then wrap the paragraphs in parallel.)

  23. February 08, 2013 at 8:49 am, joe lackner said:

    great article. this is something often not considered in web design, but it certainly worth investigating solutions for. if this was built into css, it will lead to a more beautiful web.

    cheers!

  24. February 08, 2013 at 12:18 pm, Nijiko Yonskai said:

    I agree with what you are saying, but the text on this blog is really hard on the eyes so it’s hard to take you seriously. It’s weight is too thin, maybe this is due to chrome; I have not investigated your elements to figure out why, yet it is a large problem. Even the headers are too light in weight, I had to force myself to read this like a plate full of vegetables to a kid who only likes candy.

    Good suggestions though, I agree.

  25. February 08, 2013 at 11:23 pm, Christopher Chedeau said:

    Donald Knuth wrote a paper in 1990 that explains how to find the optimal set of break points in a text based on a cost function. That would be really nice to use this algorithm as it has proof of optimality instead of all the attempts of heuristics.

    http://bowman.infotech.monash.edu.au/~pmoulder/line-breaking/knuth-plass-breaking.pdf

  26. February 09, 2013 at 12:34 am, Random Drive-by comment said:

    The Knuth-Plass algorithm is implemented in C in the open-source Gnu Core Utilities “fmt” program. It’s plenty fast for rendering in a browser. http://www.gnu.org/software/coreutils/

  27. February 09, 2013 at 4:52 am, Arthur Corenzan said:

    There’s a post about this with a simple solution in JavaScript – it’s in portuguese:
    http://simplesideias.com.br/titulos-palavras-orfas-e-javascript

  28. February 11, 2013 at 3:51 pm, Alejandro Gutierrez said:

    Really fine work here. Thanks for putting it together – pretty clutch for typography lovers!

  29. February 11, 2013 at 9:20 pm, Elliot Geno said:

    I actually built the same thing with Flash YEARS ago. It was quite useful and it looks way better that orphaned/widowed text! This is a no-brainer spec that should have been implemented years ago and probably won’t be implemented for years to come. Yay committees!

  30. February 11, 2013 at 11:48 pm, Matias Larsson said:

    Nice work! I hope it gets added to both browsers and standards.

  31. February 13, 2013 at 2:29 am, Dennis said:

    Pretty funny how you write about better readability and use 130+ something line length and not nearly enough leading to make up for it.

  32. February 13, 2013 at 7:48 am, Indra Kupferschmid said:

    Have you ever looked at this website on a mobile device? Ridiculous!

  33. February 22, 2013 at 1:20 pm, Luke said:

    Another solution is to use   between words where you don’t want a break to occur.

    Admittedly, it’s not a very scalable solution and requires direct access to the HTML, but it’s worth doing for the occasional headline/introduction text, because you effectively get to teach the browser a bit about language – which phrases to keep together, like prepositions and names – and then you can put   between the last few words to achieve the same orphan-avoiding effect as @richard ‘s proposed orphans attribute.

  34. June 03, 2013 at 9:50 am, Balancing Text for better readability - Typography n Fonts said:

    [...] Balancing Text for better readability [...]