Welcome to the Layouts of the Future!

Historically, layout on the web has been quite difficult. Developers have relied on third-party tools, like Bootstrap, and media queries based on “average” device sizes. Today, however, the web is available on an increasingly large range of devices – everything from your watch to your fridge! We are reaching the limits of what these tools can handle.

The good news is that CSS has you covered now! Modern CSS contains a number of properties that support responsive designs natively. We’re going to have a look at CSS columns, flexbox and grid. We’ll take a quick look into how each works individually. And then we’ll learn how we can combine them to create truly flexible layouts, that work across a huge range of devices, without relying on device-based breakpoints.

Welcome to the Layouts of the Future!

Erin Zimmer, Senior developer Cogent

We’re probably all familliar with the “CSS is awesome” meme, where the text breaks out of the box – and this is supposed to suggest CSS is not awesome. In fact the layout is what actually makes sense in reality.

There are a bunch of frameworks out there, weirdly obsessed with single-letter logos, but still…

Frameworks like Bootstrap enable a lot of powerful layouts without a lot of custom code. Or if you want to roll your own, it’s still only a few lines of code to get a basic responsive design working.

But there are some problems with the assumption that all responsive design should be attached to breakpoints.

The web is continuous – people don’t all use windows sized to your breakpoints. Many websites look surprisingly clunky if you happen to open your browser at a size that’s awkwardly placed between breakpoints.

You can alleviate this by setting breakpoints aligned to your design, rather than trying to aligning to screen size.

But when we write our CSS we don’t have all the information, such as how big the content will be; or how big the container will be. If the container was always the viewport, media queries would be perfect.

Design systems face this problem a lot, where a component is designed without knowing the context it will be used in.

So what can we do instead? Erin’s suggestion is let the browser work it out. The web’s flexibility is a feature, not a bug. Don’t try to place every pixel perfectly, give the browser boundaries and let it figure out what to do.

This is really what CSS is doing anyway – making suggestions to the user agent.

As an example, let’s look at making some responsive columns – the real newspaper-style column isn’t very popular on the web as it was really hard to do for years.

But now we have CSS columns which can do it in a single line of code:

.columns {
  columns: 3 200px;

Why is this just a suggestion? Well if the property isn’t supported, the content will behave as a normal container. We can suggest a maximum for the number of columns and how wide we want them, but we don’t know what will fit.

So the browser takes info and finds a layout that fits the suggestions within the constraints at the time of rendering.

Then you can combine columns with flexbox. Text is set with columns, while an accompanying image is set to the side or below. The browser then goes ahead and makes it work in whatever combination makes sense.

A more common use case is things that grow and shrink. Two buttons side by side is a really common pattern; as is wanting the button to stretch wide if the parent is wide; or stack up if the container is narrow.

This seems hard but you can make it work using flexbox and a minimum width on the buttons. The demo uses a new flexbox property gap which sets space between elements – browser support can’t come soon enough!

This works really well but you need to be judicious with your boundaries. By setting too many you can create unwanted effects.

(Demo of a set of buttons, where four were normal sized and the fifth full width; because they’d been given a boundary of 24% min-width. It works better without that boundary.)

Next is an issue that is near and dear to all web developers – how to align things.

  • Flexbox is good for alignment in one dimension (eg. vertical)
  • Grid is better for alignment in two dimensions (ie. both vertical and horizontal)

(Two minute crash course in Grid)

There are a couple of ways to make Grid responsive.

You can make Grid responsive to its own content using width auto. Auto sets the boundary that the column needs to be at least as wide as its content; and the guideline is that it should stretch to fill available space.

Or, you can dynamically change the number of columns. This may not be immediately obvious so let’s break down the code.

grid.auto-columns { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); grid-template-rows: auto; gap: 20px; width: 100%; }
  • repeat(auto-fit – fit as many columns you can in the space available
  • minmax(300px, 1fr) each col needs to be at least 300px wide; and stretch to fill available space

The big difference in this option is that the columns will all be the same width and not driven by the width of the content. So it’s better when you know or control the size of the content.

The last example combines everything… columns reflow to fit content into the available space; the whole page reflows to adapt to viewport size.

Finishing with a quote from Jeremy Keith’s Resiliant Web Design:

Relinquishing control does not mean relinquishing quality. Quite the opposite. In acknowledging the many unknowns involved in designing for the web, designers can craft in a resilient flexible way that is true to the medium.

A final note that browser support is better than you expect; although you will need some postprocessing for IE11.

@ErinJZimmer | slides: Welcome to the Layouts of the Future!