css中元素垂直居中和水平居中方式

1,102 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

我正在参加 码上掘金体验活动,详情:show出你的创意代码块

水平居中方案

text-align: center

text-align: center可以使行内级元素行内块级元素在父元素中水平居中

<!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>
    .container {
      width: 300px;
      height: 300px;
      background-color: #eee;
      text-align: center;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }

    .avatar {
      width: 100px;
      height: 100px;
    }
  </style>
</head>
<body>
  <div class="container">
    <!-- 这里的div是为了让span元素和img元素换行显示 -->
    <div>
      <span class="box">lorem</span>
    </div>
    <img src="https://p9-passport.byteacctimg.com/img/user-avatar/745c26f761d5ad2b65d79f98eee61a5f~300x300.image" class="avatar">
  </div>
</body>
</html>

掘金代码片段

margin: 0 auto

margin: 0 auto可以使有设置宽度的块级元素在水平方向上居中

注意: 使用margin: 0 auto让块级元素水平居中的前提条件是 块级元素有设置对应的宽度

因为块级元素默认的宽度是独占父元素的一行,此时就不存在水平居中不居中的问题了

<!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>
    .container {
      width: 300px;
      height: 300px;
      background-color: #eee;
    }

    .box {
      /* 必须设置div.box的宽度 */
      width: 100px;
      height: 100px;
      /*
        父元素的宽度 = margin-left + margin-right + div.box的宽度(contentWidth + 左右边框 + 左右边距)
      */
      margin: 0 auto;
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段

定位

使用定位来实现元素的水平居中有个前提条件: 那就是居中元素必须有固定的宽度值

<!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>
    .container {
      width: 300px;
      height: 300px;
      background-color: #eee;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      /* 使用以下方式使用div.box 水平居中 */
      /* 
      	这里可以使用相对定位也可以使用绝对定位
      	此处使用相对定位的原因是相对定位不脱标,依旧在标准流中占位
        可以有效避免后边的span元素上移
      */
      position: relative;
      left: 0;
      right: 0;
      margin: 0 auto;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
     <span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Harum, quam.</span>
  </div>
</body>
</html>

掘金代码片段

flex布局

使用flex布局来元素的水平布局存在如下的限制:

justify-content: center会使flex container下的所有flex item 全部水平居中

如果只需要某一个具体的元素水平居中,其余元素不需要水平居中的时候,使用flex布局会比较难以实现

<!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>
    .container {
      width: 300px;
      height: 300px;
      background-color: #eee;
      display: flex;
      justify-content: center;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段

left 结合 transform

使用left 结合 transform 来实现元素的水平居中是兼容性最好的一种方式

实现方式:

  1. 开启元素的定位 --- 设置left/right --- 使元素位移父元素宽度的50%
  2. 使用transform属性使元素位移居中元素自身宽度的50%
<!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>
    .container {
      width: 300px;
      height: 300px;
      line-height: 300px;
      background-color: #eee;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      position: relative;
      left: 50%;
      transform: translateX(-50%);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段

垂直居中方案

line-height 结合 height

使用line-height实现元素垂直居中对齐的局限性是需要垂直居中的元素必须是单行的文本元素

<!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>
    .container {
      width: 300px;
      height: 300px;
      /*
        当 line-height的值 等于 height的值的时候
        可以使单行文本元素在其父元素中 垂直居中对齐
      */
      line-height: 300px;
      background-color: #eee;
    }
  </style>
</head>
<body>
  <div class="container">
    Lorem ipsum dolor sit amet consectetur
  </div>
</body>
</html>

掘金代码片段

绝对定位

和使用定位来实现元素的水平居中的局限性一样,如果我们需要使用定位来实现元素的垂直居中,则该元素必须具有固定的高度

使用绝对定位来实现垂直居中的限制条件:

  1. 必须给需要垂直居中的元素设置具体的高度
  2. 必须使用绝对定位 --- 这就意味着 居中元素会脱标,可能会影响后继元素的布局方式
<!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>
    .container {
      width: 300px;
      height: 300px;
      line-height: 300px;
      background-color: #eee;
      position: relative;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      /* 使用如下属性来实现div.box 在 div.container中的垂直居中 */
      /*
        注意: 这里的定位必须是绝对定位
        因为相对定位本质上并没有脱标
        所以绝对定位和相对定位虽然都可以实现元素的水平居中
        但只有绝对定位可以实现元素的垂直居中
      */
      position: absolute;
      top: 0;
      bottom: 0;
      margin: auto 0;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段

flex布局

和使用flex布局来实现元素水平居中的局限性一样

使用align-item:center来实现元素的垂直居中对齐会导致所有的flex item全部垂直居中

如果只需要其中的部分flex item实现垂直居中对齐,可以使用align-self

<!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>
    .container {
      width: 300px;
      height: 300px;
      line-height: 300px;
      background-color: #eee;
      display: flex;
      align-items: center;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段

top 结合 transform

使用top 结合 transform 来实现元素的垂直居中是兼容性最好的一种方式

实现方式:

  1. 开启元素的定位 --- 设置top/bottom --- 使元素位移父元素高度的50%
  2. 使用transform属性使元素位移定位元素自身高度的50%
<!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>
    .container {
      width: 300px;
      height: 300px;
      line-height: 300px;
      background-color: #eee;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      /*
      	在这里 使用margin-top: 50%;可以实现相同的效果
      	但是 不推荐使用margin-top: 50%;来进行移动
      
      	因为margin-top的百分比相对的是包含块的宽度(refer to the width of the containing block)
      	包含块在这里就是div.container
      	而这里宽度和高度正好一致,所以设置margin-top为50%后,元素表现为垂直居中
      	但是如果div.container的宽度和高度不一致的时候,就无法实现元素垂直居中效果
      */
      position: relative;
      top: 50%;
      /*
      	transform的百分比相对的是自身的宽度或高度( refer to the size of bounding box )
      */
      transform: translateY(-50%);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

掘金代码片段