Don't use margin in CSS
Tags: css, cleancode, webdev, react
Published: 2023-10-10 19:52:30

Nowadays, CSS has a wide range of tools and properties that allow designs that, until a few years ago, seemed impossible to implement. Many developers focus on learning this style language to the smallest detail, which can be quite challenging for some.

Despite not being considered a programming language by most, it's important to note that it's also a part of many applications. As developers, we should be responsible, making the code we develop as easy to **understand, modify, and maintain** as possible. CSS is no exception.

The goal of this post is to shed some light on a well-known property in CSS: **margin**. We will discuss its sometimes incorrect usage and propose alternative approaches that are much more maintainable and clean.

---


## ❌ When not to use

The main reason for not using margin lies in a matter of **responsibility**. When designing the layout of an application or an individual component, we should consider who is responsible for what.

_(For the sake of the post, we will omit border styles and other details)._

### Between parent and children

Let's imagine that we want to implement the following layout. The goal is to position the blocks as shown in the image. Who is responsible for placing the child at a certain distance from the parent: the child or the parent?

![Layout with one block as child](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8oz3urp37ud8awkptft.png)

**It's the parent** who should define the distance at which their children are positioned. This is the key. **The responsibility lies within the parent block**. If we wanted to change the content of the parent, we would probably want to preserve the distance that their children have from it, so these styles should belong to the parent.

```css
.parent {
    padding: 24px;
}

.child {
    /*No margin needed*/
}
```

Of course, there are exceptions. It's possible that we may need to create a layout where the children are not at the same distance to the parent, as shown in the following image.

![Layout with many blocks as children](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qfcnpflzmy03w70zjcx.png)

In this case, it's possible to approach the design as follows: **the parent of the last two elements is not the same as the parent of the first element**. We can create another element to serve as a **wrapper for the last two elements** and apply the "extra margin" they have as padding.

![Adding wrapper to the last two children](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66bgws9vh6xxyj5m0a4p.png)

```css
.parent {
    padding: 24px;
}

.wrapper {
    /*Extra padding for the last two children*/
    padding: 24px; 
}

.child {
    /*No margin needed*/
}
```


_Note: The borders are shown simply to illustrate the blocks we would have at code level. The presence of an additional parent block would be invisible to the application end-user._


### Between siblings

You may have noticed a detail in the previous layout: **the child elements are also separated from each other.**

This separation can be achieved by applying top or bottom margin to all of them. However, we come back to the same question: who should be responsible for separating the children from each other? Well, surprisingly, **it should be the parent.**

But, from the parent, how can we separate children from each other? The best option is to harness the power of the [Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout).

This post doesn't cover the use of this type of layout in detail. In summary, the **Grid Layout** allows us to treat the children of an element as if they were in a grid, organizing how they are positioned relative to each other. Among its options, it's possible to determine the exact distance at which elements are positioned from each other. How? Well, by using the `gap` property.

![Container with elements positioned using grid layout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dtlnpxe6esg1m3soafcn.png)

```css
.parent {
    display: grid; /*Changes the display layout to grid*/
    gap: 24px; /*Desired gap between elements*/
    padding: 24px;
}

.child {
    /*No margin needed*/
}
```


The major advantage of using this alternative is that the `gap` property **adds space only between the elements, neither at the beginning nor at the end**. If we were to use margins for each element, we would need to ensure that these margins are not applied incorrectly to the first or last element to avoid unnecessary spacing.

**Amazing! Isn't it?**


---

## ✅ When to use

There are some occasions when using margin is not a bad alternative.

### Margin: auto

If an element uses `margin: auto`, **it will be centered horizontally with respect to its parent**. However, there are several considerations to keep in mind:

1. This only works for centering elements horizontally, not vertically.
2. Inline elements (`<a/>`, `<em/>`, `<span/>`, etc) cannot be centered using this declaration. It only works for block elements.
3. We come back to the same question again: who is responsible for centering the element? In this case, the element would be centered by itself, not by its parent.
4. There are other properties within the flex and grid layouts that allow both vertical and horizontal centering (`justify-content`, `align-items`, etc), which could be more appropiate.

Despite these disadvantages, sometimes using `margin: auto` is simpler and quicker than any of the alternatives, so it's not a bad choice.

### Overlapping

When it comes to overlaying elements, using margins can be very handy.

![Container that overlaps its parent](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf3hkbs2y1inao4dhyxw.png)

To achieve the layout from the previous image, we can apply a **negative margin** to the child element (such as `margin-left: -120px`), causing it to be displayed overlapped with its parent element.

There are other alternatives, such as the `position` property, which allows to position elements relative to another element. However, using this property may, among other things, cause the child element not to respect the parent's padding.

In this case, using negative margins is much simpler and more straightforward.

---


I hope you found this post interesting and that it helps you in your programming projects. The proposed alternatives are just one of the many options that CSS offers. In programming, there is not a single way to do things. In CSS, neither is there.

If you have any questions or want to share any ideas, please leave a comment below.

Thanks for your time!