Analysis of the principle of CSS implementation of element centering

Centering elements horizontally and vertically is a very common requirement in CSS. But this is one that seems to be extremely simple to implement in theory. In practice, it often stumped many people.

Centering an element horizontally is relatively simple: if it's an inline element, apply it to its parent text-align: center; if it's a block element, apply it to itself margin: auto.

However, if you want to vertically center an element, it is not so easy, and sometimes it makes your scalp tingling just thinking about it.

This article describes the inline elements and block-level elements respectively, and collects the currently popular implementation methods and analyzes the implementation principles for your convenience. It should be pointed out here that each method is not perfect. The key is to look at your own needs, so as to analyze which implementation method is the most suitable.

Elements in the line

First, let's write the basic code:

<div class="main">
    <span class="content">我是要居中的行内元素span</span>
</div>
.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
}

.content {
    background-color: #5b4d4e;
    color: #FFFFFF;
}

.mainThe div with class wraps this .contentinline element span with class , and our purpose is .contentto .maincenter the element in the element.

Centered horizontally

text-align

The horizontal centering of inline elements is relatively simple. We can .maindirectly add text-align: center;to in , and then .mainbecomes :

.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
    
    text-align: center;  /* 水平居中 */
}

Implementation principle: Set text-alignthe value of center, because this attribute specifies the horizontal alignment of the text in the element, then set to center, the text will be centered horizontally.

Center vertically

line-height

The vertical centering of inline elements is divided into 一行and 多行或者图片等替换元素to illustrate.

If it is 一行, then we can use line-heightto achieve, at this time the .mainelement css code becomes:

.main {
    width: 300px;
    height: 300px; /* 可以不设置 */
    background-color: #50ba8b;

    line-height: 300px; /* 垂直居中 */
}

In fact, line-heightsetting can make the text vertically centered, and it does not need to be set at the same time height. This is also a misunderstanding that has always existed.

Implementation principle: This way to achieve vertical centering uses the "up and down equalization mechanism of line spacing" in CSS, which also explains why this way is only suitable 一行for text of .

Another point to note is that the vertical centering achieved in this way is "approximate", not perfect vertical centering, because the vertical centerline position of the text glyph is generally lower than that of the real "line box box". And because the font-size we usually use is relatively small, this deviation is not easy to detect, so it is perceived as vertically centered.

line-height 及 vertical-align

Let's talk about the realization 多行或者图片等替换元素of the vertical centering effect, here we need to use line-heightand vertical-alignto achieve.

Let the text wrap first:

<div class="main">
    <span class="content">
        我是要居中的行内元素span <br>
        我是要居中的行内元素span
    </span>
</div>

Look at the modified css code again:

.main {
    width: 300px;
    background-color: #50ba8b;

    line-height: 300px;
}

.content {
    display: inline-block;
    background-color: #5b4d4e;
    color: #FFFFFF;
    line-height: 20px;
    margin: 0 20px;
    vertical-align: middle;
}

Implementation principle:

  1. Set the .contentelement 's display to inline-block. The function is to not only reset the outer line-height to the normal size, but also maintain the characteristics of the inline element, so that the vertical-align property can be set, and a very critical "line box box" can be generated. What we need is not this "line box box", but a product that comes with each "line box box" - "ghost blank node", that is, an invisible "ghost node" with a width of 0 that behaves like ordinary characters. node". With this "ghost blank node", our line-height: 300px;has a working object, which is equivalent .contentto propping up an inline element with a height of 300px and a width of 0 in front of the element.
  2. Because inline elements are baseline aligned by default, .contentwe vertical-align: middle;adjust the vertical position of multi-line text by setting the element to achieve the "vertical centering" effect we want. This also works 图片等替换元素for vertical centering effects of . Of course, the "vertical centering" here is also approximate, which is caused by vertical-align. You can learn more about why vertical-align: middle;.

block level element

Still write the basic code first:

<div class="main">
    <div class="content">我是要居中的块级元素div</div>
</div>
.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
}

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;
}

.mainThe div with class wraps this .contentblock-level element div with class , and our purpose is .contentto .maincenter the element in the element.

position + margin: auto

The implementation code is as follows:

.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
    
    /*关键代码*/
    position: relative;
}

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;

    /*关键代码*/
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
}

Implementation principle:

  1. Set the .mainelement to relative positioning position: relative;so that its child elements will be relative to it when absolute positioning is set.
  2. Then set the .contentelement to absolute positioning position: absolute;and set its top, left, bottom, rightto 0, so that the size of the element of the element is expressed as "formatted width and formatted height", which is the same as <div>the "normal flow width" of , and belongs to the external size, That is, the size automatically fills the available size of the parent element, but since we set the width and height of the .contentelement , the automatic filling of the element is limited, so that there is an extra 150px of space.
  3. Finally, we set the .contentelement as margin: auto;, at this time, according to the calculation rules of auto, the remaining space of the upper, lower, left and right sides is divided equally, and it is naturally centered.

position + margin-left/top

The implementation code is as follows:

.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
    
    /*关键代码*/
    position: relative;
}

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;

    /*关键代码*/
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -75px;
    margin-top: -75px;
}

Implementation principle:

  1. Set the .mainelement to relative positioning position: relative;so that its child elements will be relative to it when absolute positioning is set.
  2. Then set the .contentelement to absolute positioning position: absolute;and set top: 50%;, left: 50%;so .contentthat the upper left corner of the .mainelement is in the center of the element.
  3. Finally, set the .contentelement margin-left: -75px;, margin-top: -75px;move itself to the left and half of the width and height, so .contentthat the center of the element is at the center of the .mainelement, and the centering effect is naturally achieved.
  4. The disadvantage of this method is that the width and height of the .contentelement .

position + translate

The implementation code is as follows:

.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;
    
    /*关键代码*/
    position: relative;
}

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;

    /*关键代码*/
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

Implementation principle:

  1. Set the .mainelement to relative positioning position: relative;so that its child elements will be relative to it when absolute positioning is set.
  2. Then set the .contentelement to absolute positioning position: absolute;and set top: 50%;, left: 50%;so .contentthat the upper left corner of the .mainelement is in the center of the element.
  3. Finally, set the .contentelement transform: translate(-50%, -50%);to move itself to the left and half of the width and height, so .contentthat the center of the element is at the center of the .mainelement, and the centering effect is naturally achieved.
  4. The advantage of this method is that there is no need to fix the width and height of the .contentelement .

Flexbox

The implementation code is as follows:

.main {
    width: 300px;
    height: 300px;
    background-color: #50ba8b;

    /*关键代码*/
    display: flex;
}

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;

    /*关键代码*/
    margin: auto;
}

Implementation principle:

  1. Set .mainelement display: flex;.
  2. Then set the .contentelement to margin: auto;to achieve centering.
  3. This is undoubtedly the best solution, we don't need to set the .contentelement to be absolutely positioned, margin: autoit can naturally act on the width and height, and we don't need to set the width and height of the .contentelement , because Flexbox (flexible box) is specially designed for this kind of demand designed.
  4. The disadvantage is that the current browser support level will be lower than other methods.

Another benefit of Flexbox is that it can also vertically center anonymous containers (i.e. text nodes that are not wrapped by labels). .mainFor example , instead of setting the element to display: flex;, we set the .contentelement to display: flex;, and with the help of the align-items and justify-content properties introduced by the Flexbox specification, we can center the text inside it (we can .mainuse the same properties for the element to make The .contentelement element is centered, but is a bit more elegant than the margin: automethod and acts as a fallback at the same time).

.content {
    width: 150px;
    height: 150px;
    background-color: #5b4d4e;

    /*关键代码*/
    display: flex;
    align-items: center;
    justify-content: center;
    margin: auto;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325050181&siteId=291194637