无论是在面试中还是在工作中,将一个元素置为水平或垂直居中,都是一个前端工程师必备的基本功,接下来让我们一起来对居中这个话题进行系统性的梳理和总结。

一、水平居中

行内元素

HTML结构

  <div class="parent">
    <span class="child">111</span>
  </div>

居中方法:给其父元素设置text-align: center;

text-align: center;

块级元素

一般块元素

只需给该元素设置margin: 0 auto即可。

margin: 0 auto;

子元素包含float的情况

可以给父元素设置宽度为:fit-content。

.parent {
    margin: 0 auto;
    width: fit-content;
}
.child {
    float: left
}

flex布局实现水平居中

通过给父元素设置下面两个属性:

display: flex;
justify-content: center;

绝对定位 + left + transform

给子元素设置下面的css样式。(注意:下面的translate是相对于自身进行移动的)

position: absolute;
left: 50%;
transform: translate(-50%,0);

绝对定位 + left + margin-left

给子元素设置下面的CSS样式。

position: absolute;
left: 50%;
margin-left: calc(-0.5*100px);

绝对定位 + left/right + margin

给父元素设置下面的CSS样式。

position: absolute;
left: 0;
right: 0;
margin: 0 auto;

二、垂直居中

行内元素

单行文本

给子元素的行高设置为父元素的高度即可。

.parent {
  width: 200px;
  height: 200px;
  text-align: center;
  border: 1px solid red;
  margin: 0 auto;
}
.child {
  line-height: 200px;
  background-color: pink;
}

将行高和高度均设置在父元素身上也是可行的。

.parent {
  width: 200px;
  height: 200px;
  line-height: 200px;
  border: 1px solid red;
}

块级元素

行内块元素

可以给行内块元素,添加一个兄弟元素,将这个兄弟元素的高度设置和父元素高度一致,字体大小设置为0.

.parent {
  width: 400px;
  height: 400px;

  border: 1px solid red;
}
.child,.brother {
  display: inline-block;;
  vertical-align: middle;
}
.child {
  background: blue;
  font-size: 12px;
}
.brother {
  height: 400px;
  font-size: 0;
}
  <div class="parent">
    <div class="child">child</div>
    <div class="brother">brother</div>
  </div>

flex布局

只需给父元素设置display:flex和align-items: center即可。

display: flex;
align-items: center;

绝对定位 + left/top/right/bottom + margin: auto

子级绝对定位,父级相对定位,同时给自己的四个定位边置为0,然后设置为,margin: auto即可。

.parent {
  position: relative;
  width: 400px;
  height: 400px;
  border: 1px solid red;
}

.child {
  width: 200px;
  height: 100px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0; 
  margin: auto;
  background: blue;
  font-size: 12px;
}

table-cell + vertical-align

这种垂直居中方法只需给父元素设置display: table-cell,同时设置vertical-align:middle即可。

.parent {
  width: 400px;
  height: 400px;
  border: 1px solid red;
  display: table-cell;
  vertical-align: middle;
}

.child {
  width: 200px;
  height: 100px;
  background: blue;
}

子绝对父相对 + margin偏移

这种定位,首先需要子绝父相,然后通过margin进行偏移,缺点是需要知道宽高才可以。

.parent {
  width: 400px;
  height: 400px;
  border: 1px solid red;
  position: relative;
}

.child {
  width: 200px;
  height: 100px;
  background: blue;
  position: absolute;
  top: 50%;
  margin-top: -50px;
}

自绝对父相对 + transform

子元素设置绝对定位,父元素设置相对定位,然后通过transform进行平移偏移量。

.parent {
  width: 400px;
  height: 400px;
  border: 1px solid red;
  position: relative;
}

.child {
  width: 200px;
  height: 100px;
  background: blue;
  position: absolute;
  top: 50%;
  transform: translate(0,-50%);
}

借助伪元素

给父元素内部设置before伪元素,这个伪元素的高度设置为100%,内容设置为空,并设置为行内块元素,然后设置行内垂直对齐。子元素也要设置为行内块元素,行内垂直对齐。

.parent {
  width: 400px;
  height: 400px;
  border: 1px solid red;
  text-align: center;
}

.child {
  width: 200px;
  height: 100px;
  background: blue;
  display: inline-block;
  vertical-align: middle;
}
.parent::before {
  height: 100%;
  content: '';
  display: inline-block;
  vertical-align: middle;
}

三、垂直水平居中

不定宽高

注意:这里的不定宽高指的是子元素的宽高不知道,并不是父元素的不知道。

方式1:绝对定位 + transform

  • HTML结构
  <div class="parent">
    <div class="child">child</div>
  </div>
  • CSS样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      position: relative;
    }
    .child {
      position: absolute;
      background: yellow;
      left: 50%;
      top: 50%;
      transform: translate(-50%,-50%);
    }
  </style>

方式2:table-cell布局

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: table-cell;
      text-align: center;
      vertical-align: middle;
    }
    .child {
      background: yellow;
      display: inline-block;
    }
  </style>

方式3:flex布局

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .child {
      background: yellow;
    }
  </style>

方式4:flex + margin:auto

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: flex;
    }
    .child {
      margin: auto;
      background: yellow;
    }
  </style>

方式5:grid布局 + flex布局

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: grid;
    }
    .child {
      background: yellow;
      align-self: center;
      justify-self: center;
    }
  </style>

方式6:grid布局 + margin: auto

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: grid;
    }
    .child {
      background: yellow;
      margin: auto
    }
  </style>

定宽高

注意:这里的定宽高指的是子元素的宽高是已知的。

方式1:绝对定位 + 负margin值

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • CSS样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      position: relative;
    }
    .child {
      background: yellow;
      position: absolute;
      width: 100px;
      height: 100px;
      left: 50%;
      top: 50%;
      margin-left: -50px;
      margin-top: -50px;
    }
  </style>

方式2:绝对定位 + transform (定宽/不定宽 通用)

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • CSS样式
.parent {
  width: 200px;
  height: 200px;
  border: 1px solid red;
  position: relative;
}
.child {
  background: yellow;
  position: absolute;
  width: 100px;
  height: 100px;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}

方式3:绝对定位 + left/top/right/bottom + margin: auto

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • css样式
  <style>
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      position: relative;
    }
    .child {
      background: yellow;
      position: absolute;
      width: 100px;
      height: 100px;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
    }
  </style>

方式4:flex布局(定宽高和不定宽高:通用)

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • CSS样式
    .parent {
      width: 200px;
      height: 200px;
      border: 1px solid red;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .child {
      background: yellow;
      width: 100px;
      height: 100px;
    }

方式5:grid布局 + margin: auto(通用)

  • HTML样式
<div class="parent">
   <div class="child">child</div>
</div>
  • CSS样式
.parent {
  width: 200px;
  height: 200px;
  border: 1px solid red;
  display: grid;
}
.child {
  background: yellow;
  width: 100px;
  height: 100px;
  margin: auto;
}

方式6:table-cell布局(通用)

  • HTML样式
  <div class="parent">
    <div class="child">child</div>
  </div>
  • CSS样式
.parent {
  width: 200px;
  height: 200px;
  border: 1px solid red;
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}
.child {
  background: yellow;
  width: 100px;
  height: 100px;
  display: inline-block;
}

四、图片居中的方法

关于图片的垂直水平居中,可以参考上文提到的几种通用垂直水平居中的方法,原理是一样的。

  • 绝对定位 + transform

  • flex布局

  • grid布局 + margin: auto

  • table-cell布局

五、自适应垂直水平居中

  • 方式1:绝对定位 + left/top/right/bottom + margin: auto

  • 方式2:绝对定位 + transform

  • 方式3:flex布局