Skip to main content
Dublin Library

The Publishing Project

Use margin-trim to trim the bottom margin on the last child

 

When writing CSS one of the most annoying and repeating tasks is having to customize the styles for the last element in a list or other repetitive components.

I've lost track of how many times I've had to tweak code like the code shown below where we override the margin-block-end or margin-bottom property on the last child element to remove the padding or margin.

.child {
  margin-bottom: 2rem;
  border: 1px solid red;
  width: 50vw;
  padding-block: 1rem;
  padding-inline-start: 2rem;
}

.child:last-child {
  margin-block-end: 0;
}

It's tedious and, potentially, error-prone. I may forget to add it or the last-child element may have other attributes that conflict with the necessary margin removal.

That's where margin-trim comes in.

Using this property allows the container to trim the margins of its children where they adjoin the container's edges. Note that margin-trim uses logical property names for the possible attribute values; if we change the writing direction then the area that will get compressed when we use start or end attributes will change.

To make this work we place code in two @supports blocks. The first one covers when the browser doesn't support margin-trim.

If this is the case we reveal our warning message that the browser doesn't support margin-trim and we set the margin-block-end property on the last child element.

@supports not (margin-trim: block-end) {
  .warning {
    display: block;
  }

  .child:last-child {
    margin-block-end: 0;
  }
}

The second feature query will match if the browser supports margin-trim. If the browser supports margin-trim, we add the attribute to the card element.

This will have the same effect on browsers that support margin-trim with less code and easier to read.

@supports (margin-trim: block-end) {
  .card {
    margin-trim: block-end;
  }
}

The possible values for margin-trim are:

none
The container will not trim the children's margins
block
Removes the block children's margins in the block axis without affecting the margins provided to the container
block-start
Removes the margin of the first block child with the container's edge to zero
block-end
Removes the margin of the last child block with the container's edge to zero.
inline
Removes the block children's margins in the inline axis without affecting the inline margins provided to the container
inline-start
Removes the margin between the container's edge and the first inline child
inline-end
Removes the margin between the container's edge and the last inline child

Edit on Github