During the interview, you must never say only one, never say one solution, and never stop your hesitant mouth.

One of the most asked questions in CSS, I want to analyze it in three cases, horizontal centering, vertical centering and horizontal and vertical centering

As far as horizontal and vertical centering is concerned, there are probably the following solutions:

Centered element variable width and height

  • absolute + transform
  • flex property to center
  • flex + child margin auto
  • The grid property is centered
  • grid + child margin auto
  • grid + child property centering
  • -webkit-box property to center
  • table-cell + text-align
  • line-height + text-align
  • writing-mode
  • table

Only centered elements with fixed width and height apply:

  • Notice width and height + absolute + negative margin
  • Notice width and height + absolute + calc
  • Notice width and height + absolute + margin auto

Constrained global centering

  • Notice width and height + fixed + transform
  • Notice width and height + fixed + negative margin
  • Notice width and height + fixed + calc
  • Notice width and height + fixed + margin auto

Centered horizontally

text-align: center

 text-align: center;

Need to set display: inline-block inline block element

Absolute positioning + transform displacement

 position: absolute;
left: 50%;
transform: translateX(-50%);

out of document flow

width + margin: 0 auto

 width: 100px;
margin: 0 auto;

Here, width:100px must be a specific number, and the center is the outer center, and the content in the width is not centered

Center vertically

Absolute positioning + transform displacement

 position: absolute;
top: 50%;
transform: translateY(-50%);

Like the horizontal centering, it is a practice out of the document flow

table-cell + vertical-align

 display: table-cell;
vertical-align: middle;

display: table-cell , so that its label element is rendered as a table cell, similar to the td label,

vertical-align: middle , used to specify vertical centering of inline or table-cell elements

Centered horizontally and vertically

Absolute center + transform displacement

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

flex property to center

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: flex;
  justify-content: center;
  align-items: center;
}

flex + margin auto

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: flex;
}
.son {
  margin: auto;
}

The grid property is centered

 <div class="father">123123</div>
// 或者
<div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: grid;
  justify-content: center;
  align-items: center;
}

grid child property centering

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: grid;
}
.son {
  align-self: center;
  justify-self: center;
}

grid + margin auto

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: grid;
}
.son {
  margin: auto;
}

Grid is very similar to flex, it is an upgraded version of flex, so grid can do more

The above absolute positioning, flex, grid are about horizontal and vertical centering, and the rest is the older layout method of centering

-webkit-box property to center

This is an outdated layout, see this article CSS3 What is the difference between display: flex and display: box?

A netizen said:

flex is the syntax of 2012, the standard going forward

box is the 2009 syntax, which is outdated and needs to be prefixed

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: -webkit-box;
  -webkit-box-pack: center;
  -webkit-box-align: center;
}

table-cell + text-align

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.son {
  display: inline-block;
}

line-height + text-align

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  height: 200px;
  line-height: 200px;
  text-align: center;
}

line-height and height , the row height is the same as the height, so it is naturally centered vertically

writing-mode

 <div class="father">
  <div class="“son”">
    <div class="“sonson”">
      123123
    </div>
  </div>
</div>
 .father {
  writing-mode: tb-lr;
  writing-mode: vertical-lr;
  text-align: center;
}

.father .son {
  writing-mode: lr-tb;
  writing-mode: horizontal-tb;
  text-align: center;
  width: 100%;
  display: inline-block;
}
.father9 .son .sonson {
  display: inline-block;
  text-align: initial;
}

This is very cold and stuffy, someone has introduced this situation

table

 <table>
  <tbody>
    <tr>
      <td class="father">
        <div class="son">
          123123
        </div>
      </td>
    </tr>
  </tbody>
</table>
 .father {
  text-align: center;
}

The table label itself centers it vertically, text-align:center and then it is centered horizontally

You can watch the demo

When the element has width and height , there are three more options

Notice width and height + absolute center + margin negative margin

 <div class="father">
    <div class="son">
        123123
    </div>
</div>
 .father {
  position: relative;
  height: 200px;
}
.son {
  width: 100px;
  height: 100px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -50px;
}

The parent element must have a height in order to stretch the container. The child element must have a width and height in order to calculate the margin value

Notice width and height + absolute positioning + calc

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  position: relative;
  height: 200px;
}

.son {
  width: 100px;
  height: 100px;
  position: absolute;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
}

Similar to margin negative margins, the parent element needs to set a height. The child element must have a height, without margin, but use calc in CSS3 to calculate the center displacement, compatibility needs to support CSS3 properties

Notice width and height + absolute center + margin: auto

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 .father {
  position: relative;
  height: 300px;
}

.son {
  width: 100px;
  height: 100px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
}

Same as above two cases.

These three methods require positioning to achieve horizontal and vertical centering. You need to set the height of the parent element (must have it, to stretch the screen), and the child element needs to set the width and height. The first two methods are to calculate it in the parent element. Relative position, the latter method is to indicate that the child element is a container (if the width and height are not set, it is none)

Other methods

In fact, in terms of horizontal and vertical centering, if the interviewer insists on asking, is there anything else? There really is, use fixed positioning . But this method has flaws. Although it can achieve horizontal and vertical centering, it is relative to the viewport (viewport), not the parent element.

The method is to change the above implemented with absolute to fixed.

  • Notice width and height + fixed + transform
  • Notice width and height + fixed + negative margin
  • Notice width and height + fixed + calc
  • Notice width and height + fixed + margin auto

These four methods all need to set the width and height of the child element

Paste the code here

 <div class="father">
  <div class="son">
    123123
  </div>
</div>
 /* transform */
.son {
  width: 100px;
  height: 100px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: blue;
}

/* 负 margin */
.son {
  width: 100px;
  height: 100px;
  position: fixed;
  top: 50%;
  left: 50%;
  margin-left: -50px;
  margin-top: -50px;
  background: blue;
}

/* calc */
.son {
  width: 100px;
  height: 100px;
  position: fixed;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
  background: blue;
}

/* margin: auto */
.son {
  width: 100px;
  height: 100px;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  background: blue;
}

Summarize

With Microsoft's announcement to abandon IE11, flex layout can be used in real projects, and the grid part is not yet adapted, but it will definitely replace flex in the future.

Although I have written a lot, I will not use outdated layout methods such as table, writing-mode, -webkit-box, etc. in my work. I wrote this article purely to be asked this kind of question during the interview.

The harvest is that absolute centering needs to be concentric with the parent and child (the parent element sets the height, and the child element sets the width and height), and the fixed centering only needs to set the width and height of the child element.

Online demo view

References

This article participated in the SegmentFault Sifu essay "How to "anti-kill" the interviewer?" , you are welcome to join.

山头人汉波
394 声望555 粉丝