New CSS Property margin-trim
December 11, 2023
One of the most annoying things to deal with in CSS is margins. They have weird interactions with collapsing and more often than not you end up with extra spacing where you don’t want it. This becomes an even larger pain when moving to a component based design system since now you need to ensure your components all work well with each other without leaking styles outside themselves.
The new margin-trim
property helps solve part of this problem by making it very easy to remove extra margin from the children of an element.
The Problem
Let’s say we have a simple card with a list of children inside it.
<div class="card">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
<div class="child">Child 3</div>
</div>
.card {
background-color: var(--accent-color);
padding: 1rem;
}
.child {
margin-bottom: 2rem;
}
This will result in the following:
As you can see, the bottom margin of the last child is forcing the card to have extra
space on the bottom which makes the card taller than it should be. This is relatively
easy to fix if we change our CSS by using the :last-child
selector to remove the
margin from the last child.
.child {
margin-bottom: 1rem;
}
.child:last-child {
margin-bottom: 0;
}
This will result in the following:
This works, but it is not ideal since this code does not work well in a component based system. Our child component needs to know that the parent component wants to remove margin from it. This is not ideal since it means that the child component is now coupled to the parent component. We could instead write our CSS like this to make it so the parent component handles everything.
.card {
background-color: var(--accent-color);
padding: 1rem;
}
.card > :last-child {
margin-bottom: 0;
}
This still isn’t ideal, though, since now we are selecting elements outside the parent component which breaks the encapsulation of the component. This is where the margin-trim
property comes in.
margin-trim
Solution
The margin-trim
property is a very simple property that allows you to specify which edges of an element should be trimmed and it will remove all excess spacing from those edges. This means that we can now write our CSS like this:
.card {
background-color: var(--accent-color);
padding: 1rem;
margin-trim: block-end;
}
.child {
margin-bottom: 1rem;
}
This will result in the following:
As you can see, the margin-trim
property removed the extra margin from the bottom of the card without us needing to write any extra CSS.
This property can be used for any of the 4 directions block-start
, block-end
, inline-start
, and inline-end
. It can also be used with just block
or inline
to remove margin from both the start and end of the specified axis.
.card {
/* All these assume the direction is left to right, top to bottom */
margin-trim: block; /* Removes from top and bottom */
margin-trim: inline; /* Removes from left and right */
margin-trim: block-start block-end; /* Removes from top and bottom */
margin-trim: inline-start; /* Removes from left */
}
By using margin-trim
we are able to keep all our CSS inside the component without the need for any complex children selectors or :last-child
selectors which makes it much easier to maintain and refactor our code.
Browser Support
Unfortunately, Safari is the only browser that supports this feature which leads to just 14% support across all browsers at the time of writing this article. Hopefully, in the coming months/years this number will increase as more browsers support this useful property.
Conclusion
The margin-trim
property is a very simple, but incredibly useful property that makes it easy to remove extra margin from the children of an element. This makes it easier to work with components in a component based design system since you no longer need to worry about parent/child components leaking styles outside themselves.