Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

Diving Into CSS Regions

by

This tutorial will cover the basics of CSS regions, which allow us to flow content within various sections of the page. Confused? You probably are; read on!



CSS Region Support

At the time of this writing, the CSS Regions specification is a working draft and things may change! Techniques mentioned in this tutorial might change in implementation. The aim of this tutorial is to give a basic understanding of CSS Regions and what might be coming to a browser near you.

Check out caniuse.com for a list of browsers which have some support for CSS Regions. This tutorial will only use webkit/non-vendor-prefixed examples for simplicities sake.

If you find the demo is not working for you it may be because CSS Regions needs enabling, here are instructions for Chrome (should work for Chrome, Chrome Canary & Chromium )

  1. Navigate to chrome://flags/ (or about:flags)
  2. Find "Enable CSS Regions" and enable it.
  3. Restart your browser and verify that the demo is working.
  4. Screenshot of the Chrome Flags page

A Simple Example

Demonstrating CSS Regions in a simple manner actually requires very little code!

To get into the flow of things lets go through a quick example of how to use CSS Regions.

First, we need some dummy text which is contained within the paragraph tag, below that you'll notice two empty divs each with a class of "regions". Using CSS Regions we will allow our "example-text" to flow into the region divs.


<p class="example-text">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."</p>

<div class="regions"></div>
<div class="regions"></div>
.example-text {
	-webkit-flow-into: example-text-flow;
	padding: 0;
	margin: 0;
}
  
.regions {
	-webkit-flow-from: example-text-flow;
	border: 1px solid black;
	padding: 2px;
	margin: 5px;
	width: 200px;
	height: 50px;
}

If you try viewing the code above in a Webkit browser that supports CSS Regions, you should see something like:

Basic example of CSS Regions

All styling (apart from -webkit-flow-from) which has been applied on the "regions" class is only there to make it evident where the regions are, the two lines of CSS that we really care about are:

-webkit-flow-into: example-text-flow;

-webkit-flow-from: example-text-flow;

These will be discussed in more detail below


The flow-into Property and Named Flows

The flow-into property accepts an identifier as its value, once we apply the flow-into property onto an element and pass it an identifier, that element then becomes part of a "named flow". As soon as an element becomes part of a named flow it is taken out of its usual flow - this essentially means the element will not be rendered on the page, for example:

<p class="example-text">I will not be rendered on the page</p>
.example-text {
	-webkit-flow-into: example-text-flow;
}

There are some exceptions to this however, if the flow-into property is given the value 'none' the element will not be part of a named flow and thus be subject to usual rendering on the page. As you might have guessed, another case where an element which is part of named flow will be displayed is when it has a valid region associated with it.

Multiple elements can be put into the same named flow:

#example-1 {
	-webkit-flow-into: my-named-flow;
}

#example-2 {
	-webkit-flow-into: my-named-flow;
}

If there is an associated region for "my-named-flow", an attempt will be made to flow the two elements (#example-1 & #example-2) into their corresponding region chain.

It's not just simple bits of text which can be put into a named flow, we can put images too! Having the ability to put all sorts of HTML elements into named flows is a powerful thing. For example, let's say we had two individual lists but from a presentation point of view we wanted to show them together. One way to go about this is to use CSS selectors to target only the portions we need and put them into a named flow, example (extract of code):

<article id="css3">
  <header><h4>CSS3</h4></header>
  <ul>
    <li>Media Queries</li>
    <li>Text Shadows</li>
    <li>3D Transforms</li>
  </ul>
</article>
  
<article id="html5">
  <header><h4>HTML5</h4></header>
  <ul>
    <li>Canvas</li>
    <li>Drag-and-drop</li>
    <li>Web Storage</li>
  </ul>
</article>  

  
<div id="buzzwords-region"></div>
/* Only put the list within the article into a named flow */
#css3 > ul {
-webkit-flow-into: buzzwords-flow;
}

#html5 > ul {
-webkit-flow-into: buzzwords-flow;
}  

#buzzwords-region {
-webkit-flow-from: buzzwords-flow;
border: 1px solid green;
}
Result of combining two lists using CSS Regions

(Demo of the above.) If you look at the source code you'll notice that our HTML5 & CSS3 lists have been merged into a new buzzword list. Take note of how the headers of those lists were not targeted in the CSS selectors and thus are not part of any named flow, they are therefore still rendered on the page and are not contained within a region.


The flow-from Property

The flow-from property is able to take a container, for example an empty div and turn it into a region. For it to turn into a valid region it must have an associated named flow. As discussed, named flows are created by using the flow-into property and then using an identifier as its value.

<div class="region"></div>
.region {
	-webkit-flow-from: my-named-flow;
}

Similar to flow-into property, we can assign the value of 'none' to the flow-from property, this makes the corresponding element nothing more than a container e.g. it will not act as a region.

When applying the flow-from property on an element, it will not have a height or width which is why you'll need to set these in order to view the contents of the region. Regions may only act as region chains for a single named flow, so multiple elements may flow-into a single named flow however a region can only flow-from a single named flow. A region will maintain the styles of its source element; this means if the source element has the colour value of red the text will continue to appear red when rendered as part of a region.

The CSS Region specification has been considering using @region rules for specific region styling.

"An @region rule contains style declarations specific to particular regions."

This could allow for CSS syntax (similar to that of media queries) such as:

/* A regular style on all paragraph tags */
p {
	font-weight: normal;
}

@region #my-region {
	/* When text from the p element is flowing into #my-region, use the styling below */
	p {
		font-weight: bold;
	}
}

Being able to do this would allow region specific styling to be applied on the source, currently, setting for example "font-weight: bold" on a region will not cause content displayed within it to be bold - the styling must be applied on the source element.


JavaScript API

At the time of this writing, there is some support in Webkit-based browsers to access CSS Region information through JavaScript. Using JavaScript, we can pick out a flow according to its identifier and find out what regions are associated with it. We can even find out the status of a particular region, there may be a use case where empty regions need specific handling, using JavaScript we can accomplish this.

Accessing a flow by name

A named flow can be accessed in JavaScript using document.getFlowByName('identifier') (You can try these in the developer console in the demo.)

var flow = document.webkitGetFlowByName('example-1-text');
The return object of getFlowByName

The returned object is something called a WebkitNamedFlow. flow.contentNodes will contain an array of HTML Elements which are being used as the source for the flow being accessed.

Discovering which regions belong to which content node

The ability to detect which content belongs to which regions can prove useful in various situations.

var flow = document.webkitGetFlowByName('example-4-text');
var main_content = document.querySelector('#example-4 .main_content');
flow.getRegionsByContentNode(main_content);

In the code above, we first find our flow on the page using the flow name, then using the Selectors API we access a piece of content on the page and pass it as an argument to getRegionsByContentNode(), this returns a list of elements which are being used as regions for that particular piece of content.

Finding out whether or not a piece of content fits inside a region

We can very quickly determine the status of a region in regards to how content inside it fits.

//This is not a very efficient selector, see https://developers.google.com/speed/docs/best-practices/rendering#UseEfficientCSSSelectors
var region7 = document.querySelector('#example-4 .regions > div:nth-child(7) ');
region7.webkitRegionOverflow //"fit"

element.regionOverflow will return different values depending on how it's handling the source content. There are four possible values: 'overflow', 'fit', 'empty' and 'undefined'

  • overflow: The content does not fit in the specified region and will overflow to the next region if it's available
  • fit: The region has successfully contained the content and no overflow is necessary.
  • empty: There is no content inside of the selected region and therefore it is empty (as will normally be the case with a region whose previous region returns 'fit' for regionOverflow)
  • undefined: The element is not a valid region.

You can try this out using developer tools in Chrome, on the demo page, right click on one of the blue boxes (a region) and select 'Inspect Element'. You may find the source element is selected rather than the region div. Try to find the nearest div with the class of 'regions' and select one of the child divs (they should appear empty). At this point you can hit the Escape key on your keyboard which should bring up the console; now as a handy shortcut you can type $0 into the console to access the selected element. Now try typing:

$0.webkitRegionOverflow //'overflow', 'fit', 'empty' or'undefined'
Using the dollar zero shortcut in developer console to access the selected element

A Few Notes and Opinions

Hello! Thanks for reading this tutorial, here are some extra bits of information you may be interested in.

  • Browser implementation for CSS Regions isn't great right now and even when it does improve browser implementation may vary. For example Internet Explorer only allows flow-into to be set on an iframe.
  • CSS Regions can let developers and designers offer a more improved experience on the web, especially on mobile/tablet devices.
  • Modernizr can detect support for CSS Regions, it's what the demo uses.
  • Adobe have taken a great initiative on CSS Regions. Be sure to check out their demos!
  • Chris Coyier of CSS Tricks has come up with a cool and practical use for CSS Regions.
Advertisement