You Might Also Be Interested In
Understanding the difference between margin and padding can be tricky in CSS as both are spacings. In this article, we will observe how they are different and why having an incomplete understanding can lead to design bugs.
Before we dive into understanding the difference between margin and padding, we need to have an understanding of the CSS Box Model.
Box Model is a visual presentation model that CSS uses to represent an object. Why? A model is necessary for CSS Engine to refer to for understanding how to display, position, and style items.
Everything in CSS is a box.
As we can see, this box has 4 parts:
background-color
applied to the content area will also be applied to this area.<h1>
, <p>
, etc.As we briefly touched on it, padding is the inner spacing of an element between the border and content areas. Padding is a space that belongs to the element and is an integral part of it.
For example, consider the following illustration of a fried egg:
Our content is the yolk. Padding is all the white - the space between the yolk and the boundary (i.e. border) of the egg.
What will happen if we increase the whiteness? The egg will grow in size. The same applies to increasing padding. When we increase the padding, we essentially increase the size of the target element.
Consider the following example. We have the same element with 3 different values of padding.
Note that the increase in padding increased the actual size of the element. This is reflected by an increase in the size of the blue background - which is an integral part of the element itself.
Margin is a space that an element can reserve beyond its physical boundary. The physical boundary includes all the regions that can be classified as integral parts of the element. Reserving a space beyond it helps only in positioning and adds nothing to the structure of the element.
In the following figure, while the spacing between an egg’s yolk and its edge is padding, the spacing between the edges of the 2 eggs is the margin.
Increasing the margin around an element does not affect its size. Let’s illustrate this with an example.
We create a parent-child hierarchy of divs. Parent div has a width set to max-content while the child div has a fixed, limited width. Parent div has an orange background color but since the inner div does not have any margin around it, we can’t see it. Parent div has its display set to flex for creating a flex layout.
<div class="parent">
<div class="child">
Margin: 0px;
</div>
</div>
.parent {
background: orange;
}
.child {
background: #48abe0;
margin: 0;
}
Let’s give it a margin of 10px.
.child {
// …
margin: 10px;
}
Why do we see the orange color? Because the inner div now has a margin of 10px around it. Since all that area is physically not part of the target element, we can see the content of the parent component around it.
What if we had given it padding instead of margin? Let’s see.
.child {
margin: 0;
padding: 10px;
}
The blue region, the background of the inner div, has grown in size. Why? Because padding is the space internal to the element and is a part of it, unlike margin.
Margin can be set to auto, negative, and float values, unlike padding which must be provided with non-negative values only.
Now that we know the definitions of and differences between margin and padding, let’s take a look at which should be used in what scenario.
Using the wrong spacing can lead to design bugs. Let’s assume we are building a tabs header to host multiple tab names. We write the required HTML and use spans for tab names. Since tab names should be at a reasonable distance from each other, we give them a left margin.
<div class="tabs">
<span class="tab">Tab1</span>
<span class="tab">Tab1</span>
<span class="tab">Tab1</span>
</div>
.tabs {
border-bottom: 1px solid grey;
}
.tab {
margin-left: 10px;
margin-right: 10px;
}
Everything looks good so far. Let’s make it more appealing by adding a vertical separator between the tabs.
.tab:not(:first-child) {
border-left: 1px solid;
}
Does this look like what we wanted? No. In our mind, we had the separator not touching the text. What went wrong here? We provided the spacing between the tab names with margin, not padding. So when the border is added to the tab names, there is no gap i.e paddable-area between the content and border. We can fix this by using padding instead of margin.
.tab {
padding-left: 10px;
padding-right: 10px;
}
There we go, it is fixed as now we are setting the right type of spacing.
Padding also increases the surface area of elements, which is particularly beneficial for hoverable/clickable elements. Consider we are developing a navbar containing <a>
tags and it looks like the following so far.
We need the elements to swap background and text color on hover as follows
We have the hover effect in place. But the spacing is off. We need our nav elements to grow in size. Let’s try to solve it by adding a margin to them.
ul li a { margin: 10px; }
Hover state now looks like this
We were able to increase the spacing as per our requirement, but why didn’t our hover/clickable area increase? Because we applied margin which is a space external to the element and not a part of it. So we got the spacing we needed but not the benefit of the growth of our element’s interactive surface area. If we solve the problem with padding, we get the added benefit.
ul li a { padding: 10px; }
There we go, our spacing is fixed as well as the interactive area is increased. There we go, our spacing is fixed as well as the interactive area is increased.
<input type="radio" id="margin" name="fav_language" value="HTML" checked> <label for="margin">Margin</label> <input type="radio" id="padding" name="fav_language" value="CSS"> <label for="padding">Padding</label> <div class="parent"> <div class="child"> Target Element </div> </div>
body { font-family: sans-serif; text-align: center; } body { font-size: 22px; } .parent { width: max-content; display:flex; justify-content: center; align-items: center; margin: auto; background: orange; } .child { display: inline-block; width: 320px; background-color: #48abe0; color: white; text-align: center; font-family: sans-serif; } .controls { margin-bottom: 20px; display: flex; } #margin { margin-bottom: 20px; } #margin:checked ~ .parent .child { margin: 10px; padding: 0px; } #padding:checked ~ .parent .child { margin: 0px; padding: 10px; }
There are a number of scenarios that can put content into the margins, e.g:
transform
property to move/scale another element into the marginposition: relative;
can be used to move an element into another element's marginsposition: absolute;
can be used to place an element absolutely over the layout at any place, including margins of the elements that are part of the layout.Margins and Paddings are very different kinds of spacing. Understanding their differences is essential for creating bug-free layouts that behave in expected ways.