CSS Regions are now enabled by default in a widely used browser - Safari on iOS 7. This makes it easier for developers to experiment and use the feature in their projects.
Perhaps this is a good time to share some of the lessons we learned at Adobe while using CSS Regions in demos. Take this article as a recommendation of good practices, not by any means a comprehensive list. CSS Regions is still an evolving feature.
One of the first use cases for CSS Regions is to enable traditional print layout for digital publishing. Columns are very common in print. Regions can be used to achieve complex column-like layouts where content flows from one box to the other. Take care to use columns sensibly, as they may degrade the reading experience if used incorrectly.
Avoid using a row of columns which are taller than the viewport's height. This makes the user have to scroll down to finish reading one column, then scroll back up to continue reading the next one.
Opt for shorter columns of text which can fit within the height of one screen size. The vh
(relative viewport height) CSS units are very helpful in this situation, as demonstrated in the demo for National Geographic - Orphan Elephants.
CSS Regions is a cool and useful new feature, but it will take some time before all major browsers support it. Wanting to use the latest CSS features is not a valid excuse to keep people from reading and using the content.
Browsers ignore CSS properties that they don't support. Use this to your advantage! Build a good layout for your content that everyone can use regardless of browser or device. For people using capable browsers, you may enhance the layout with CSS Regions by flowing content between boxes or moving it around to different positions on the page in a responsive layout.
Take care that the containers used as regions do not interfere with the layout when CSS Regions are not supported.
The Modernirz feature detection library has an optional plugin that will check for CSS Regions. You may configure a custom build of Modernizr that includes it, or download it separately from GitHub. After Modernizr with the plugin runs on a page, if the feature is supported, the <html>
element will get a class name of regions
. Conversely, the class name will be no-regions
for browsers without support. Use this in your CSS to swap between different layouts.
/* assume no CSS Regions, avoid breaking layout */ .region{ display: none; } /* 'regions' class is applied by Modernizr */ html.regions .content{ flow-into: myFlow; } html.regions .region{ flow-from: myFlow; display: block; }
Regions are only visual containers for content. When content flows into a region it visually replaces anything that was in the region. The structure of the DOM doesn't change. This is a good thing because it keeps the content's styling consistent and maintains any behavior attached with JavaScript.
However, any pointer events such as mouse clicks or touches attached to the regions themselves can become unaccessible. This happens because the content in the region captures the inital event, which is the expected behavior. Since, in most cases, the content isn't a descendant of the region in the DOM, the event will no bubble up for a region to react to it.
Most use cases for CSS Regions will not encounter this problem. For those few where event 'pseudo-bubbling' is required there is a workaround.
Setting the CSS property pointer-events
to none
on the content will cause it to ignore pointer events and defer them to whatever other elements are at that position - the region in this case.
.content{ flow-into: myFlow; pointer-events: none; // prevent events from triggering } .region{ flow-from: myFlow; }
This is a sledgehammer approach. Clicks, touches and text selection will no longer work on the content.
There is a more sensible JavaScript solution where a developer can turn off the pointer events on the content just for a moment to check if there's a region at that location, then turn them back on so there's no impact on the user experience. This is more suited for complex applications such as CSS Regions text editors.
var content = document.querySelector('.content') var region = document.querySelector('.region') content.addEventListener('click', function(e){ // memorize the current 'pointer-events' property value var memo = e.target.style.pointerEvents // prevent the content from reacting to pointer events content.style.pointerEvents = 'none' // attempt to get the other element at the same event coordiantes el = document.elementFromPoint(e.x, e.y) if (el == region){ console.log('Clicked the region: ', el) } // restore the original 'pointer-events' property value content.style.pointerEvents = memo })
This is a simple presentation of the solution. It can be adapted to cover deeper element nesting and complex region chains.
While this is a practical workaround at the moment, work is already underway to find a better solution and add it to the next level of the CSS Regions W3C specification.
This a short list of approaches to working with CSS Regions that we found to make sense for real-world projects. Hopefully, this information will help put you in the right mindset.
CSS Regions is a novel implementation that touches a lot of the existing CSS features. It interacts with them in interesting and sometimes unexpected ways. A lot of options for building responsive layouts have now become available.
We'd love to get your feedback and ideas about how you use CSS Regions in your demos or everyday projects. Share your good practices with us on Twitter @AdobeWeb or through the comments form.
A couple of notes:
vh
on iOS, especially when coupled with auto-height regions. I'm not sure it's ok to recommend it to people only to see it crumblingAlso, a minor visual nit: use a better looking x / v for the checkmarks on the first figure