Less than a year ago, Trent Walton published Content Choreography in which he lamented at some of the difficulties and limitations of responsive layouts.
At times, it seems as though all of the site architecture & planning goes out the window as content reflows.
You have to admit, an awful lot of responsive designs end up being:
- Squeeze everything into one column
- Push the sidebar(s) to the bottom
*cough* this site does that *cough*
Trent mentioned it may be a more appropriate approach to “interdigitate” content.

That is, to fold bits of content together into that single column in a more thoughtful or useful manner.
A Practical Example: Ad Folding
Consider a layout at a large browser window size. Two columns. Articles in a wide column on the left, advertisements in a narrow column on the right.
At narrower browser window sizes we’ve decided to drop down to a single column. This layout is probably done with floats, the most common layout method still today. Unfortunately that probably means setting both columns to 100% wide and letting their source-order determine which is on top. Meaning: push all the ads to the bottom. Probably not ideal. It likely would be nicer to fold the ads into the content.
But how?
There’s probably a number of ways to do this. With JavaScript, you could measure the window width and shuffle things around in the DOM. That seems heavy to me, but the browser support would be good. I’d rather lean on CSS for this kind of thing. That’s what CSS is (supposed to be) for. The grid layout may hold some possibilities for us, but for this tutorial, let’s use the hot-off-the-presses CSS Regions, a contribution by Adobe.
HTML
<section class="main-content">
<article> ... </article>
<div class="ad-region-1">
<!-- empty, ads flow into here as needed -->
</div>
<article> ... </article>
<div class="ad-region-2">
<!-- empty, ads flow into here as needed -->
</div>
<article> ... </article>
<div class="ad-region-3">
<!-- empty, ads flow into here as needed -->
</div>
</section>
<aside>
<!-- Fallback content in this flow region, probably clone #ad-source -->
</aside>
<!-- Source of flowing content, essentially hidden as an element -->
<div id="ad-source">
<a href="#"><img src="ads/1.jpg"></a>
<a href="#"><img src="ads/2.jpg"></a>
<a href="#"><img src="ads/3.jpg"></a>
<a href="#"><img src="ads/4.png"></a>
</div>
Notice the “content” (our ads) are tucked into a <div>
at the bottom of the page. Once we set up the CSS regions, the element will essentially be hidden and the content inside it will flow into the regions we tell it to.
CSS
We kick it off by telling our content-holding div#ad-source to flow it’s content into a “named flow”:
#ad-source {
-webkit-flow-into: ads;
-ms-flow-into: ads;
}
I’m only using two vendor prefixes here because that’s the only support for now. I’d recommend not using the unprefixed version as this stuff could change in final implementation.
‘ads’ is an arbitrary name that we just made up. It could be anything, like naming a CSS animation.
Now we set up regions in which for that content to flow. First, into the aside, then into the interdigitated divs between the articles.
aside, [class^='ad-region'] {
-webkit-flow-from: ads;
-ms-flow-from: ads;
}
In our case, at wide browser window widths, the aside is large enough to hold them all. At narrower widths, through media queries, we hide the aside, forcing the content to flow into the divs.
[class^='ad-region'] {
display: none;
height: 155px;
width: 100%; /* Weird that this is required */
}
@media (max-width: 800px) {
[class^='ad-region'] {
display: block;
}
[class^='ad-region']:last-child {
height: 300px; /* I wish height auto worked */
}
aside {
display: none;
}
}
Semantics
Soooo yeah, we have some empty elements we’re tossing around here. Not super semantic. I’m not sure what this does for accessibility either. I do know that the DOM doesn’t change around. All the content, despite where it “flows”, is still within the “source” (the element with the flow-into
property).
Here’s the thing though: regions are layout style agnostic. We’re still using floats for layout in this example, but the layout style you use doen’t really matter. Regions paired up with the CSS Grids might be much more powerful and more semantic (I just don’t know).
Browser Support
CSS Regions is shipping in Chrome 16 through 20, then put under the flag “Enable CSS Regions” in 21-22, and now under the flag “Enable experimental WebKit features” in Chrome 23+. It works in Safari 5.2 (available as dev, or WebKit Nightly). Supposedly it works in IE 10, but I couldn’t get it to.
Demo & Download
For your enjoyment:
Please note the browser support above, it’s very limited.
Also note that at some fairly wide browser window widths, the ads in the aside get cut off. I’m leaving it that way to illustrate how regions don’t expand in height naturally, you need to account for that yourself.
Browser Detection
This HTML and CSS as is would be pretty sucky in a browser that didn’t support CSS regions. There would be this chunk of ads at the bottom of the page randomly. Instead I chucked in a bit of JavaScript (based on this) to test for it and apply classes to the html
element reflecting support.
// Generic Testing Function
var supports = (function() {
var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;
return function(prop) {
if (prop in div.style) return true;
prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});
while (len--) {
if (vendors[len] + prop in div.style) {
return true;
}
}
return false;
};
})();
// Test
if ( supports('flowInto') ) {
$("html").addClass('cssregions');
} else {
$("html").addClass('no-cssregions');
}
That was we can do stuff like this to make sure the fallback is OK:
#ad-source {
display: none;
}
.cssregions #ad-source {
display: block;
-webkit-flow-into: ads;
-ms-flow-into: ads;
}
And also, copy the contents of the div#ad-source into the aside, so at least the ads appear there at the widest browser window widths.
- Using the browser bar navigate to chrome://flags
- If you’re running Chrome 21 or Chrome 22, find the “Enable CSS Regions” flag and enable it
- If you’re running Chrome 23 or newer, find the “Enable experimental WebKit features” flag and enable it.
- Restart your browser by clicking the “Relaunch Now” button on the lower left corner.
If you wanted to add this test to Modernizr you’d do:
Modernizr.addTest('regions', Modernizr.testAllProps('flow-into'));
Hopefully they’ll add that as an option in future versions.
Things I Wish Were Better
- I wish you could style content based on what container element it happens to flow into. That might be problematic as a different style in a different container might cause a reflow which pushes it back out of that container causing infinite looping sadness, but maybe there is some kind of solution for that.
- I wish block level elements would remain block level even with the flow-from property. It’s weird you have to set them to width: 100%;
- I wish height: auto; worked on the region with the last bit of flowed content. I understand most flow regions can’t do that because then they would just expand to fit all the content and not continue the flow, but the final region should be able to know what it has left and expand naturally.
- I wish you could
flow-from
andflow-into
the same element. That way one semantic element could be the source and only if it shrinks or goes away do the other regions get filled.
I definitely dislike websites which shove everything into one column.
With desktop layout (on mobile) I can simply scroll sideways to get to page navigation.
With “responsive” zoom is broken and navigation is far far away with only 100%-sized scrolling available.
Please just do nothing for mobile! I like zoom!
I don’t really agree with you there. If zoom is disabled on mobile layouts it means that the designer has fixed the maximum-scale to 1.0 which is naughty for a number of reasons not least accessibility. The only thing it apparently cures is device rotation.
However, my site for example is fully responsive but text and everything else can still be zoomed because I think it’s more important to be accessible than to suit a user rotating their ipad. After all they can quickly zoom-out and it fixes.
I do agree with your point about Navigation however, perhaps a fixed nav bar or anchor link that takes you back to the top might be something to look at. I’m aware that iOS devices do this for you though if you tap the title bar area up top.
This is very timely for me as I’ve been contemplating how I’ll merge two content list columns for an upcoming project.
As you point out, browser support is currently lacking for this method but it’s one to keep an eye on.
The only alternative I can think of currently is altering HTML on the fly with jQuery at different device widths. Specifically, moving the items in two columns into one, and then ordering chronologically. A pure CSS way would be preferable.
Good post!
Hi Chris, like the article. As for screen readers – as the DOM is not being re ordered this is probably a good thing the Ads are at the base?
another solution could be to put the ads in both places (sidebar AND between articles) and show or hide them depending on the window’s width!
That is a rather ingenious workaround.
I agree! Clever idea, but it could be a problem in Googles eyes as it might see your content is covered with ads!
I could be wrong about this, but thats just my feeling.
For google ads, I’m fairly sure you aren’t allowed to “hide” the ads. In the terms and conditions I believe.
I like this solution better, actually. And I wouldn’t worry about Google “seeing a bunch of ads” because the entire containing div doesn’t even show up in the resulting html (I believe). Thus, Google will only see one set of ads.
The biggest problem with ad serving and show/hiding them is the analytics. If tools like Omniture and Analytics are used to track ads, then a hidden ad on a page is a very bad thing. Most tracking software will denote that ad as underperforming, and they are not yet smart enough to differentiate from the hidden ads and the ads that are in view.
Great post Chris! I for one am really excited about the future – wider implementation of this, as pure CSS, would make it a great addition to sites with the two column setup.
great site – it´s cool to check this out. but the content folding not working 100% on my browser, because the images are hidden when page-width is smaller than (maybe) 800px. best regards from germany
I’ve tried addressing this issue earlier and I ended up settling with a combination of float: left and float: right declarations.:
http://jsfiddle.net/GL9sM/3/embedded/result/
The drawback to this method is that a container can only go as far up the page as the top of its preceding sibling.
I like the future possibilities of regions.. but the support just isn’t there. Doesn’t seem like the kind of thing that should be polyfilled as a fallback. Just do it in Javascript in the first place.
For WordPress… I like the idea of adding an ad to the loop.php(or content.php or whatever) and output and article and an ad paired. Then let things float to single column when the width gets to narrow. It’s the “ad on the bottom” solution, but per article. And we can do it now. The two per article could work as well. I think I’m going to try it this weekend with a clients’ theme.. see if he likes it. It’s not ads, but testimonials. I think it could work out nice!
btw.. “interdigitate” is 15 points in Scrabble.
Just expanding on Joe’s idea, but you can re-create your ad folding example using floats and a media query: http://jsfiddle.net/ympKa/embedded/result/
Nice! That’s exactly the html structure I want to edit the “loop” in WordPress to output for me.
Thanks! This solution is what I eventually arrived at: the combination of float: right/left declarations and media queries to snap to a single column layout once a threshold is reached. I’m just not a fan of the gap that’s created in between the ads containers when the first article’s height is more than the first two ads’ height. I haven’t found a fix for that…any thoughts would be appreciated!
WOW.
This is fantastic! Thanks for sharing!
When I shrink my screen, the ads simply disappear. That’s AWESOME!!!!
I wish it was that easy to get rid of ads on tv : )
Nobody wants to shrink their TV though :)
Awesome as usual
WTF?! oO
Chris Coyier, the hero of CSS!
Your Comment Preview is a perfect example of focusing attention on sh*t that doesn’t matter. Sure it’s a neat little trick, but it slows the user’s typing down to a snail’s pace.
In regards to the article…
1.) Most of your viewers are nerds whose screen resolution is large enough to accommodate two columns
2.) Most of your viewers are nerds who have ad block plus running
3.) Most people do not sit there resizing the browser window to see what happens.
Am I missing something here? All three of your points are invalid. The main purpose of this article (as well as almost all of the articles on this site) is to share techniques with other developers to use on their own projects; it’s not tailored specifically for css-tricks.com.
Dear Jimmy, in regards to this article, it’s not for the nerds browsers. :) It’s for we who build for clients who have a variety of screen sizes (not because they resize). We who have clients who don’t block ads…
It’s an experiment at a creative solution for adapting to screen resolutions… along with playing with source order, etc. It’s not a perfect solution (there isn’t one yet) but I for one welcome the experimentation and sharing. Thanks Chris!
(Not sure what happens with your browser with comment preview, but I’m not slowed at all in Chrome.)
Have a nice weekend! :)
Thanks,
I didn’t know about the “flow-into” a div
I don’t understand the upper carat and brackets in “[class^=’ad-region’]”. Can someone explain the notation and how it’s being used?
Select all elements that have a class attribute with
ad-region
as the starting value. That mean:ad-region-1
.ad-region-2
,ad-region-3
,ad-region-wow
.Thank you. Makes sense now; for some reason it just wasn’t sinking in before.
CSS Regions seem the perfect way to break semantics in my eyes.
For this specific example i.e. ads (as they are generally a fixed height), I would suggest interleaving the them in the markup and then using absolute positioning to shift them to the side column when on wider devices.
This is basically the solution I arrived at for a recent project – it worked ok, but can be a bit problematic for sites with numerous/complex templates.
Good article though, love seeing any new ideas on how to tackle this issue.
Speaking from a commercial point of view:
You will find it difficult to justify re-sizing ad’s like that to a client. If you sell a client a 300×250 adblock, it’s got to remain 300 x 250 across all responsive folds/layouts. So trying to sell this zoom option to a business investor is going to require some serious sales skills.
I think leader boards would be the biggest problem. The only solution I see is to swap the entire ad out with a different dimension version at lower resolutions.
_jin
thanks for tutorial :)
Really nice work around.
Peter Avey
I don’t have a huge issue with the placeholder divs with respect to screen readers. You can, of course, inject them with JavaScript, but the W3C states (HTML4 spec; couldn’t find anything in the HTML5 spec):
“We discourage authors from using empty P elements. User agents should ignore empty P elements”
Tags are meant to give context to content. By that logic, I like to think that an empty tag is like a sentence without any words.
I agree with Matthew Balaam.
Anyway, Thanks for this tutorial!!
This is good stuff. And the example works for calls-to-action just as well as for ads.
Ooh, me likey! Works well in Chrome 17.
The ads don’t appear for IE8 and Firefox at all tho.
Very cool! Thanks for those CSS3 Tricks.
Hi – Great article! I’m the Group Product Manager for the Web Platform team at Adobe and I wanted to share a quick update for the things you wish were better with CSS Regions since they’re already in the works :)
-Styling: We have a plan to support this and in fact hope to share an update at the May CSS Face-2-Face Working Group meeting. Keep an eye on our blog (blogs.adobe.com/webplatform) for an update on the implementation and syntax for styling regions.
-block level elements & setting width to 100%: This is actually a bug in the implementation – for blocks in the normal flow, width:auto should compute to 100% for the regular blocks. For blocks that require shrink wrapping, we just converged on an implementation approach for that case. Stay tuned for these fixes to make it in over the next several weeks.
-Setting height:auto: This is also something we are currently working on and will share an update after May’s F2F WG meeting. Again, we’ll post an update on our blog after May. You can read a little bit more about the proposed approach here: http://wiki.csswg.org/spec/css3-regions/auto-height
-flow-from and flow-into the same element: After some discussion internally the engineers confirmed that this should in fact work since the spec and implementation allow for it. Its queued up to tackle in the upcoming weeks.
Great news, thanks for the update.
Fortunately, Chrome updating is so good that we won’t have to worry about older problematic implementations in that.
It’s in Safari 5.2 though which might have a pretty long life cycle unfortunately. Ohhhh well.
I’ll try this out in an upcoming WebDev class. Looks like a great solution.
I wasn’t sure if there could be a legitimate use of CSS regions – all those demos of absolutely positioned containers on images – but this is pretty cool. There’s a good level of abstraction between content and presentation but the empty DOM nodes will make lots of purists shiver – has anyone tested if reflow will work with pseudo-elements?
Yes, yes they can…
Thank you, as always
I just agree with Matthew Balaam. Anyway, Thanks for this tutorial!!
Such a good point. I also imagine that those that have ads on our sites aren’t thrilled about them always getting pushed down to the bottom from their premium top-of-the-sidebar spot as soon as things get narrow, so this is pretty sweet.
Very clever and perfect solution for responsive design. I love CSS Region. Now waiting for the browser support ;D
sorry, but I have a question about implementing both. Say you have a site with a column of news feeds on the right but the news feeds are more than what is in the center page. Well, is there a way to automatically move some of the news feeds under the center page until you keep adding more text to the center page, then it would revert the news feeds back over to the right column? css of course.
Hi, its wonderful infact. But i am having problem integrating it to sections inside Bootstrap Tab. It works for active tab, but couldn’t make it happen after clicking another tab. Any help would be highly welcome!