超详细的CSS元素水平垂直解决方案(包含浮动元素的水平居中)

782 阅读3分钟

一般的水平&垂直居中

备注:

PC端有兼容性要求,宽高固定,推荐absolute + 负margin

PC端有兼容要求,宽高不固定,推荐css-table

PC端无兼容性要求,推荐flex

移动端推荐使用flex

0.水平居中

  • 文本居中法

    • .son {
          text-align: center;
      }
      
  • margin居中法

    • .son {
          margin: 0 auto;
      }
      

1.单行文本

等的垂直居中

  • line-height法

    • 不适用于需要换行的文本,依靠单行的line-height挤成居中。

    • .text{
      	line-height: 父容器高度;
      }
      
  • inline-block+伪元素填充法

    • .parent::after, .son{
          display:inline-block;
          vertical-align:middle;
      }
      .parent::after{
          content:'';
          height:100%;
      }
      

2.需要换行的文本以及块级元素、内联块级元素等

  • 父元素行高法

    • 只支持设置垂直居中

    • 居中元素必须设置为inline-block

    • .parent {
          width: 800px;
          height: 800px;
          background-color: aqua;
          line-height: 800px;
      }
      .son {
          display: inline-block;
          vertical-align: middle;
          line-height: 30px;
      }
      
  • 内边距法

    • 通过父元素的padding挤压内容导致垂直水平居中。
    • 适用于display:[inline|inline-block|block]
  • 模拟表格法

    • 通过表格布局,可以实现垂直水平的居中,只能适用于一个孩子元素的居中

    • .parent {
        display: table;
      }
      .son {
        display: table-cell;
        vertical-align: middle;/* 垂直居中 */
        text-align: center;/* 水平居中 */
      }
      
  • 相对定位+调整位置法

    • inline-block可以完美兼容水平垂直居中

      • div > span {
            display: inline-block;
            position: relative;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
        
    • inline无效,因为没有margin、translate特性

    • block的设置方法比较特殊,可以实现水平垂直居中

      • div.parent > div.son {
                width: fit-content;/* 确保正确的transform,类似于转换成inline-block */
                position: relative;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
        }
        
  • 子绝父相+调整位置法

    • 父元素空间不够时, 子元素可能不可见。如果子元素设置了overflow:auto, 则高度不够时, 会出现滚动条。

    • 使用transform兼容所有display(表现一致),可以调整水平垂直居中

      • .parent {
            width: 800px;
            height: 800px;
            background-color: aqua;
            position: relative;
        }
        .son {
            display: inline-block;/* [block]|[inline] */
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);/* [margin-left:-0.5宽度]| */
        }
        
    • 使用margin负值调整,需要知道待居中元素的宽度,因为是absolute,所以inline也可以设置宽度。

      • .parent {
            width: 800px;
            height: 800px;
            background-color: aqua;
            position: relative;
        }
        .son {
            display: inline-block; /* [block]|[inline] */
            width: 200px;
            height: 200px;
            position: absolute;
            left: 50%;
            top: 50%;
            margin-left: -100px;
            margin-top: -100px
        }
        
    • 使用margin: 0 auto调整,只支持水平居中,支持inline、inline-block、block

      • .parent {
            width: 800px;
            height: 800px;
            background-color: aqua;
            position: relative;
        }
        .son {
            display: inline; /* [block]|[inline] */
            position: absolute;
            width: fit-content;
            left: 0;
            right: 0;
            margin: 0 auto;
        }
        
  • flex法&box法(最佳!)

    • 2012版本,支持水平垂直居中

      • .parent {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
    • 2009版本,支持水平垂直居中

      • .parent {
            display: box;
            box-orient: horizontal;
            box-pack: center;
            box-align: center;
        }
        

3.带float元素的居中

  • 宽度确定

    • 直接使用合适宽度或'fit-content'

      嵌套再使用上述水平居中法

    • .parent{
          width:fit-content;
          margin:0 auto;
      }
      .son {
          float: left;
      }
      
  • 不定宽度

    • 父相子相定位法,支持多个float元素,详见例子

    • <style>
          .father {
              width: 100px;
              height: 100px;
              background-color: green;
              float: left;/* 使其转换为带宽度元素 */
              position: relative;
              left: -50%; /* 内部浮动元素右移50% */
          }
          .son {
              width: 100px;
              height: 100px;
              background-color: red;
              float: left;
              position: relative;/* 子绝父相 */
              left: 50%;/* 父元素右移50% */
          }
      <style>
      
      <div class="father">
      	<div class="son"></div>
      </div>
      

导航栏的案例(float元素的居中)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .clearfix:after {/*伪元素是行内元素 正常浏览器清除浮动方法*/
        content: "";
        display: block;/* clear只适用于块级元素 */
        height: 0;
        clear: both;
        visibility: hidden;
      }
      .clearfix {
        *zoom: 1; /*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
      }
        /* 父元素 */
      div.container {
        border: 1px solid rgba(0, 0, 0, 0.6);
        float: left;
        position: relative;
        left: 50%;
      }
       	/* 子元素,包含所有的浮动元素 */
      div.container > div {
        position: relative;
        left: -50%;
      }
      .left {
        width: 100px;
        height: 100px;
        background-color: rgba(0, 0, 0, 0.2);
        float: left;
      }
      .right {
        width: 100px;
        height: 100px;
        background-color: rgba(0, 0, 200, 0.2);
        float: left;
      }
      .center {
        float: left;
      }
      ul.unorder_list {
        margin: 0;
        padding: 0;
      }
      ul.unorder_list > li {
        width: 100px;
        height: 100px;
        background-color: rgba(0, 200, 0, 0.2);
        list-style: none;
        float: left;
      }
      :not(ul.unorder_list > li:last-child) {
        /* margin-right: 10px; */
      }
    </style>
  </head>
  <body>
    <div class="container clearfix">
      <div class="left"></div>
      <div class="center">
        <ul class="unorder_list">
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
        </ul>
      </div>
      <div class="right"></div>
    </div>
  </body>
</html>