Six CSS Layout Features To Look Forward To

Advertisement

A few concerns keep bobbing up now and then for Web developers, one of which relates to how to lay out a given design. Developers have made numerous attempts to do so with existing solutions. Several articles have been written on finding the holy grail of CSS layouts, but to date, not a single solution works without major caveats. At the W3Conf, I gave a talk on how the CSS Working Group is attempting to solve the concerns of Web developers with multiple proposals. There are six layout proposals that are relevant to us, all of which I described in the talk. Here is a little more about these proposals and how they will help you in developing websites in the future.

Generated Content For Paged Media

This proposal outlines a set of features that would modify the contents of any element to flow as pages, like in a book. A video demonstration shows how to use paged media to generate HTML5 slideshows (look at the demos for GCPM in the Opera Labs Build to play with the features more). To make the content of an element be paged, you would use this syntax:

@media paged {
  html {
    width: 100%;
    overflow-style: paged-x;
    padding: 5%;
    height: 100%;
    box-sizing: border-box;
  }
}

This would make the content look something like this:

screenshot

Here, @media paged indicates that the browser understands paged media and that all of the selectors specified for it should have their styles applied when paged media is supported. Then, you indicate which selector you want to be paged (in the above example, the selector is the html element itself) by specifying the property overflow-style: paged-x. This will simply make the content paged; if you want paged controls to be visible, you need to specify overflow-style: paged-x-controls.

The properties break-before, break-after break-inside can be used to control where the content falls within the pages. For example, if you want headings to only appear with their corresponding content and never at the end of the page or standing alone, you can specify that:

h3, h2 {
break-after: avoid;
}

This ensures that if a heading occurs on the last line of a page, it will be pushed to the next page with the content that it introduces.

API

Two properties are available on an element whose content is paged: currentPage and pageCount. You can set the currentPage property via JavaScript, which would trigger a page change on that element. This would then trigger an onpagechange event on that element, which you could use to run other scripts that are required when the page changes. The pageCount property stores the total number of pages in the paged element. These properties are useful for implementing callbacks that should be triggered on page change; for example, to render notes for a particular slide in a slide deck.

Multiple Columns

Multiple columns are now available in most browsers (including IE10!), which makes them pretty much ready to use on production websites. You can render the content of any element into multiple columns simply by using column-width: <length unit> or column-count: <number>. As with paged content, you can use break-before, break-after or break-inside to control how the content displays within each column. You can also make one of the child elements span the whole set of columns by using column-span: all. Here is how that would look:

screenshot

Columns are balanced out with content by default. If you would prefer that columns not be balanced, you can set that by using column-fill: auto property. Here is an example of the default behaviour (i.e. column-fill: balanced):

screenshot

And here is an example of the column-fill: auto behavior:

screenshot

Note that the last column is empty, and each column is filled one after the other.

Regions

The closest equivalent to regions would be InDesign’s linking of text frames. With the properties in this proposal, you can make the content of selected elements flow through another set of elements. In other words, your content need not be tied to the document flow any longer.

To begin, you need to select elements whose content will be part of a “named flow,” like this:

article.news { flow-into: article_flow; }

Here, all of the content in the article element with the class name news will belong to the flow named article_flow.

Then, you select elements that will render the contents that are part of this named flow:

#main {
flow-from: article_flow;
}

Here, the element with the ID main will be used to display the content in the flow named article_flow. This element has now become a region that renders the content of a named flow. Note that any element that is a region establishes new “block-formatting contexts” and “stacking contexts.” For example, if a child element is part of a flow and is absolutely positioned, it will now only be absolutely positioned with respect to the region it belongs to, and not to the whole viewport.

You can also tweak the styles of content that flows through a region:

@region #main {
  p { color: indianred; }
}

screenshot

API

An interface named getNamedFlow and an event named regionLayoutUpdate are available for elements that are regions.

getNamedFlow

This returns the flow that that particular region is associated with. The properties available are:

  • overflowA read-only boolean that tells you whether all of the content of the named flow fits within the regions that are part of the flow or whether it overflows.
  • contentNodesA NodeList of all the content elements that belong to the flow.
  • getRegionsByContentNodeThis returns all of the regions that a particular content element would flow through. A very long paragraph might flow through more than one region; with this method, you can retrieve all of the regions that that paragraph element flows through.
  • regionLayoutUpdateThis event gets triggered every time an update is made to the layout of a region. If the region’s dimensions are altered, then the child content elements that are part of that region might alter, too (for example, a few might move to another region, or more child elements might become part of the region).

Exclusions

  • Draft specification (a combination of two proposals: “Exclusions” and “Positioned Floats”)
  • Demo
  • Browser support: IE 10+

Exclusions allow inline content to be wrapped around or within custom shapes using CSS properties. An element becomes an “exclusion element” when wrap-flow is set to a value that is not auto. It can then set the “wrapping area” for inline text outside or within it, according to various CSS properties. The wrap-flow can take the following values: left, right, maximum,both, clear or the default value of auto. Here is how each of these values would affect the inline content around the exclusion element:

screenshot

wrap-flow: auto

screenshot

wrap-flow: right

screenshot

wrap-flow: both

screenshot

wrap-flow: clear

screenshot

wrap-flow: maximum

The wrap-margin property can be used to offset the space between the boundary of the exclusion element and the inline text outside of it. The wrap-padding property is used to offset the space between the boundary of the exclusion element and the inline text inside it.

screenshot

In the above image, the space between the content outside of the red dashed circular border and the black text outside of it is determined by the wrap-margin, while the space between the red dashed circular border and the blue text within it is determined by the wrap-padding.

Now comes the fun part: specifying custom shapes for the wrapping area. You can use two properties: shape-outside lets you set the wrapping area for inline text outside of the exclusion element, while shape-inside lets you set the wrapping area for inline text inside the exclusion element.

screenshot

Both of these properties can take SVG-like syntax (circle(50%, 50%, 100px);) or image URLs to set the wrapping area.

Exclusions make magazine-like layouts on the Web a trivial matter and could spark the kind of creative use of content that we are used to seeing in print!

Grid

Grid properties allow you to throw block-level elements into a grid cell, irrespective of the flow of content within the grid parent element. An element becomes a grid when display is set to grid. You can then set the number of columns and rows with the grid-columns and grid-rows properties, respectively. You can then declare each child selector itself as part of a grid cell, like so:

#title {
grid-column: 1; grid-row: 1;
}

#score {
grid-column: 2; grid-row: 1;
}

You can also use a template to plan the grid:

body {
  grid-template: "ta"
                 "sa"
                 "bb"
                 "cc";
}

In this syntax, each string refers to a row, and each character refers to a grid cell. In this case, the content of grid cell represented by the character a spans two rows but just one column, and the content represented by b spans two columns but just one row.

Now you can set any of the child element’s grid-cell position:

#title {
grid-cell: 't';
}

This will make the element with the ID title within the body element to be positioned in the grid cell represented by the character t in the grid-template property.

If you are not using grid-template, you can also declare how many columns or rows a particular element should occupy with the grid-row-span and grid-column-span properties.

Flexbox

Flexbox allows you to distribute child elements anywhere in the box (giving us the much-needed vertical centering), along with flexible units that let you control the fluidity of the child elements’ dimensions.

Note that this specification has changed substantially since it was first proposed. Previously, you would invoke Flexbox for an element with display: box, but now you would use display: Flexbox to do so. Child elements can be vertically aligned to the center with flex-pack: center and horizontally aligned to the center with flex-align: center. Also note that all elements that obey the Flexbox need to be block-level elements.

How Do Various Properties Interact With Each Other?

You might wonder how to use these properties in combination. The following table shows which of these features can be combined.

Paged Media Multiple Columns Regions Exclusions Grid Flexbox
Paged Media
Multiple Columns
Regions
Exclusions
Grid
Flexbox

As you can see, the multiple-column properties can be used in conjunction with generated content for paged media, regions and exclusions. But grid, Flexbox and regions are mutually exclusive (i.e. if an element is a grid, it cannot be a Flexbox or region). Do note that, as Alan Stearns says in the comments, while a grid container cannot be a Flexbox or a region, a grid cell could become a region, or a Flexbox child item could be a region.

A Note Before You Rush Out To Use Them In Client Projects

The specifications are always changing, so be careful with them. Except for multiple columns, I would recommend using these strictly in personal projects and demos. The syntaxes and properties used in some of the demos are different from what you would find in the actual specifications, because they have changed since the builds that support a previous version of the specification came out. Also, because they are still unstable, all of these properties are vendor-prefixed, which means you have to add support for each prefix as support is added.

If you do use these features, just make sure that the content is readable in browsers that do not support them. The easiest way to do this would be to use feature detection and then use CSS to make the content readable when the feature is unsupported.

Help The Working Group!

Do these layout proposals sound exciting to you? Jump on the www-style mailing list to provide feedback on them! Just note that the mailing list will flood your inbox, and you should carefully filter the emails so that you pay attention only to the drafts you are interested in.

Write demos and test how these work, and if you find bugs in the builds that have these properties, provide feedback to the browser vendors and submit bug reports. If you have suggestions for changing or adding properties to these proposals, do write in in the mailing list (or you can bug me on Twitter)!

These are exciting times, and within a few years the way we lay out Web pages will have changed dramatically! Perhaps this will finally sound the death knell of print. (Just kidding.)

(al)

.checklist th, .checklist tr, .checklist td { font-family: “Proxima Nova Bold”, Arial, sans-serif; }
.checklist td { border: 1px solid #eee; }
.checklist th { background-color: #eee; color: #333; border: 1px solid #fff; }

↑ Back to top

Divya Manian is a web opener for Opera Software in Seattle. She made the jump from developing device drivers for Motorola phones to designing websites and has not looked back since. She takes her duties as an Open Web vigilante seriously which has resulted in collaborative projects such as HTML5 Boilerplate.

  1. 1

    Been using flexbox for a little bit and its really great. Looking to give these new features a go.

    0
  2. 2

    The grid related stuff looks potentially extremely useful as it could replace all kinds of trickery that’s needed to achieve grids these days.

    But columns? I never knew people wanted columns in web content and I still don’t. I can’t speak for other people of course, but for me, column content would be the worst way to read on the web! You’d have to scroll back up at the end of each column.

    0
    • 3

      I love multicolumn layout, and paged media. It is so sweet.

      I do not however, see why it cannot be used in grid. Lets have a simple 3×3 grid: “abb” “abb” “ccc”. put menu in a, content in b, and footer and controls in c. content could then be multi-columned and paged INSIDE a “b”. It makes perfect sense, to me.

      0
    • 4

      I think the use of this feature’ll be great if you want to use css attribut media=”print”. To design a big article on text colum and so save space on your paper and organize it better for reading on paper.

      0
    • 5

      Not quite. Nowadays screens are wide, but long paragraphs are hard to read. Breaking content in columns makes sense.

      That’s why most layouts today just settles on a fixed width and waste a lot of horizontal space: making multi-column layouts with CSS is harder.

      0
  3. 6

    Michael Burgstahler

    December 15, 2011 7:48 am

    Um… flexbox is actually supported in Safari 5.1+, as well as in Firefox 7+ (if a bit patchy)

    0
    • 7

      No, they actually use a previous invalid version of the spec for their implementations. The most recent spec version has only been implemented in Chrome for now.

      0
      • 8

        Michael Burgstahler

        December 15, 2011 8:06 am

        Oh… didn’t know that. I’ve already used it successfully in Safari + Firefox for 6 months in a major project – thanks to a tip from the awesome @simurai :)

        0
  4. 9

    Really looking forward to Regions and Flexbox! They’re going to make web layout so much easier (and allow for things that aren’t currently possible)

    Also nice to see IE10 taking the lead here, although I hope firefox can catch up soon (as their users tend to be the second slowest to update)

    0
  5. 10

    Yeah, this is awesome, I can’t wait to start trying out some of these new features!

    0
  6. 11

    Flexible Box layout is awesome but it’s going to be a bit a pain for a while if you’ve used the old spec and want to support the new one as well. It isn’t just adding vendor prefixes because you need to maintain two versions of the spec. Fun.

    If this was for something less awesome than Flexbox I’d be more irritated.

    0
    • 12

      Yes, which is why I had always been an advocate of don’t use flexbox till spec is stable :(

      0
      • 13

        I only used it on personal things where it doesn’t matter if browser support is sketchy. Any word on if browsers will continue to support the old spec once the new one is included?

        0
        • 14

          I cant comment on what each browser policy is, but I think typically they try to support it for at least 2 versions before dropping support.

          0
  7. 15

    As for the multi-column digest … It’s clever, but I can’t imagine reading down a long thin column only to have to scroll up to the top of the page to keep reading to be anything but a leap in the wrong direction. It’s a web page, not a newspaper! Is there a better example of how this can be used?

    0
    • 16

      I’ve been doing some work on this very concept. Multiple columns work very well with paged media, and can work for small pieces of text so long as the containing element isn’t taller than the browser viewport.

      0
  8. 17

    Hi Divya,

    Don’t you have an extra height:100% in the @media paged rule (instead of width:100%)

    0
  9. 19

    Divya,

    While you’re correct that “if an element is a grid, it cannot be a Flexbox or region” you should be able to position regions using flexbox or grid. A grid cell could become a region, or a flexbox child could be a region. So I find your interaction table a little misleading. Perhaps you could emphasize that this shows what properties can be combined on a single element?

    0
  10. 21

    Shape inside/outside stuff is pretty useless without a normal typographic engine and hyphenation. First browsers should should make justification not look like crap.

    0
    • 22

      Shapes inside/outside, as well multi-columns, etc, works well with &shy; (can be done automatically on server, or client using quite small JS) – works already in Opera or Firefox, or even better with automatic hyphenation (currently supported only in IE 10).

      0
  11. 23

    You may be the arsonist of the semantic web ( :P ), but you are the queen of CSS! Excellent talk.

    0
  12. 24

    Regions works well with FF8.0 having the correct url fetched using Chrome15 since the link giving through FF is smthng IE. …..

    0
    • 25

      Hi! I’m going crazy with this pagination thing. Have tried saverel approches now and can’t quite get it right.I’m using this code (with your example), but when I click on next page it displays the exact same posts, but in the URL it shows /page/2 4, ‘posts_per_page’ => 5,’paged’ => ( get_query_var(‘paged’) ? get_query_var(‘paged’) : 1 ))); $count = 0; if(have_posts()):while(have_posts()):the_post();?> Any thoughts on why?I do have multiple loops and also a $count variable in this page template. Thanks!

      0
  13. 26

    Great descriptive article.Thank you for sharing.

    0
  14. 27

    Having a column layout would make websites more horizontally navigated. The New York Times set up their app for iPad in this way, and it reads and navigates comfortably. Unfortunately, I think it’ll be easy for it to be misinterpreted or misused by those who may not have a good grasp on typography and layout. As I imagine this will create sites with painfully long columns (designer still thinking of the web being vertically-scrolled and not considering page height). Dunno, but it would be interesting to experiment with. I’m intrigued!

    0
  15. 28

    Hi this is awesome…. Thanks Goodness… IE announces auto-update for old browsers IE 6 & IE 7 to IE 8 – XP then for IE8 in vista and windows it will be updated to IE 9 . I am eagerly looking to try out some of these new features you given in the article. I am looking for microsoft to step forward to IE10 to auto-updated in all OS in coming years…. :)

    0
  16. 32

    To be honest, I am not too excited about any of these except the flex-box and flowing around shapes. Everything else seems to be redundant (almost anything these “features” seem to solve can be quite easily achieved with existing CSS).

    Furthermore multi-column text which is not a really good idea for the digital canvas, seems to be getting way too much focus that could be better utilised.

    Something I think most will agree that would be useful when it comes to layout (especially in responsive design) are box-ordinal-group and box-orient, yet still lack heavily on browser-support.

    0
  17. 33

    Most of the examples shown here seem to allow the ability for more traditional magazine or newspaper layout, which, if used aggressively or consistently, in my opinion, is going to obstruct readability (funky kearning, widows, orphans, etc.). If used willy-nilly, many of these new properties will start reintroducing content-display that should have stayed and died with newspaper design.

    Last thing, hopefully this won’t inspire folks to write more copy just to play with it. Bad copy is bad copy. If a one column teaser does it, render just one.

    0
  18. 34

    All of these new techniques and abilities are great… For modern browsers. But the real world of development demand sites that work for the majority of the market share… Which makes these fancy new possibilities worthless unless there was a way to FORCE the user to upgrade their browser.

    Seriously, its the biggest catch 22 of all. So frustrating. Reset, DIV and float… It’s really our only option without having to write per-browser code over and over.

    0
  19. 35

    Current “Regions” proposal is somehow messy. Why semantic side of HTML needs to have this empty divs? IT is tag abuse. This presentational information should be expressed in CSS directly. I do not how exactly, but maybe just list of boxes coordinates, or some function/expression. This will allow changing presentation without even touching HTML file, and changing text content without touching CSS files (makeing it more reusable).

    I also do not like idea of referencing one id/class from other id/class in CSS. CSS structure should be more flat, than proposed spaghetti code! This is not against, extensions like LESS, SASS, COMPASS, but pure CSS should’nt be mess when parsing by browser, or interpreting this spaghetti (and all problems connected with it, like cyclic references, double references, etc, etc).

    0
  20. 36

    Divya, I don’t think saying that because a feature is now supported in IE10, its OK to use it in production. Look at the spread of IE7/IE8/IE9! and there isn’t really a nice graceful fall-back for this without JavaScript, which in production websites is not acceptable.

    … Ok, watching the end of the video, you do recommend using feature detection.

    0
  21. 37

    Uriah Rittenhouse

    January 2, 2012 12:08 am

    I’m super stoked about the new layout features. Now if we can only get everyone to stop using antiquated browsers (ie, I’m looking at you).

    0
  22. 38

    The columns feature is fantasic: I’ve been wishing for a while that there was a way to make lists automatically move into columns (as opposed to having to put each item into a table cell). I can see plenty of uses for it, especially on a news/blog page.

    0
  23. 39

    Sadly, all the images except two are not displayed. nginx says 404 for each. Smashing Magazine is the best source for new web dechnologies, but if only i could SEE what every new property is producing…

    0
  24. 40

    I think you should have covered the quite impressive -ms-grids properties that Microsoft is trying to get adopted by the Web consortium. These are based on the powerful XAML markup language used for Silverlight and Windows Applications. In fact, it would bring back the “table” features used in the 90′s but with a pure HTML5 compliant code.

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top