Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.
The margin-trim
property in CSS removes the additional margin along the edge of a container when the last child element in the container has a margin that bumps right up alongside it.
.element {
margin-trim: block-end;
}
margin-trim
is defined in the CSS Box Model Module Level 4 specification.
Syntax
margin-trim: none | block | inline | [ block-start || inline-start || block-end || inline-end ]
- Initial value:
none
- Applies to: block containers, multi-column containers, flex containers, grid containers, including
::first-letter
and::first-line
- Inherited: no
- Computed value: a set of zero to four keywords indicating which sides to trim
- Animation type: discrete
Values
/* Keyword values */
margin-trim: none;
margin-trim: block;
margin-trim: block-start;
margin-trim: block-end;
margin-trim: inline;
margin-trim: inline-start;
margin-trim: inline-end;
/* Global values */
margin-trim: inherit;
margin-trim: initial;
margin-trim: revert;
margin-trim: revert-layer;
margin-trim: unset;
none
: The container does not trim margins from the last child elements.block
: The container trims margin from the last child elements in theblock-start
andblock-end
directions together.block-start
: The container trims margin from the last child elements in theblock-start
direction.block-end
: The container trims margin from the last child elements in theblock-end
direction.inline
: The container trims margin from child elements in theinline-start
andinline-end
directions together.inline-start
: The container trims margin from the last child elements in theinline-start
direction.inline-end
: The container trims margin from the last child elements in theinline-end
direction.
You’ll notice that the values for margin-trim
align with other types of logical properties, meaning that they set what direction to trim margin based on the HTML dir
attribute or the element’s writing-mode
or direction
in CSS. If you’re new to logical properties all that means is we talk about directions in terms of block and inline. In a typical left-to-right writing mode, like English, “block” refers to the top and bottom of the element, and “inline” is the left and right.

If the dir
or writing-mode
changes to, say, a right-to-left language like Arabic, then the inline directions change so that inline-start
corresponds to the right side and inline-end
is the left side. The same thing would be true if we changed to a vertical direction or writing mode, but in the block direction.

Why we need this property
margin-trim
is designed to solve a super common layout issue. Take the following basic example of an unordered list of items:
See what’s happening there? I’ve added 1rem
worth’s of margin to the bottom (or, more accurately, the block-end
) of each <li>
element. Then I added a background color to the <li>
elements so we can see the spacing between then. Oh, and I drew a border around the container, the <ul>
element, so we can see the margin between the <ul>
and the last <li>
.
Now let’s say we want to display another <ul>
below the first one. Easy peasy.
But notice how the browser automatically adds margin to the <ul>
by default…

block-end
direction by the browser’s default styles.So, now we have double the margin we need! There’s the margin between the last <li>
and the bottom of the <ul>
container, and margin between the two <ul>
elements.
The margin after the last <li>
is unnecessary. We have a few ways to eliminate it…
:last-child
pseudo selector
Use the This is how we’ve done it forever!
li {
margin-block-end: 1rem;
}
li:last-child {
margin-block-end: 0;
}
Nothing wrong with that. But it’s a pain to have to write that just to remove something we didn’t want there in the first place.
:not()
relational pseudo selector
Use the A little fancier, but effectively does the same thing.
li:not(:last-child) {
margin-block-end: 1rem;
}
Use the “Lobotomized Owl”
A bonafide and favorite CSS trick from Heydon Pickering.
ul > * + * {
margin-block-start: 1rem;
}
The Universal Selector, *
, is not only powerful in that it selects all the things, but it makes a nice logo for a site about making website, right? 😉
Placing an adjacent sibling selector (+
) between two universal selectors is basically saying: Yo, anything inside an unordered list that has an element that precedes it… add some margin above it. In the case of our <ul>
example, all <li>
have an element that precedes it — except the first <li>
. And since nothing precedes the first <li>
, it’s skipped and doesn’t get the margin.
It’s a dang good trick. But it’s also pretty nuclear in the sense that it selects everything. It might take additional CSS to override what we don’t want to add margin to. That’s a downside for sure, even though it definitely gets the job done.
margin-trim
instead!
Use It’s an elegant, hack-free way to remove space from whatever edge of the container you want.
ul {
margin-trim: block-end;
}
Mmm. Nothing like solving a decades-long problem with a single declaration.
Browser support
Not a whole lot of support yet, but it was introduced in Safari Technology Preview 162 on January 25, 2023.
More information
- CSS Box Model Module Level 4 Specification
- Spacing The Bottom of Modules (CSS-Tricks)
- The
margin-trim
property (Manuel Matuzović) - How To Adjust the Content, Padding, Border, and Margins of an HTML Element With CSS (DigitalOcean)
Related tricks!
Lobotomized Owls
Spoooooky CSS Selectors
Is There Too Much CSS Now?
CSS Logical Properties and Values
Building Multi-Directional Layouts
Control Layout in a Multi-Directional Website
Related
margin
.element { margin: 50px 2rem; }
margin-block
.element { margin-block: 30px 60px; }
margin-block-end
.element { margin-block-end: 25%; }
margin-block-start
.element { margin-block-start: 25%; }
margin-inline
.element { margin-inline: 60px auto; }
margin-inline-end
.element { margin-inline-end: 3rem; }