CSS面试20真题高频版-如何使元素水平垂直居中?如果元素不定宽高呢?

74 阅读2分钟

背景

在开发中经常遇到这个问题,即让某个元素的内容在水平和垂直方向上都居中,内容不仅限于文字,可能是图片其他元素

居中是一个非常基础但又是非常重要的应用场景,实现居中的方法存在很多,可以将这些方法分成两个大类:

  • 居中元素(子元素)的宽高已知
  • 居中元素(子元素)宽高未知

实现方法

  • 定位 + margin: auto
  • 定位 + margin: 负值
  • 定位 + transform
  • table布局
  • flex布局
  • grid布局 (relative:相对于初始位置;absolute:相对于上一个有定位的父元素)

定位 + margin: auto

    <div className="contentBox">
        <div>son</div>
     </div>
     
  .contentBox {
      width: 200px;
      height: 100px;
      background-color: #f55;
      position: relative;
      div {
        background: #fcc;
        width: 50px;
        height: 40px;
        line-height: 40px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
      }
    }
     

image.png

定位 + margin:负值

    .contentBox {
       width: 200px;
       height: 100px;
       background-color: #f55;
       position: relative;
       div {
            background: #fcc;
            width: 50px;
            height: 40px;
            line-height: 40px;
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -25px;
            margin-top: -20px;
        }
    }
     

定位 + transform (未知子元素宽度高度)

    .contentBox {
       width: 200px;
       height: 100px;
       background-color: #f55;
       position: relative;
       div {
            background: #fcc;
            width: 50px;
            height: 40px;
            line-height: 40px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
    }
     

table 布局

设置父元素为 display:table-cell,子元素设置 display:inline-block。利用 vertical-aligntext-align 可以让所有的行内块级元素水平垂直居中

<style>
    .father {
        display: table-cell;
        width: 200px;
        height: 200px;
        background: skyblue;
        vertical-align: middle;
        text-align: center;
    }
    .son {
        display: inline-block;
        width: 100px;
        height: 100px;
        background: red;
    }
</style>

<div class="father">
    <div class="son"></div>
</div>

flex 弹性布局

父元素 display: flexjustify-content: center(水平);align-items: center(垂直);

<style>
    .father {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 200px;
        height: 200px;
        background: skyblue;
    }
    .son {
        width: 100px;
        height: 100px;
        background: red;
    }

</style>

<div class="father">
    <div class="son"></div>
</div>

grid 网格布局

父元素display: grid;align-items:center;justify-content: center;

<style>

    .father {
        display: grid;
        align-items:center;
        justify-content: center;
        width: 200px;
        height: 200px;
        background: skyblue;
    }
    .son {
        width: 10px;
        height: 10px;
        border: 1px solid red
    }
</style>

<div class="father">
    <div class="son"></div>
</div>

如果元素不定宽高

根据元素标签性质

  • 内联元素
  • 块级元素
内联元素居中
  • 水平居中:text-align:center 或者 父元素display: flex;justify-content: center;
  • 垂直居中:单行文本父元素确认高度:height===line-height;多行文本父元素确认高度:display: table-cell; vertical-align: middle
块级元素居中
  • 水平居中 定宽: margin: 0 auto;绝对定位+left:50%+margin:负自身一半
  • 垂直居中
  1. position: absolute设置left、top、margin-left、margin-top(定高);
  2. display: table-cell
  3. transform: translate(x, y)
  4. flex(不定高,不定宽)
  5. grid(不定高,不定宽),兼容性相对比较差