Balance Text Proposal

Last updated on February 1, 2013

Purpose

The basic algorithm for rendering text is simple: put as much text as will fit on each line, with the remainder on the last line. This results in the fewest possible lines of text being used, but when the text spans more than 1 line, the result can sometimes be visually undesirable.

When rendering text that spans multiple lines, this feature provides the option to automatically balance text across the necessary number of lines.

The intended usage for balance text is for short text elements such as headings, blockquotes, labels, and captions. When balance text is applied to large paragraphs of text, the effort increases and the benefit diminishes, so there probably should be a way to specify a maximum length of text.

Proposed Implementation

CSS

A new value of balanced is proposed for the CSS4 Text module text-wrap property. For example:

  text-wrap: balance;

Text Alignment

Any text-alignment value can be used with balanced text.

Note that once implemented in browsers, any text-alignment can be used with text-wrap:balance;, but text-alignment:justify; will not work with the polyfill because inter-word spacing has already been calculated by the browser before the JavaScript recalculates the line breaks.

Text Direction

Any direction value can be used with balanced text.

Container Size

Balance text does not affect the width of the containing element. The resulting text will always wrap to same number of lines as original text. There may be cases where height changes.

One exception to this may be shrink-to-fit containers.

Boundaries

Balance text is limited to a single block-level element. It does not balance across multiple paragraphs.

Float Intrusions

Float intrusions seems like a solvable case, but the point where there is enough text to wrap around something approaches the point where balance text loses effectiveness, so this may not be a beneficial enough case to implement.

Break tag handling

How text that contains <br> tag needs to be defined.

Text Length Limit

As the length of text increases, the effort increases and the benefit decreases, so it may be desirable to limit length of text to a configurable value, and balance text does nothing if that threshold has been surpassed.

Details

The following proposed algorithm provides a good balance of text in 2 rendering passes.

First Rendering Pass

First, determine the minimum number of lines required for the text using the basic text rendering algorithm. The text rendering algorithm is necessary because, due to the actual order and length of elements in the text, the number of lines may be more than by simply dividing the total text width by the container width.

If there's only 1 line of text, then it is rendered on a single line, and the algorithm is done.

Also, need to determine total width of text (i.e. length of text rendered on 1 infinitely long line). This is determined by a keeping cumulative length as text is rendered.

Second Rendering Pass

Layout text in final pass:

  1. Divide the total text width by the required number of lines to determine the average line width.
  2. Keep track of total width and number of lines and attempt to break at "cumulative average line width" (average line length multiplied by the current line number). This self-adjusts the amount of text on each line (e.g. for a line shorter than average, the next line will tend to be longer than average).
  3. Use center-point (not end) of word to determine where to break for better balance.
  4. Don't allow line length to exceed container line length.
  5. Ignore "cumulative average line width" for last line.

Example

Sample Implementation

This proposal has been implemented in JavaScript as a polyfill and shown in this demo page.

Revision History

Date Name Description of Change
Mar. 16, 2011 Randy Edmunds First draft.
Aug. 13, 2012 Randy Edmunds Implement feedback from Alan Stearns.
Sep. 2, 2012 Randy Edmunds Feedback from Divya Manian, Alan Stearns.
Sep. 13, 2012 Randy Edmunds Reduce algorithm to 2 rendering passes based on suggestion from Alan Stearns. Add link to JavaScript implementation demo.
Feb. 1, 2013 Randy Edmunds Made updates based on feedback from www-style list (L. David Baron, Peter Moulder).