Intricate Fluid Layouts in Three Easy Steps
The Year of the Script may have drawn attention away from CSS but building fluid, multi-column, cross-browser CSS layouts can still be as unpleasant as a lump of coal. Read on for a worry-free approach in three quick steps.
The layout system I developed, YUI Grids CSS, has three components. They can be used together as we’ll see, or independently.
The Three Easy Steps
- Choose fluid or fixed layout, and choose the width (in percents or pixels) of the page.
- Choose the size, orientation, and source-order of the main and secondary blocks of content.
- Choose the number of columns and how they distribute (for example 50%-50% or 25%-75%), using stackable and nestable grid structures.
The Setup
There are two prerequisites: We need to normalize the size of an em
and opt into the browser rendering engine’s Strict Mode.
Ems are a superior unit of measure for our case because they represent the current font size and grow as the user increases their font size setting. This flexibility—the container growing with the user’s wishes—means larger text doesn’t get crammed into an unresponsive container. We’ll use YUI Fonts CSS to set the base size because it provides consistent-yet-adaptive font-sizes while preserving user control.
The second prerequisite is to opt into Strict Mode (more info on rendering modes) by declaring a Doctype complete with URI. You can choose XHTML or HTML, and Transitional or Strict. I prefer HTML 4.01 Strict, which looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
Including the CSS
A single small CSS file powers a nearly-infinite number of layouts thanks to a recursive system and the interplay between the three distinct components. You could prune to a particular layout’s specific needs, but why bother when the complete file weighs scarcely 1.8kb uncompressed? Compressed, YUI Fonts and YUI Grids combine for a miniscule 0.9kb over the wire.
You could save an HTTP request by concatenating the two CSS files, or by adding their contents to your own CSS, but I’ll keep them separate for now:
<link href="fonts.css" rel="stylesheet" type="text/css">
<link href="grids.css" rel="stylesheet" type="text/css">
Example: The Setup
Now we’re ready to build some layouts.
Step 1: Choose Fluid or Fixed Layout
Choose between preset widths of 750px, 950px, and 100% by giving a document-wrapping div an ID of doc
, doc2
, or doc3
. These options cover most use cases, but it’s easy to define a custom fixed width.
The fluid 100% grid (doc3
) is what I’ve been using almost exclusively since it was introduced in the last YUI released.
<body>
<div id="doc3"></div>
</body>
All pages are centered within the viewport, and grow with font size. The 100% width page (doc3
) preserves 10px of breathing room via left and right margins. If you prefer your content flush to the viewport, just add doc3 {margin:auto}
to your CSS.
Regardless of what you choose in the other two steps, you can always toggle between these widths and behaviors by simply swapping the ID value. It’s really that simple.
Example: 100% fluid layout
Step 2: Choose a Template Preset
This is perhaps the most frequently omitted step (they’re all optional), but I use it nearly every time. In a source-order-independent way (good for accessibility and SEO), “Template Presets” provide commonly used template widths compatible with ad-unit dimension standards defined by the Interactive Advertising Bureau, an industry association.
Choose between the six Template Presets (.yui-t1
through .yui-t6
) by setting the class value on the document-wrapping div
established in Step 1. Most frequently I use yui-t3
, which puts the narrow secondary block on the left and makes it 300px wide.
<body>
<div id="doc3" class="yui-t3"></div>
</body>
The Template Presets control two “blocks” of content, which are defined by two div
s, each with yui-b
(“b” for “block”) class values. Template Presets describe the width and orientation of the secondary block; the main block will take up the rest of the space.
<body>
<div id="doc3" class="yui-t3">
<div class="yui-b"></div>
<div class="yui-b"></div>
</div>
</body>
Use a wrapping div
with an ID of yui-main
to structurally indicate which block is the main block. This wrapper—not the source order—identifies the main block.
<body>
<div id="doc3" class="yui-t3">
<div id="yui-main">
<div class="yui-b"></div>
</div>
<div class="yui-b"></div>
</div>
</body>
Example: Main and secondary blocks sized and oriented with .yui-t3
Template Preset
Again, regardless of what values you choose in the other steps, you can always toggle between these Template Presets by toggling the class value of your document-wrapping div
. It’s really that simple.
Step 3: Nest and Stack Grid Structures.
The bulk of the power of the system is in this third step. The key is that columns are built by parents telling children how to behave. By default, two children each consume half of their parent’s area. Put two units inside a grid structure, and they will sit side-by-side, and they will each take up half the space. Nest this structure and two columns become four. Stack them for rows of columns.
An Even Number of Columns
The default behavior creates two evenly-distributed columns. It’s easy. Define one parent grid with .yui-g
(“g” for grid) and two child units with .yui-u
(“u” for unit). The code looks like this:
<div class="yui-g">
<div class="yui-u first"></div>
<div class="yui-u"></div>
</div>
Be sure to indicate the “first
“ unit because the :first-child pseudo-class selector isn’t supported across all A-grade browsers. It’s unfortunate we need to add this, but luckily it’s not out of place in the markup layer since it is structural information.
Example: Two evenly-distributed columns in the main content block
An Odd Number of Columns
The default system does not work for an odd number of columns without using the included “Special Grids” classes. To create three evenly distributed columns, use the “yui-gb
“ Special Grid:
<div class="yui-gb">
<div class="yui-u first"></div>
<div class="yui-u"></div>
<div class="yui-u"></div>
</div>
Example: Three evenly distributed columns in the main content block
Uneven Column Distribution
Special Grids are also used for unevenly distributed column widths. For example, .yui-ge
tells the first unit (column) to take up 75% of the parent’s space and the other unit to take just 25%.
<div class="yui-ge">
<div class="yui-u first"></div>
<div class="yui-u"></div>
</div>
Example: Two columns in the main content block split 75%-25%
Putting It All Together
Start with a full-width fluid page (div#doc3
). Make the secondary block 180px wide on the right (div.yui-t4
). Create three rows of columns: Three evenly distributed columns in the first row (div.yui-gb
), two uneven columns (66%-33%) in the second row (div.yui-gc
), and two evenly distributed columns in the thrid row.
<body>
<!-- choose fluid page and Template Preset -->
<div id="doc3" class="yui-t4">
<!-- main content block -->
<div id="yui-main">
<div class="yui-b">
<!-- stacked grid structure, Special Grid "b" -->
<div class="yui-gb">
<div class="yui-u first"></div>
<div class="yui-u"></div>
<div class="yui-u"></div>
</div>
<!-- stacked grid structure, Special Grid "c" -->
<div class="yui-gc">
<div class="yui-u first"></div>
<div class="yui-u"></div>
</div>
<!-- stacked grid structure -->
<div class="yui-g">
<div class="yui-u first"></div>
<div class="yui-u"></div>
</div>
</div>
</div>
<!-- secondary content block -->
<div class="yui-b"></div>
</div>
</body>
Example: A complex layout.
Wasn’t that easy? Now that you know the three “levers” of YUI Grids CSS, you’ll be creating headache-free fluid layouts faster than you can say “Peace on Earth”.
About the author
Nate Koechley is a Yahoo! frontend engineer and designer based in San Francisco‘s Mission district. When he’s not helping design and build the open-source Yahoo! User Interface (YUI) Library he edits the YUIBlog, promotes accessibility, defines Yahoo! browser support policies, writes occasionally at his personal blog, and presents at conferences around the globe.