The next problem for CSS3 to address will be layouts. Until now we've got by with floats, relative positioning and negative margin tricks, but we still have to work incredibly hard to produce anything beyond the fairly standard two- to three-column layouts.
The W3C and the browser makers are aware of this problem, and working on a range of solutions. Chief among them (you may be surprised to learn) is the Internet Explorer team. IE10 looks set to herald an exciting new era of CSS layouts, making possible rich, dynamic and eye-catching websites that were previously beyond our reach.
In this article I'm going to take a look at the various layout methods that are at different stages of development, from the well-implemented to the purely theoretical. Perhaps not all of these will make it to the stage where we're able to use them (or, at least, not in their current form), but it's worth taking a look to see where the future lies. If you want more detail about some of the methods in this article, as well as much more of what CSS3 offers, I humbly recommend my book, The Book of CSS3.
Columns
Distributing content over multiple columns is a staple of print, and the CSS Multi-Columns module brings the same flexibility to the web. There are two approaches to making columns, both of which use a different property (applied to the parent element). The first is prescriptive, where you explicitly set a number of columns to flow the text into. The following code creates three columns of equal width, filling the width of the parent:- div { column-count: 3; }
- div { column-width: 140px; }
- div {
- column-gap: 28px;
- column-rule: 2px dotted #ccc;
- }
Flexible box
The Flexible Box Layout module ('FlexBox') provides a method of automatically resizing elements within their parent without having to calculate height and width values. As a simple example, imagine you have two child elements and you want them to fill their parent (which has a variable width) in such a way that both have the same width. You could do this with percentages, but it gets complicated when borders, padding and margins are involved. The FlexBox solution is much simpler:- .parent { display: box; }
- .child-one, .child-two { box-flex: 1; }
- .child-one { box-flex: 1; }
- .child-two { box-flex: 2; }
This is an easier concept to show than to explain, so you can see it more clearly in this example of CSS FlexBox (you'll need Firefox, Chrome, Safari, or IE10PP). Try resizing the browser window to see it scale.
As well as dynamically changing an element's size, FlexBox can also apply properties to a parent that control where any empty space is distributed, setting the position of its children. The box-align property acts on a child element's width (by default, although that can be changed), and there's a companion property, box-pack, that acts on its height. Here's how it works:
- .parent {
- box-align: center;
- box-pack: center;
- display: box;
- height: 200px; width: 100px;
- }
- .child {
- box-flex: 0;
- height: 100px; width: 100px;
- }
Grid
Brand new to IE10PP is the Grid Layout system, which I'm quite excited about. The first step to using it is to define your grid with rows and columns. You can use length values, the auto keyword, and a new length unit, fr, which is shorthand for 'fraction'. Take a look at this code example:- div {
- display: grid;
- grid-columns: 1fr 3fr 1fr;
- grid-rows: 100px auto 12em;
- }
Now that we have our grid, we can position content on it. Using HTML5 sectioning elements I can create a really simple common page layout:
- header { grid-column: 1; grid-column-span: 3; grid-row: 1; }
- nav { grid-column: 1; grid-row: 2; }
- article { grid-column: 2; grid-row: 2; }
- aside { grid-column: 3; grid-row: 2; }
- footer { grid-column: 1; grid-column-span: 3; grid-row: 3; }
I've made an demo of a layout using these elements, which you can see in this example of CSS Grid Layout, but you'll have to use the IE10 Platform Preview to see it. If you don't have access to IE10PP, you can see it in this screenshot.
Template
Another approach to grid systems is provided by the Template Layout module. This uses a somewhat different syntax, the first step of which is assigning position values using an alphabetical character and the position property:- header { position: a; }
- nav { position: b; }
- article { position: c; }
- div { display: 'abc'; }
- div {
- display:
- 'baa'
- 'bcc';
- }
The demo uses JavaScript so should work in most modern browsers, but if you can't see it just take a look at the picture from the Grid Layout section – it's exactly the same! Also, remember I said that there’s more to come from the Grid Layout module? That includes properties which adopt the Template syntax, as in this example:
- header { grid-cell: a; }
- article { grid-cell: b; }
- div {
- display: grid;
- grid-template: 'a' 'b';
- }
Positioned floats
The current float property let's us float text around an element to either the left or right, but an extended property in IE10PP lets us take that a step further and means that we can position the floated element wherever we like, and the rest of its sibling content will still flow around it. All that's required is a new value for float, and some positioning properties:- div {
- float: positioned;
- left: 200px; position: absolute; top: 100px; width: 250px;
- }
- div { wrap-type: top-bottom; }
- div {
- float: positioned;
- grid-column: 2;
- grid-row: 2;
- }
Exclusions
So Positioned Floats allow you to flow content around a box-shaped element, but I mentioned that the specification also covers shaped floats. This idea comes from a module proposed by Adobe: CSS Exclusions. There are two key properties in this module; the first, wrap-shape, allows you to create ellipses, rectangles or polygons, which will dictate the form of the content flow; for example:- div { wrap-shape: circle(50%, 50%, 100px); }
- div { wrap-shape: polygon(0,100px 100px,100px 50px,0); }
- div {
- wrap-shape: circle(50%, 50%, 100px);
- wrap-shape-mode: around;
- }
Regions
A further suggestion by Adobe, CSS Regions, provide a way of flowing content across multiple different elements. This is done by first declaring the element from which the content will be supplied, using a unique string value identifier with the flow property, then selecting which regions to flow that content through with the from() function on the content property:- .content { flow: foo; }
- .target1, .target2 { content: from(foo); }
The Regions spec isn't implemented in any browsers as yet but, as with Exclusions, you can download the prototype for from Adobe Labs and try it out for yourself.

No comments
Post a Comment