margin-trim as a best practice?

It’s not every day there is a new “best practice” for CSS, since it’s such a huge, ubiquitous, and highly used language. But here’s one, maybe?

If you add padding in the main flow direction of an element, adding margin-trim in that same direction.

If you have both padding and margin in the same direction, the amount of space in that direction is their combined total. My thinking is that it’s quite rare that the space you actually want is that combined total. It’s probably just the padding. The margin is likely there for child elements pushing each other away.

Doing this looks like:

.card {
  padding: 1rem;
  margin-trim: block;
}

.nav {
  display: flex;
  padding: 0.25rem 1rem;
  margin-trim: inline;
}Code language: CSS (css)

Jen Simmons’ WWDC video this year makes this super clear:

In the above example, because there is padding in the block direction, margin-trim is also used in that direction. And there are elements with padding in those directions, so it’s cut off. Nice. No more ughgk this again I guess I’ll try to fight it with some kind of :last-child/:first-child margin-removing thing that I hope is specific enough to work. This solves the extra space problem from the parent level.

I couldn’t see a keyword value that would margin-trim in all directions 🤷‍♀️. But I guess I can kinda the reasoning, like in that example above if the margin was trimmed in the inline-end direction only on the last paragraph it would be like… why? It wouldn’t be doing the same useful thing. It would have to be more heuristically built, trimming margin from any element that butts against the inline-end, but I don’t think that’s how it works.

If margin-trim had come out before flexbox and grid layout, it would have been huge. It’s such a little annoyance that we need to select the last element somehow and remove the flow-direction margin, lest be left with more space than we want. Both flexbox and grid have gap, which is beloved for this very reason. I just want to space things out between elements.

This makes me wonder if there is a generic way to express this idea. Perhaps even something that you could chuck in a reset stylesheet? The most modern thing I can think of would be a (range-style?) style query that checks if it needs to apply margin-trim based on the existence of padding in that direction:

/* not real, as I write */

@container style(padding-inline > 0) {
  :scope {
    margin-trim: inline;
  }
}
@container style(padding-block > 0) {
  :scope {
    margin-trim: block;
  }
}Code language: CSS (css)

I’m not sure that will ever work though, because:

  1. I think style queries need a container, and you can’t style the container you query. So the :scope thing above is just wishful thinking.
  2. At the moment, I think style queries only work with --custom-properties.
  3. You kinda wanna test the actual calculated value for this. So if an element, for any reason, ended up with padding-inline-end, you’d want to apply margin-inline-end. But I’m not sure style queries do calculated values, only declared… right?
  4. I also don’t even know if range values (like the “greater than zero” fake syntax above) will ever be real. That seems smart as perhaps you don’t want to trim margins if the padding is “removed” via a zero value, but again not sure if that will ever be possible.

🤘

CodePen

I work on CodePen! I'd highly suggest you have a PRO account on CodePen, as it buys you private Pens, media uploads, realtime collaboration, and more.

Get CodePen PRO

3 responses to “margin-trim as a best practice?”

  1. Bob says:

    This is great but it does feel like a late addition to the game. I’ve been using the lobotomized owl * + * for so long now and it works great for the most part.

    References:
    * https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/
    * Your original thoughts: https://css-tricks.com/spacing-the-bottom-of-modules/
    * Your follow-up: https://css-tricks.com/lobotomized-owls/

  2. Alec says:

    For those of using the stack from Every Layout (https://every-layout.dev/layouts/stack/) I think this will be helpful. Here’s my current stack implementation: https://codepen.io/alecgregory/pen/oNaQxgP. And here’s a version utilizing margin-trim: https://codepen.io/alecgregory/pen/PoVezyN

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top ⬆️