CSS Regions Aren’t Just For Columns

I recently wrote a new text layout engine that uses CSS Regions to do two things:

  1. Wrap text from two different columns around a centered graphic.
  2. Determine the optimal font size for pull-quotes so that they always fill the entire available space. (Quotes that are pulled from a story and displayed in a larger font are frequently referred to as "pull-quotes".)

Here it is in action:


As you can see, CSS regions aren’t just for columns. Regions allows text to flow from one element to another automatically — regardless of size, position, or order — and allows that text to reflow when necessary (when content is added or removed, when elements get resized, when the font sizes changes, etc.). Of course, you can use regions to implement columns if you want to, but remember that you’re not actually creating columns; you’re creating regions that just happen to be arranged as columns. Additionally, you can use the CSS Object Model (CSSOM) to script regions in order to do some very cool things (more on this below).

Here’s a nice simple diagram of CSS regions I stole from Razvan Caliman’s post, Working with CSS Regions and the Shadow DOM:

In the screenshot below, it looks like my content is arranged in columns which wrap around a central graphic and pull-quote:

This is actually done with a series of strategically placed regions:

I’m also using CSS Regions to do something for which it wasn’t really intended: getting text of an arbitrary length to perfectly fill an element of arbitrary size. For example, in the two screenshots below, the first pull-quote is longer, and therefore requires a smaller font size than the one after it.

Using regions, I’m able to dynamically determine the perfect font size regardless of text length or element dimension. It works like this:

  1. All the pull-quotes are extracted from the story (span tags with their class attributes set to "pull_quote").
  2. Pull-quotes are matched to text that appears on each page (since you don’t want a pull-quote that corresponds to text on a previous or subsequent page).
  3. Unique named flows are created for each pull-quote. Those named flows are used for the flow-into CSS property of the quotes, and the flow-from property of the pull-quote elements.
  4. Each region has a regionLayoutUpdate event attached to it.
  5. Each pull quote has a font size of 1em to start. In the regionLayoutUpdate event handler, the regionOverflow property is checked to see if the text fits or not.
  6. If the text fits — if the value of the regionOverflow property is "fit" — the font size is increased by 1/10th of an em. This process is repeated until the text no longer fits (when the regionOverflow property is "overflow").
  7. Now that the text no longer fits, the size is backed down 1/10th of an em and the regionLayoutUpdate event listener gets removed.

In the video, you can actually see the process in action for the first quote (all the quotes are actually being resized simultaneously, but only the quote on the first page is visible). If I really wanted to polish the code, I would optimize the process by using an algorithm that could arrive at the optimal size faster, and I’d probably hide the quotes until they were the right size, but for the demo, I like the visual effect of them expanding.

If you want to check out the code, you can see a demo here (press "Esc" to reveal the regions). Be sure you’re using Google Chrome, and that you have CSS Regions enabled in chrome://flags (and that you’ve restarted your browser after enabling regions). Also, the resizing behavior is still a little buggy, so if you resize your browser window, you might get some unexpected results.