Content-based grid tracks and embracing flexibility

Something I love about CSS is that it lets us define visual design for unknown content. This is kind of magic. We can even size things based on content, with min-content, max-content and auto. This post is about how that works in CSS Grid Layout, and what usage in real projects would mean.

In Grid Layout, there are many ways to size a column or row (I’ll refer to them as ‘track’ from here). You can be absolute and define tracks in pixels, or even centimeters, which is pretty useful if you’re doing print work. You can use relative units too, for example relative to the root element’s font size (rem), viewport (vw, vh, vmin, vmax), the width of a 0 (ch)… any CSS length size, really. Of course, all of these sizing methods can be mixed in grid definitions. For example, you could make one column flexible, the other absolute and yet another one content-based. In fact, that’s often a sensible thing to do.

Why size at all?

In Grid Layout, you don’t have to size anything. If you don’t define (some) track sizes, their size will be auto, based on the content they need to fit. You could still say which tracks you want with the grid-area syntax, but leave sizing up to the browser. Or you could refrain from defining areas at all, in which case the browser will create tracks for each of your grid items, then size them.

The obvious reason to define some, most or all of your track sizes anyway, is because you have intentions about your lay-out. You want your content area to have a maximum length for better readability, or you want your ad bar to be certain size for business reasons.

Another reason to give some sizes, is that it saves the browser from parsing your content in order to figure out track sizing by itself, the spec notes:

when content-based sizing is used on an item with large amounts of content, the layout engine must traverse all of this content before finding its minimum size, whereas if the author sets an explicit minimum, this is not necessary

This is not an issue with small amounts of content, the spec concurs that that’s trivial, but it is a potential concern if you have lots of grid items or content.

Content versus context

The go-to CSS spec on sizing is CSS Intrinsic & Extrinsic Sizing Module Level 3. It deals with two ways to size: based on context and based on content.

Context-based or extrinsic sizing of an element is sizing based on the container it is in. This is often its parent, or it could be the viewport. The extrinsic size of a block element is the size of that container, minus padding and border. If you set an element to, say, width: 50%, it is said to be extrinsically sized to be half of the container.

Content-based or intrinsic sizing, on the other hand, is sizing based on the element’s content, so it is independent from its context.

Before I continue: one place we already have widespread content-based sizing on the web is in tables. They size based on how much content is in the cells. If you place two tables on the same page, they’ll likely differ in size (like the schedule for day 1 and day 2 on the Fronteers website differ). This happens automagically, unless you start setting explicit sizes.

min-content, max-content and auto

So how do min-content, max-content and auto work? Let’s take the following line of text (from Charles Darwin’s On the origin of species, 24):

Some facts in regard to the colouring of pigeons well deserve consideration.

If it is displayed in a browser using CSS, it will sit in a box. The minimum width of that box in order to fit this content, is the size that fully fits the longest word, so without ‘overflowing’. In this sentence that would be ‘consideration‘. To size this box to that word, CSS lets you use the min-content keyword. If you set width: min-content onto the element that has this text, it will be sized something like this:

Some facts in
regard to the 
colouring of 
pigeons well 

Note that if your box contains more than just words, more things influence min-content, for example largest image or fixed size box.

The maximum width of that box is the width of this entire sentence. Think of the width it would require if white-space: nowrap was applied. To size the box to the maximum that is required for the content, CSS has the max-content keyword.

Keep in mind that min-content and max-content are all about sizing in the inline direction, the one in which words flow, as opposed to the block direction, in which blocks, like paragraphs, flow.

In CSS, we can use the min-content and max-content keywords as sizes for elements that contain content. In Grid Layout specifically, we can use the keywords to size tracks. Say you’re using min-content to size a column, it will be calculated based on the minimum required for content throughout all the rows in that column.

And then there’s auto. This keyword can mean different things throughout CSS (for a more in-depth look, see fantasai’s Defining auto at CSS Day 2015). For example, in block level elements an auto width takes up the full available width, while in inline level elements, it takes up just the space needed for the content. In grid tracks, it behaves similar-ish to inline elements, it will take up the space of the content. One exception is that if there is a grid item inside the track that has a size, that size can make the whole track grow.

Embrace the web’s flexibility

As I said above, I really like content-based sizing, so it bugs me that I don’t see it used a lot in real-world projects. Websites don’t need to look the same in all browsers, right? That theory is convincing, at least in the circles of front-end developers and designers, but clients often expect more sameness across browsers than we’d like. Even within teams, this is common.

Going from websites that look the same in all browsers, what about looking the same with all content? Content-based sizing units are potentially very useful, but will they make sense on production websites? I see two potential hurdles: it could still be hard to incorporate them in our design processes, and they could create purposeful inconsistencies that some may see as mistakes.

Design process

One of the hardest problems in designing for the web is that the designer has to deal with unknowns. Websites have CMSes, so content can change. It’s likely unknown. Users come with all sorts of devices and screens, so canvas size is mostly unknown, too.

CSS does a fantastic job at giving us tools to solve that exact problem. If you want a certain amount of characters in a column, you don’t need to know what the characters are in order to get what you want. Just write what the rule is, and the browser worries about how to apply it to actual content. But even if this is solved in CSS, that doesn’t mean it is solved in the tools we design websites in. I have met with designers who write CSS and design in the browser, but design in software like Sketch is also very common.

If we want to use content-based sizing in designs and use design tools that are not the browser, whoever writes the CSS should demonstrate what the web can do. The CSS person can show how flexibly built websites can work better in different languages, on different devices and for different people. Designers and developers can team up, make demos. Browsers can help too, they are improving design tools to expose what’s happening. Tools like the new flexbox inspector in Firefox Dev Tools can bring design and code closer together.

Is intentional inconsistency ok?

What does it mean if subsequent pages end up having slightly (or wildly) different grids? This may create a confusing or “broken” user experience. I think inconsistencies can be very powerful, because they lead to an ideal space distribution. The track that needs most space, gets most space (in an auto scenario). This is ideal for content, but does it yield the ideal for visual design and user experience? I don’t know, maybe?

Content-based sizing could be most effective in components that exist once on a page, so that there are no inconsistencies. Or in pages that are quite unique, like temporary landing pages and one off sites for conferences, exhibitions and the like.

Wrapping up

With the min-content, max-content and auto keywords, we can size grid tracks based on their content. I think this is very cool. If we manage to embrace as much of the web’s flexibility as we can, we can get the most out of these tools, and let CSS help us with designing for the unknown.

Comments, likes & shares (1)