实现水平垂直居中

前言

大家好,这里是藤原豆腐店,实现水平垂直居中是前端面试中经常会问的问题,下面我总结了常见的九种实现方法。

absolute + transform

该方法也适用于子元素是行内元素、行内块元素、块元素,适用性比较广。

实现原理是因为 position: absolute; 和 float 属性会隐式地改变元素的 display 类型(display: none;除外)。只要设置了 position: absolute; 和 float 属性中的一个,都会让元素以 display: inline-block; 的方式出现。

transform的translate属性可以设置百分比,其是相对于自身的宽和高,所以可以将translate设置为-50%,就可以做到居中了

xml 复制代码
<style>
    /* 定位代码 */
    .wrap {
      width: 400px;
      height: 300px;
      background-color: lightcoral;
      position: relative;
    }
    .inner { 
      background-color: lightblue;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
</style>
<div class="wrap">
  <span class="inner"></span>
</div>

只实现垂直居中的话

xml 复制代码
<style>
    /* 定位代码 */
    .wrap {
      position: relative;
    }
    .inner {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateY(-50%);
    }
</style>
<div class="wrap">
  <span class="inner"></span>
</div>

absolute + margin负值

该方法也适用于子元素是行内元素、行内块元素、块元素,缺点是需要知道子元素的宽高, margin-left和margin-top的值分别负的是宽和高的一半

xml 复制代码
<style>
    .wrap {
      width: 400px;
      height: 300px;
      background-color: lightcoral;
      position: relative;//给父元素增加相对定位
    }
    .inner {
      height: 100px;
      width: 100px;
      position: absolute;;
      top: 50%;
      left: 50%;
      /*  以盒子左上角作为定位  */
      /*  设置margin使其偏移  */
      margin-left:-50px;
      margin-top:-50px;
    }
</style>
<div class="wrap">
  <span class="inner"></span>
</div>

只设置垂直居中的话

xml 复制代码
<style>
    .wrap {
      width: 400px;
      height: 300px;
      background-color: lightcoral;
      position: relative;//给父元素增加相对定位
    }
    .inner {
      height: 100px;
      width: 100px;
      position: absolute;;
      top: 50%;
      margin-top:-50px;//高度/2
    }
</style>
<div class="wrap">
  <span class="inner"></span>
</div>

absolute+calc

原理同上一样,利用calc计算好元素的left和top从而保证了元素的水平垂直居中

该方法也适用于子元素是行内元素,行内块元素,块元素,唯一的要求是子元素的高度和宽度已知

xml 复制代码
<style>
  .wrap{
    width: 400px;
    height: 300px;
    background-color: lightcoral;
    position: relative;
  }
  .inner{
    background-color: lightblue;
    position: absolute;
    top: calc(50% - 40px);
    left: calc(50% - 50px);
    height: 80px;
    width: 100px;
  }
</style>
<div class="wrap">
  <span class="inner"></span>
</div>

absolute + margin auto

块级元素的特性:能独自占据父级元素一行的,而不是一列。

  • 如果不设置块级元素的 width 值,块级元素默认 width: 100%; 在水平方向上会铺满占据父级元素。
  • 但是如果不设置 height,块级元素却不会自动占据父级元素的高度

对于块级元素通过margin:auto可以使元素水平方向居中

  • 当我们设置了块级元素的宽度和 margin:auto; 表示块级元素除了本身的宽度,水平方向的剩余空间距离父元素左边和右边的 margin 自动分配,也就可以让元素水平居中。

但是在垂直方向上,块级元素不会自动扩充,它的外部尺寸没有自动充满父元素,也没有剩余空间可说。所以margin:auto不能实现垂直居中

  • 但是当我们使用了绝对定位 absolute;top: 0; bottom: 0; 的时候,元素在垂直方向有了自动充满父元素的特点。这时使用 margin: auto; 就会告诉浏览器除去元素本身的高度,那么垂直方向上的剩余空间 margin-top 和 margin-bottom 都是 auto 的,也就是平分剩余空间,从而实现元素垂直方向的居中。

该方法也适用于子元素是行内元素、行内块元素、块元素,唯一的要求是子元素要有 高度 和 宽度 。不然子元素会完全填充父元素

xml 复制代码
<style>
  .wrap{
    width: 400px;
    height: 300px;
    background-color: lightcoral;
    position: relative;
  }
  .inner{
    background-color: lightblue;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    height: 80px;
    width: 100px; 
    margin: auto;
    text-align: center;
  }
</style>
<div class="wrap">
  <span class="inner">absolute + margin:auto</span>
</div>

line-height

对于行内元素

  • 水平居中text-align:center就可以实现
  • 垂直居中就是line-height的值与height的值相等即可
xml 复制代码
<style>
    .wrap{
        width: 400px;
        height: 300px;
        line-height: 300px;
        text-align: center;
        background-color: lightcoral;
    }
</style>
<div class="wrap">
    <span>行内元素</span>
</div>

对于行内块元素

  • 需要借助vertical-align设置为middle
  • 同时子元素line-height需要重置为默认值
xml 复制代码
  <style>
      .wrap{
          width: 400px;
          height: 300px;
          line-height: 300px;
          text-align: center;
          background-color: lightcoral;
      }
      .inner{
          height: 200px; 
          width: 200px; 
          display: inline-block;
          background-color: lightblue;
          vertical-align: middle;
          font-size: 14px;
          line-height: initial;/*将行高重置为默认值*/
      }
  </style>
  <div class="wrap">
      <div class="inner">display: inline-block;</div>
  </div>

BFC+margin

如果父子元素的高度和宽度都是固定的话,可以直接利用 margin-top 和 margin-left 对子元素进行定位,从而实现居中。

同时利用 position: absolute;,让子元素成为一个 BFC,从而解决父子元素 margin collapsing 的问题。

xml 复制代码
<style>
    .container{
        background-color: silver;
        width: 400px;
        height: 500px;
    }
    .content{
        width: 200px;
        height: 300px;
        background-color: red;
        margin-top: 100px;
        margin-left: 100px;
        position: absolute;
    }
</style>
<body>
    <div class="container">
        <div class="content"></div>
    </div>
</body>

使用flex

flex布局适用于子元素是行内元素、行内块元素、块元素,适用性比较广。

css 复制代码
.wrap {
    display: flex;
    justify-content: center;
    align-items: center;
}

使用display:table-cell

设置父元素 display:table-cell用于将元素显示为表格单元格

  • 设置vertical-align: middle让行内元素或者行内块元素垂直居中
  • 设置text-align: center让行内元素或者行内块元素水平居中
xml 复制代码
<style>
    .wrap{
        width: 400px;
        height: 300px;
        background-color: lightcoral;
        display: table-cell;
        vertical-align: middle;
        text-align: center;
    }
    .inner{
        background-color: lightblue;
        display: inline-block;
        height: 110px; 
        width: 100px; 
    }
</style>
<div class="wrap">
    <div class="inner">
    </div>
</div>

使用grid

grid布局是比flex更强大的布局,通过它也是可以实现水平垂直居中

xml 复制代码
<style>
  .wrap{
    display: grid;
    justify-items: center;
    align-items: center;
    width: 400px;
    height: 300px;
    background-color: lightcoral;
  }
  .inner{
    background-color: lightblue;
    height: 110px; 
    width: 100px; 
  }
</style>
<div class="wrap">
  <div class="inner"></div>
</div>
相关推荐
快起来别睡了2 分钟前
CSS 层叠上下文:从“谁在前,谁在后”说起
css
孤月葬花魂9 分钟前
JavaScript 中的 Promise API 全面解析
前端·javascript
几道之旅10 分钟前
Electron 应用打包全指南
前端·javascript·electron
shushushu14 分钟前
Web如何自动播放音视频
前端·javascript
帅夫帅夫19 分钟前
前端存储入门:Cookie 与用户登录状态管理
前端·架构
陈随易22 分钟前
程序员的新玩具,MoonBit(月兔)编程语言科普
前端·后端·程序员
傻球25 分钟前
前端实现文本描边
前端·canvas
snakeshe101026 分钟前
1. 实现 useEffect
前端
前端进阶者29 分钟前
天地图InfoWindow插入React自定义组件
前端·javascript
Nu1137 分钟前
@babel/preset-env的corejs、@babel/plugin-transform-runtime的corejs之间区别
前端·babel