Margin is a very common property that is used in CSS all the time to control the spacing and layout of elements in a web page. Even in popular CSS frameworks like Bootstrap and Tailwind CSS, we have utility classes to specify margins for all or specific sides of an element.
Though we normally use lengths in units (such as rems, pixels, ems etc.) or percentages as values for margin property. Do you know margin property also accepts a keyword called "auto" as value?
Let's take a deeper look at what auto
does and how it can be used!
β¨ What does auto
mean?
When an auto keyword is used in margin property, the browser automatically calculates a suitable margin for an element based on the space around it. auto
essentially tells the browser to let the element take up the available space.
β¨ What does "taking up available space" mean?
Suppose I have a <div> tag
inside a <section> tag
and it looks like the image below.
We know that block-level elements primarily take up the entire width of their parent so no space is left for auto
to work on. Therefore, I've given the <div> tag
a fixed width of 100px to create space inside its container.
π What do you think will happen if I assign margin-left: auto to this orange box?
The element moves all the way to the right side, using every bit of the available space for its left margin.
auto
takes up all the available space for the margin it is applied for. But there are few points that should be kept in mind when using auto
- For block-level elements, it works only with margin-left and margin-right properties.
- It shows no effect for floated and inline elements.
- It works for absolute elements only under certain conditions.
- It works for margin-top and margin-bottom properties only with flexbox or grid.
β¨ Using auto
with block-level elements
When using with block-level elements, auto
only works on margin-left and margin-right properties given that the element has a fixed width, leaving space in its parent container. We saw earlier how margin-left : auto
pushed the element to the right edge of its container.
π What do you think will happen if I also add margin-right: auto to that orange box?
auto
will divide all the available space equally between right and left margins and hence center align the element horizontally within the parent container.
This is the most popular use case of auto
. With just one line we can horizontally center images, divs and other block-level elements within their parent containers.
You can use either margin
shorthand property or margin-inline
to center align the element horizontally.
β οΈ Do remember that it will work only for block-level elements with fixed widths!
element {
/* use any one of the below properties */
margin: 0 auto;
/* or */
margin-inline: auto;
}
β¨ Using auto
with absolute elements
Absolutely positioned elements are out of the normal flow of a document so it feels right that margin: auto
should not work for it. But there seems to be an exception which allows us to use auto
to center align an absolute element within its parent both vertically and horizontally.
π W3C Spec specifies βΆ
If all three of "left", "width", and "right" are
auto
: First set any auto values for "margin-left" and "margin-right" to 0.If none of the three is
auto
: If both "margin-left" and "margin-right" are auto, solve the equation under the extra constraint that the two margins get equal values
W3C Spec specifies the same for "height", "top" and "bottom" properties. This means that we can center align an absolute element βΆ
- horizontally if its left and right properties have same values and has a fixed width
- vertically if top and bottom have same values and has a fixed height
By using these exceptions we can assign below properties to center align an absolute element within its parent.
.parent {
position: relative;
height: 150px;
}
.child {
position: absolute;
margin: auto;
inset: 0; /* sets left, right, top & bottom to 0 */
width: 70px;
height: 20px;
}
inset: 0
is shorthand for setting all four properties β left, right, top and bottom as 0.
Though this method works to center align an absolute element within a parent because of the exceptions in W3C Spec. It is best to use a combination left
, top
and transform translate
properties to achieve this.
.parent {
position: relative;
}
/* use this method to center align an absolute element */
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
β¨ Using auto
with flexbox or grid
Flexbox and grid both allows us to use auto
with margin property to center align an element both horizontally and vertically.
Let's take our previous example of a <section> tag
with a <div> tag
inside it and this time set display: flex
property on the <section> tag
.
section {
height: 120px; /* height is required to align vertically */
display: flex;
}
div {
width: 80px;
margin: auto;
}
auto
works on all 4 margin properties and places the orange box in the middle of its flexbox parent.
β οΈ Do remember to add height to flexbox container if you want to use auto
on margin-top
and margin-bottom
properties on its children, otherwise they won't work.
If you replace display: flex
with display: grid
for <section> tag
, you will get the same result.
β¨ Creating Navbars with auto
and CSS flexbox
One of the most interesting use case of auto
that I came across recently was making navigation bars with the help of CSS flexbox!
I have prepared a very basic navigation bar with a title, few links and a sign up and login buttons. Flexbox is used to align all these elements in a row.
π What if I want all the links and the 2 buttons on the right side of navbar?
One of the ways is to use justify-content: space-between
on flexbox container since we have title in one tag and all the links and buttons inside a <ul> tag
.
Another way is to add flex-grow: 1
on <ul> tag
and use margin-left: auto
on the first <li> tag
that is link Products
ul {
flex-grow: 1
}
/* <li> tag with link 'Products' */
/* nth-child(1) selects first <li> tag */
li:nth-child(1) {
margin-left: auto;
}
By default, flex items take up minimum space required to fit their content. So to create space for auto
to take we added flex-grow: 1 on <ul> tag
so that it grows to fill the remaining space in its flexbox parent.
π What do you think will happen if I set margin-left: auto
on sign-up button also?
All the links are now in the middle and the 2 buttons are at the end. We got another version of navbar very easily with just one line of code!
In the same way, we can make sidebars where say socials icons are at the end, title at the top and all the links in the middle. We just have to give flex container a fixed height and use margin-top: auto
on the first link and the social icon element.
β¨ Conclusion
Throughout this article, we looked at how auto
keyword can be used with margin
property. We also learnt how it can be used with flexbox to easily make beautiful versions of navigation bars.
That's all for this article. Thank you for reading!! π
I hope you found this article helpful! Feel free to comment down your feedbacks!! I would love to read them and improve. You can also buy me a coffee. For more content around CSS, follow me on Twitter.
Top comments (6)
I am so glad you liked the article Andrew!π
Great post, congrats!
Thanks a lot Camilo!
Great post, ππ
Thank you Martin!π