[Go Make Things] Modern layouts with CSS

Need front-end help but don't need a full-time employee? I now offer subscription front-end engineering. Ship faster and build better systems. Pause or cancel any time.

As I continue to build out my HTML-focused UI library, one of the things I've been deep in-the-weeds on recently is modern approaches to layout.

Today, I wanted to explore that a bit more. Let's dig in!

Go with the flow

The most common layout on nearly every website is the flow or the stack: a vertical stack of headings, paragraphs, and more as part of an article or document.

<h1>This is the stack</h1>  <p>You have a collection of items.</p>  <p>Each one stacked one on top of the other.</p>    <h2>Sometimes there are subheadings</h2>  <p>With more content.</p>

Generally, the headings, paragraphs, images, tables, and so on inside the stack have spacing after them.

There are so many ways to achieve this, and a lot of debate over "the right way."

The old-school way

For much of my career, I've achieved the stack by adding margin-bottom to various elements.

p {  	margin-bottom: 1.5rem;  }    h1, h2, h3, h4, h5, h6 {  	margin-bottom: 1.5rem;  }

For headings, I might often add margin or padding above them to give them more white space to indicate the start of a new section.

I'll use em for that, so that bigger elements have more spacing.

h2, h3, h4, h5, h6 {  	margin-top: 1.5em;  }

If you wanted to adjust the amount of space between two items, you would use utility classes to adjust the margin or padding on just that element.

.no-margin-bottom {  	margin-bottom: 0;  }    .margin-bottom-small {  	margin-bottom: 0.25em;  }
<p>...</p>  <p>...</p>    <h2 class="margin-bottom-small">Some sort of hero heading</h2>  <p>And a subheading.</p>    <p>...</p>  <p>...</p>

This absolutely works, but a few years back, a more modern approach emerged.

The lobotomized owl

As far as I know, Heydon Pickering introduced the technique folks refer to as the lobotomized owl.

Rather than assigning spacing on individual elements, you define it on a parent element that creates spacing relationships between it's direct child elements.

.stack > * + * {  	margin-top: 1.5em;  }

The * + * applies the margin only to elements that have a sibling before them. The > ensures that only direct child elements are affected and prevents weird nesting issues.

Using relative em units means that headings automatically get more spacing than paragraphs.

If you want to have more or less spacing between elements, you can create variants, like this…

.stack > * + * {  	margin-top: 1.5em;  }    .stack-small > * + * {  	margin-top: 0.5em;  }

And then nested stacks inside each other, like this…

<div class="stack">  	<p>...</p>  	<p>...</p>    	<div class="stack-small">  		<h2>Some sort of hero heading</h2>  		<p>And a subheading.</p>  	</div>    	<p>...</p>  	<p>...</p>  </div>

This is a mental shift, but I like much cleaner it keeps the various elements in your HTML.

Flexbox

An even more modern way to approach the .stack layout is with flexbox.

.stack {  	display: flex;  	flex-direction: column;  	gap: 1.5em;  }

In my opinion, the CSS is cleaner with this approach.

However, because the spacing is controlled by gap, headings no longer receive more space than other elements automatically. To account for this, you need to add padding-top to them.

.stack > :where(h2, h3, h4, h5, h6) {  	padding-top: 1em;  }

So, why would you choose this approach over the lobotomized owl? If anything, it seems like more work, not less.

Layout variety and gap

CSS Grid and Flexbox make it a lot easier to do a lot of previously really complicated layouts.

For example, let's say you want two items side-by-side, one pushed all the way to the left, and the other pushed all the way to the right. Think a navbar with a logo and nav menu, for example.

<div class="split">  	<a href="/">Logo</a>  	<nav>...</nav>  </div>

You can achieve that with display: flex and justify-content: space-between.

.split {      display: flex;      justify-content: space-between;      gap: 1em;  }

Or let's imagine you want a bunch of items in a group, all of them different sizes, with an equal amount of space between all of them. If there are too many for one row, you want them to automatically wrap.

Again, display: flex, this time with flex-wrap.

.cluster {      display: flex;      flex-wrap: wrap;      gap: 1em;  }

But what does this have to do with the .stack?

Utility classes for the .gap

Once you start using Flexbox and CSS Grid for a few things, it makes a lot of sense to add utility classes that can modify things like the gap on all of them.

Rather than a .stack-small class, which serves just one purpose…

.stack-small {  	display: flex;  	flex-direction: column;  	gap: 0.25em;  }

You can have a .gap-s class, which can adjust the gap on .stack, .split, .cluster, and more!

.gap-s {  	gap: 0.25em;  }
<div class="stack">  	<p>...</p>  	<p>...</p>    	<div class="stack gap-s">  		<h2>Some sort of hero heading</h2>  		<p>And a subheading.</p>  	</div>    	<p>...</p>  	<p>...</p>  </div>

What do you think?

I've been really struggling with whether to use the lobotomized owl or flex in my UI library project.

I'm leaning towards Flexbox for the utility class flexibility, but I'm not sold on it just yet.

If you have a strong opinion either way, I'd love to hear it!

Learn more about subscription front-end engineering. Ship faster and build better systems.

Cheers,
Chris

Want to share this with others or read it later? View it in a browser.

Share :

Facebook Twitter Google+ Lintasme

Related Post:

0 Komentar untuk "[Go Make Things] Modern layouts with CSS"

Back To Top