CSS layout has never been more powerful than now. The days of float hacks, margin magic, and all their fragile companions are behind us as our layout dreams are finally on the verge of coming true. Need to center an element? Easy peezy. Want a sticky footer? No sweat. What about achieving magazine-esque layouts? Getting there.
“CSS exclusions” is an addition to our layout arsenal that will become another game changer, assisting with whatever complicated layout scenarios we crave. In this article I’ll introduce you to CSS exclusions, and explain how to raise your voice for browser adoption in order to help progress for the future.
Hold on–It Isn’t Ready Yet!
Just like the title says, the spec as of the time of writing hasn’t been fully adopted; IE10+, and Edge 12+ are the current trailblazers. This clearly demonstrates how Microsoft is pushing the web forward by participating and becoming willing to experiment (we have them to thank for the development of CSS Grid if you recall).
There are certainly articles that softly suggest it’s a waste of time, or even a pipe dream, but I’m here to say right now (and going forward) that we as developers help to navigate, and lead browsers down the path of initiative and innovation. Our browsers are better than they’ve ever been, and the community they reside within is just as supportive.
The time to move forward beyond the browser wars is now, and it starts by allowing your voice to be heard through mailing lists, articles, issues trackers and any other outlets where your opinion can be vocalized. I hope my writings on this topic help to spread the word further, and raise awareness that we as a community of web developers would like to see this feature implemented.
What Are CSS Exclusions?
Okay, prepare yourself for some vocabulary. An “exclusion” starts its life by us defining an “exclusion area” that contributes to a containing block’s “wrapping context”. As a result, an exclusion influences the layout of the containing block’s descendants. It defines surrounding areas that inline content can flow around, and can be defined on any CSS block-level element. Exclusions can be considered more powerful than CSS shapes because they’re not limited to floats.
Still keeping up? Let’s try and better understand what the folk at the W3C mean when they say “wrapping context” and “exclusion area”.
Exclusion Area
An exclusion area is a block-level element that isn’t a float, and generates an “exclusion box”. An exclusion element establishes a new block formatting context, and defines how inline content flows around elements. It also extends the contents’ wrapping ability of floats to any block-level element.
When an element becomes an exclusion, inline content will wrap around the exclusion areas, but within their own formatting contexts. If the element is an exclusion, it doesn’t wrap around its own exclusion area.
The order of multiple exclusions is controlled by the z-index property. Exclusions can be positioned using any of the options we currently have at our disposal (relative
, absolute
, static
, fixed
etc.). Keep in mind as well that if you float an element, it cannot become an exclusion.
Wrapping Context
We’ve mentioned “wrapping context” a couple of times so far, and there are plenty of complex definitions to be found online, but what exactly is it? Think of it as being the parent container that holds the inline flow content and exclusion areas.
Wrap-Flow
Exclusions begin with a wrap-flow
property, and when defined with any other value than auto
, this property is kicked into life. There are a handful of values that can be given to it, such as both
, start
, end
, minimum
, maximum
, and clear
that all behave differently with respect to the context.
As you’ll see in the demo above (using the noted browsers that support the property at this time), wrap-flow
helps determine the area that inline-content flows around. This content can flow in a few different ways. Let’s get into each one more specifically:
None
: No exclusion created.auto
: No exclusion is created. Inline flow content interacts with the element as usual.both
: Inline flow content can flow on all sides of the exclusion.start
: Inline flow content can only flow around the start edge of the exclusion area, but the end edge is a no-flow zone.end
: Inline flow content can only flow around the end edge of the exclusion area, but the start edge is a no-flow zone.minimum
: Inline flow content can only flow around the edge with less available space, and leave the other edge empty.maximum
: Inline flow content can only flow around the edge with more available space, and leave the other edge empty.clear
: Nothing flows along the start and end edge of the exclusion along the inline direction.
Wrap-Through
This property controls how the content that’s intended to flow around the exclusion area will behave, and can be controlled in a couple of different ways that I’ll share shortly.
The wrap-through
property can be good to use for situations such as callout text or pull quotes, much like you see accomplished in print layout design.
wrap
: The element inherits its parent node’s wrapping context. Its descendant inline content wraps around exclusions defined outside the element.none
: The element does not inherit its parent node’s wrapping context. Its descendants are only subject to exclusion areas defined inside the element.
Scope and Layers
An exclusion affects the inline flow content descended from the exclusion’s containing block. Exclusions also follow the typical painting order we’re used to by default. Exclusions are applied in reverse to the document order in which they’re defined.
The last exclusion appears on top of all other exclusions, thus it affects the inline flow content of all other preceding exclusions or elements descendant of the same containing block. The z-index
property can be used to change the ordering of positioned exclusion boxes. Statically positioned exclusions are not affected by the z-index property and thus follow the typical painting order.
Feature Query Support
In order to play nice with the rest of the browsers that don’t support CSS Exclusions you can use the CSS feature query otherwise known as @supports
. If you aren’t using a supporting browser you’ll see we’ve used these in the demos so far.
@supports (-ms-wrap-flow: both) { .element {…} }
By including the property -ms-wrap-flow
you’ll be able to scope only to supporting browsers specifically (IE10+ and Edge 12+).
Parting Thoughts
At this time CSS Exclusions won’t work with clip-path
because Edge doesn’t support this property. Saying that, if it was widely supported CSS exclusions would be even more powerful by adopting abstract and oblique shapes as opposed to strictly rectangular boxes. It’s an unfortunate scenario since we can’t test out early implementations to really witness the power of text wrapping with non rectangular objects.
Positioning requirements can also cause issues for any elements outside the exclusion parent to sit beneath or above depending on your z-index
and can potentially become problematic since this is a requirement of CSS Exclusions. The exclusion areas also become non-aware of the browser viewport so they will not react responsively when contracting or expanding the browser. This means any positioned object has the potential to fall off screen depending on its positioning context.
I hope this article encourages you to embrace this property regardless of current downfalls! I also hope it sends a message to browser vendors to become aware of the current limitations, as well as our desire to have this implemented across the board by anyone making a browser. Happy coding everyone!