Cao Feng, front end engineer of medical support team. Virgo, code for elegance.

Where dreams begin

In the world of CSS, all kinds of centering problems can be said to be always with us, margin: Auto must be a well-deserved childhood memory, even now we have mastered all kinds of CSS strange technology and crafty, this section of plain code still occupies a place, four words to evaluate: YYDS! Let’s revisit this classic code:

<style>
	.parent-panel {
    padding: 20px;
    background-color: darksalmon;
  }
  .main-panel {
    width: 60%;
    margin: auto;
    background-color: blanchedalmond;
    text-align-last: justify;
  }
</style>

<div class="parent-panel">
	<div class="main-panel">I'm in the middle</div>
</div>

Copy the code

The effect is as follows:

Margin: Auto resolves the problem of centring a block element of a fixed width in a normal flow horizontally. Under the premise of LTR, when we set margin-left: auto (margin-right: auto) for a block element, its calculated value is the available remaining space in the horizontal direction of the parent of the block element. If both are set, the remaining space will be evenly divided and the element will naturally be centered horizontally.

If you want a fixed width block element to be horizontally centered, it is left or right. If you want a fixed width block element to be horizontally centered, it is right. According to the above explanation of the calculation principle of margin value as auto, it is not difficult to think of a solution: by setting the margin-left of the element: Auto makes its margin-left occupy all available remaining space to the left of the parent element, and pushes it to the right of the parent element to achieve the right effect. The code is as follows:

<style>
	.parent-panel {
    padding: 20px;
    background-color: darksalmon;
  }
  .main-panel {
    width: 60%;
    margin-left: auto;
    background-color: blanchedalmond;
    text-align-last: justify;
  }
</style>

<div class="parent-panel">
	<div class="main-panel">I'm on the right now</div>
</div>

Copy the code

The effect is as follows:

As can be seen from the above two examples, margin of auto is convenient to control the horizontal alignment of a block element with a fixed width, but in fact, it is very limited, mainly because we have many constraints on this element: Fixed width, block elements, horizontal orientation, and because they are block elements, there is only one block element in the line in a normal document flow. So how do we control how elements are treated in more complex scenarios, such as vertical orientation, multi-element scenarios, and so on? That’s the Flexbox layout.

Flexbox brings more possibilities

The Flexbox layout is familiar and has been used extensively in real-world applications. It provides developers with a more elegant layout solution, even for problems that previously could not be solved using CSS alone. For examples of common scenarios, see here (castle-by-Flexbox). We won’t go into the various layout options here, but let’s see what happens when Flexbox meets Margin: Auto.

The Flexbox layout comes with a number of attributes that control how child elements are aligned on main and cross axes: Align-items align-self context-content is used a lot, but there is no context-self that allows individual elements to do special things to themselves. In CSS Flexbox, why are there no “sequence-items” and “sequence-self” properties? . There are also special situations where the effects of justice-content can be problematic, as described below. Let’s take a look at some actual layout effects.

About the alignment

Take a look at this very common layout:

The layout requirements are as follows: all child elements are vertically centered and horizontally divided into two areas, the “one-click, three-link” main operation area on the left and some auxiliary operation areas on the right, and we require to write as concise HTML code as possible, pseudo code is as follows:

<ul class="operate-panel">
  <! -- Main operation area -->
  <li class="item">give a like</li>
  <li class="item">coin</li>
  <li class="item">collection</li>
  <li class="item item-forward">forwarding</li>
  
  <! -- Auxiliary operation area -->
  <li class="item item-report">complaints</li>
  <li class="item">notes</li>
  <li class="item">More operations</li>
</ul>

Copy the code

The first thing that comes to mind is to use Flexbox for layout, which looks like this:

.operate-panel {
  display: flex;
  align-items: center;
}
.operate-panel .item + .item {
  margin-left: 2em;
}

Copy the code

The above code has almost completed the layout requirements, but there is still a need to put the auxiliary area to the right how to implement. One idea is to make the ‘forward’ button flex-grow 1 push the auxiliary area to the right, or the ‘complain’ button Flex-grow 1; Text-align: right works the same way. The code is as follows:

.operate-panel .item.item-forward {
  flex-grow: 1;
}
/* or */
.operate-panel .item.item-report {
  flex-grow: 1;
  text-align: right;
}

Copy the code

But there is a downside to the code above: the width of the element is stretched, which may affect the layout of the element itself. For example, the maximum width of the element should not be more than 100px, and ellipsis should be displayed beyond the element, so our solution is to keep the size of the element unchanged.

In fact, we can wrap the left and right areas in a container, and then align the left and right sides of the two containers, but we would need to write more HTML tags for layout, so this solution is not considered for now.

So let’s see if margin: Auto works here. Let’s take a look at how Margin: Auto calculates in the Flexbox layout:

Auto margins on flex items have an effect very similar to auto margins in block flow:

  • During calculations of flex bases and flexible lengths, auto margins are treated as 0.
  • Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.
  • Overflowing boxes ignore their auto margins and overflow in the end direction.

Simple to define margin on Flex Items (Aligning with ‘auto’ Margins) according to the spec (Aligning with ‘auto’ Margins) : The effect of auto on block elements is similar to the one described above: it takes up the remaining available space of the parent, but the difference is that margin: Auto on Flex items works both horizontally and vertically. OMG use it!! Look directly at the code:

.operate-panel .item.item-forward{
	margin-right: auto;
}
/* or */
.operate-panel .item.item-report {
  margin-left: auto;
}

Copy the code

In a word: very elegant! This problem is solved very gracefully. Next.

Top bar of the page with actions

The title is a bit convoluted, look directly at the effect:

The requirements are as follows: the left “back” button is to the left, the right operation area is to the right, the title is horizontally centered in the remaining free space, and all child elements are vertically centered. Let’s start with the HTML code:

<ul class="header-panel">
  <li class="item">&lt;return</li>
  <li class="item item-title">I am heading</li>
  <li class="item">listing</li>
  <li class="item">search</li>
  <li class="item">release</li>
</ul>

Copy the code

Not surprisingly, we used Flexbox for layout. The main CSS code is as follows:

.header-panel {
  display: flex;
  align-items: center;
}
.header-panel .item + .item {
  margin-left: 2em;
}

Copy the code

The main problem now is the positioning of the “title”. Consider that in the existing alignment provided by Flexbox, we can’t find a solution unless we adapt the HTML code to wrap the left and right sections in a container and then justify-content on the parent element: Space between. Yes, but not elegant.

The title should be horizontally centered in the remaining available space, margin: auto Margin-left: auto; margin-right: auto; margin-left: auto; margin-right: auto;

.header-panel .item.item-title {
  margin: 0 auto;
}

Copy the code

Add a margin-right: auto to the left of the title and a margin-left: auto to the right of the title. Yes, but there’s no need. That’s the perfect solution to the problem. Next.

margin: autoI want to usurp the throne

Margin: Auto margin: Auto Margin: Auto Margin: Auto margin Font-size: 16px; “> < span style =” font-size: 16px; margin-top: 16px; Margin: Auto copy! Paste! Where is not neat paste where! So is this really the case? Margin: Auto margin: Auto Margin: Auto Margin: Auto margin

<ul class="flex-panel">
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
</ul>

Copy the code
.flex-panel {
  display: flex;
}

/* align-items: center */
.flex-panel > .item {
  margin: auto 0;
}

/* justify-content: center */
.flex-panel > .item:first-child {
  margin-left: auto;
}
.flex-panel > .item:last-child {
  margin-right: auto;
}

/* justify-content: space-around */
.flex-panel > .item {
  margin: 0 auto;
}

/* justify-content: space-between */
.flex-panel > .item + .item {
  margin-left: auto;
}

/* justify-content: space-evenly */
.flex-panel > .item {
  margin-left: auto;
}
.flex-panel > .item:last-child {
  margin-right: auto;
}

Copy the code

Margin: Auto allows you to use margin: Auto for all of your illustrative content and align-items. But you may be wondering: since flexbox already implements these alignments, margin: Auto is also necessary. That’s what I started with:

And the effect of context-content can be problematic in some special scenarios

Here’s a scene:

The requirements are as follows: the width of each piece is fixed width: 30% non-scalable, the remaining available space of the parent element is evenly divided between each block as an interval, when the number of too much width beyond the parent container when rolling. We can write the following code:

<style>
	.bottom-panel {
    display: flex;
    justify-content: space-evenly;
    overflow: auto;
  }
  .bottom-panel > .item {
    width: 30%;
    flex-shrink: 0;
  }
</style>

<ul class="bottom-panel">
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
</ul>

Copy the code

This code number in child elements will not beyond the parent container when performance is very perfect, but, more than three child elements, all child elements width greater than the sum of 100% will be beyond the parent element, at this time you are normal, the effect of the left side of the department of molecular element will be hidden, the whole or in part by scrolling parent cannot make it, As follows:

<style>
	.bottom-panel {
    display: flex;
    justify-content: space-evenly;
    overflow: auto;
  }
  .bottom-panel > .item {
    width: 30%;
    flex-shrink: 0;
  }
</style>

<ul class="bottom-panel">
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
</ul>

Copy the code

This problem also exists in context-content: center context-content: space-around, and safe is defined in the specification to address this problem, although browser support is woefully poor.

Margin: Auto will pop up just when you need it most.

Look again at the specification definition mentioned above:

Overflowing boxes ignore their auto margins and overflow in the end direction.

In this case, Margin: Auto will choose to disappear silently and return you a share of love and peace.

<style>
	.bottom-panel {
    display: flex;
    overflow: auto;
  }
  .bottom-panel > .item {
    width: 30%;
    flex-shrink: 0;
    margin-left: auto;
  }
  .bottom-panel > .item:last-child {
    margin-right: auto;
  }
</style>

<ul class="bottom-panel">
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
  <li class="item"></li>
</ul>

Copy the code

conclusion

I believe that you are now more impressed with the understanding and use of Margin: Auto, especially with The combination of Flexbox will bring a lot of wonderful magic experience, Flexbox itself is very powerful layout scheme, with margin: Auto’s support is even more powerful. If there are mistakes or improper expressions in the article, welcome to pat brick to help me progress. I’m a big fan of CSS, and I love elegant layouts, and I welcome you to explore them.

margin: autoForever, god!

The resources

  • Margin series keyword Auto
  • solved by flexbox
  • Aligning with auto margins
  • What’s the difference between margin:auto and justify-content / align-items center?
  • In CSS Flexbox, why are there no “justify-items” and “justify-self” properties?
  • Can’t scroll to top of flex item that is overflowing container
  • Overflow Alignment: the safe and unsafe keywords and scroll safety limits