Antonio Moruno Gracia
Posted 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 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?
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.
.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.
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.
.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.
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.
.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:
- This only works for centering elements horizontally, not vertically.
- Inline elements (
<a/>
,<em/>
,<span/>
, etc) cannot be centered using this declaration. It only works for block elements. - 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.
- 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.
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!
Posted on October 10, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.