DEV Community

Cover image for Don't use margin in CSS

Don't use margin in CSS

Antonio Moruno Gracia on October 10, 2023

Nowadays, CSS has a wide range of tools and properties that allow designs that, until a few years ago, seemed impossible to implement. Many develop...
Collapse
 
madsstoumann profile image
Mads Stoumann

Maybe it’s worth mentioning that gap is short for column-gap and row-gap. Use them individually for finer control. A quick, row-based grid can be as simple as:

.grid {
  display: grid;
  row-gap: 1em;
  &>* { margin-block: unset; }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
theklr profile image
Kevin R

In addition, gap is no longer exclusive to grid, can also be used for flexbox as well

Collapse
 
damian_cyrus profile image
Damian Cyrus

Flexbox supports gap, too. It is not too complex and works most of the time.

CSS Grid is better for complex layouts. But that doesn't mean you could use it for simple layouts, too.

Margin: auto; works fine when the container has a limited width. This can be archived now with almost the same lines of CSS code with grid. And then you get that additional superpower layout tool.

About gap: you can use different gaps for the children. There are now less reasons to use margin for layouts.

Collapse
 
lebbe profile image
Lars-Erik Bruce

It's a good post, and something for consideration indeed. It somehow goes against my intuition in, for instance, the flow of paragraphs in a document, though. It feels natural to define distance between paragraphs with margin.

You claim that "The responsibility lies within the parent block." but I fail to see a good justification for this. Why should the responsibility rest on the parent element? I guess this is a rule you have made following practical observations?

Collapse
 
lixeletto profile image
Camilo Micheletto

If you just apply margins to child elements, you'll end up with an extra margin in the last element. To avoid that, you may use the lobotomized owl selector to select only those that have siblings, eg: * + * or use the :not selector, eg: .element > *:not(:last-child), or even worse - redefine the last element's margin with an class or !important further in the code.

This seems like added complexity to me, if you want to achieve a similar result to gap.

Collapse
 
lebbe profile image
Lars-Erik Bruce

I agree that if what you want to achieve is gap, you should just use gap. :)

Collapse
 
moruno21 profile image
Antonio Moruno Gracia

If you were to replace a paragraph with a new one or another, the margin separating it from the rest should still be there, right?

If that's the case, the margin will remain independent of the paragraphs it separates, so, from my point of view, it should be the parent that separates them.

The paragraph spacing exists due to the layout that displays them (the parent).

Collapse
 
lixeletto profile image
Camilo Micheletto

About the negative margin, Bootstrap has a use case!

In the row element, Bootstrap uses negative margins to adjust the outer elements additional horizontal spacing due to the .container class horizontal padding.

Collapse
 
koga73 profile image
AJ

For your sibling example I would argue that grid is overkill and margin is a better approach. Especially if you need different spacing between the siblings, margin collapse is a benefit.

Collapse
 
andrew_roazen profile image
Andrew Roazen

grid is a wonderful thing for actually creating grid layouts, and in that context the above solution makes sense. But for simpler/smaller content margin-collapse is a more compact and saner approach, especially since both grid layouts and margin-collapse end up calling the same 'first/last element' check function in the renderer. This isn't like deprecating float: because it introduced more complexity to use it than later solutions.

Collapse
 
lixeletto profile image
Camilo Micheletto

You can still use gap and add spacing where needed, the element will offset normally. Also, can't see grid as an overkill since it's mor extensible, reliable and robust API. Nothing better to avoid creating additional media queries just to redefine absolute margins in mobile viewports.

Collapse
 
dsaga profile image
Dusan Petkovic

Thanks for the great post, its definitely something that comes to mind often when creating layouts, back in the day it was quite a bit more difficult without flexbox and grid.

How would you classify a case where we set all children to have a certain margin but from within the parent selector like so:

.parent .child {
    padding-bottom: 5px;
}

Enter fullscreen mode Exit fullscreen mode

Would the above still be classified as the child interfering with what should only be on the parent to set.

Thanks!

Collapse
 
moruno21 profile image
Antonio Moruno Gracia • Edited

Hi! I'm not quite sure about the purpose of that padding. I understand it could be for two reasons:

  1. If that padding-bottom is meant to separate the children from each other, you should remove the padding from the last child so that it doesn't add extra space after it. In this case, I would opt for using the gap property in the grid layout.

  2. If you simply want to add padding to the children (whether it's bottom, top, right, or left), I would suggest adding that padding directly to the children, like this:

.child {
    /*Whatever padding you want to add*/
}
Enter fullscreen mode Exit fullscreen mode

If you are using the .child class for other elements and only want the ones inside the parent to have this padding, you can separate the styles into two different classes: one for those inside the parent and another for those that aren't.

You may think that, with this approach, you would have duplicated styles. That's why I love using styled-components, because it allows you to create styles through composition. Here's an example:

const Child = styled.div`
    /*Common styles for all children*/
`

const ChildInsideParent = styled.div`
    ${Child}    /*You add here the common styles via composition*/
    /*Now you can add all the styles that you want without afecting the base Child component*/
    padding: 8px;

`
Enter fullscreen mode Exit fullscreen mode

Personally, I'm not a big fan of nesting styles. It's just an opinion.

I hope I've answered your question. Thanks a lot for the feedback :)

Collapse
 
thejase profile image
Jason Featheringham

Between parent and child, sure. But what about when some siblings should be spaced differently than others? This is very common, and gap doesn't cut it.

Collapse
 
pvivo profile image
Peter Vivo

I used this way to keep document harmonic flow.

<article class="grid gap-2">
  <h1>Why I don't use margin?</h1>
  <p>Because I use grid gap instead - mainly with tailwind</p>
  <section class="grid gap-1 rounded p-1 bg-gray-900  text-gray-300 text-[.7em]">
    <p>--  dense list of</p>
    <p>--  something</p>
    <!-- lot more -->
  </section>
  <p>This solution give well organized gap between different</p>  
  <p>section of doc, desktop publishing way</p>
</article>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
moruno21 profile image
Antonio Moruno Gracia

Just like that!

Collapse
 
pvivo profile image
Peter Vivo
<article class="grid gap-2">
  <h1>Why I don't use margin?</h1>
  <p>Because I use grid gap instead - mainly with tailwind</p>
  <!-- lot of other content -->
</article>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
drew-k profile image
Andrew

Paddings are not always applicable either. It heavily depends on the design and the page structure.

Collapse
 
appdevelopmentcompanyappingine profile image
AppDevelopmentCompanyAppingine

Opt for padding over margin in CSS for cleaner, more efficient code. This is crucial advice, especially for app development company striving for seamless UI/UX!

Collapse
 
npeete profile image
Péter Novák

One annoying thing with gap is that it adds around elements with display:none as well. Is there another solution except adding the margins to the children in these cases?

Collapse
 
jaelyn_jdouglas profile image
Jaelyn Tyson

Slay

Some comments have been hidden by the post's author - find out more