w3ctech

CSS居中指南

CSS居中指南

@(keywords)[CSS,center,flexbox,ghost, pseudo]

[TOC]

1 水平居中 horizontally

1.1 内联元素 inline or inline-* elements

在块级父容器中让内联元素水平居中,只需设置 text-align: center;

<div class="inline-parent">
  <span class="inline-horizon-center">inline element within block-level parent element</span>
</div>
.inline-parent {
  text-align: center;
}

这种方法可以让 inline/inline-block/inline-table/inline-flex 等类型的元素实现居中.

1.2 块级元素 block level elements

1.2.1 单个块级元素 single block level element

让单个块级元素水平居中的方法:先设置块级元素的 width,赋予一个宽度;然后设置块级元素的 margin-left: automargin-right: auto

<main class="block-parent">
  <div class="block-horizon-center">I am a block level element and am centered.</div>
</main >
.block-horizon-center {
  width: 200px;
  margin-left: auto;
  margin-right: auto;
  /* U can also do this */
  margin: 0 auto;
}

无论父级容器和块级元素的宽度如何变化,都不会影响块级元素的水平居中效果

1.2.2 多个块级元素 more than one block level element

如果要让多个块级元素在同一水平线上居中,那么可以修改它们的 display: inline-block; 或者父级容器的 display: flex;

<main class="inline-block-horizon-center">
  <div>I'm an element that is block-like with my siblings and we're centered in a row.</div>
  <div>I'm an element that is block-like with my siblings and we're centered in a row. I have more content in me than my siblings do.</div>
  <div>I'm an element that is block-like with my siblings and we're centered in a row.</div>
</main>

<main class="flex-horizon-center">
  <div>I'm an element that is block-like with my siblings and we're centered in a row.</div>
  <div>I'm an element that is block-like with my siblings and we're centered in a row. I have more content in me than my siblings do.</div>
  <div>I'm an element that is block-like with my siblings and we're centered in a row.</div>
</main>
main div {
  max-width: 125px;
}
.inline-block-horizon-center {
  text-align: center;
}
.inline-block-horizon-center div {
  display: inline-block;
  /* U may like do this although it's not necessary */
  vertical-align: middle/top;
}
.flex-horizon-center {
  display: flex;
  justify-content: center;
}

如果想让多个块级元素垂直堆栈的水平对齐,依然可以通过设置 margin-left: automargin-right: auto

main div {
  margin-left: auto;
  margin-right: auto;
  /* U can also do this */
  margin: 0 auto;
}
main div:nth-child(1) {
  width: 200px;
}
main div:nth-child(2) {
  width: 400px;
}
main div:nth-child(3) {
  width: 125px;
}

2 垂直居中 vertically

2.1 内联元素 inline or inline-* elements

2.1.1 单行 single line

  • 方法1:设置内联元素的块级父容器的 heightline-height 值相等

    <div class="single-inline-parent">
    I'm a centered single line.
    </div>
    
    .single-inline-parent {
    height: 30px;
    line-height: 30px;
    white-space: nowrap; /* 强制不换行 */
    overflow: hidden; /* 文本溢出时隐藏 */
    text-overflow: ellipsis; /* 溢出内容为省略号 */
    }
    
  • 方法2:对于单行的内联元素,也可以添加等值的 padding-toppadding-bottom 实现垂直居中

    <main>
    <span class="single-inline-vertical-center">We're</span>
    <span class="single-inline-vertical-center">Centered</span>
    <span class="single-inline-vertical-center">Bits of</span>
    <span class="single-inline-vertical-center">Text</span>
    </main>
    
    main span {
    padding-top: 30px;
    padding-bottom: 30px;
    /* U can also do this */
    padding: 30px 10px;
    }
    

2.1.2 多行 multiple lines

2.1.2.1 多行不定高
  • 方法1:对于多行的内联元素,也可以添加等值的 padding-toppadding-bottom 实现垂直居中
    <div>
    <span class="multi-line-vertical-center">
      I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.
    </span>
    </div>
    
    .multi-line-vertical-center {
    padding-top: 30px;
    padding-bottom: 30px;
    /* U can also do this */
    padding: 30px 10px;
    overflow: hidden;
    }
    
  • 方法2:使用 flexbox 实现垂直居中,因为对于父级容器为 display: flex 的元素来说,它的每一个子元素都是垂直居中的
    <div class="flex-center">
    <p>I'm vertically centered multiple lines of text in a flexbox container.</p>
    </div>
    
    .flex-center {
    display: flex;
    justify-content: center;
    width: 240px;
    }
    
  • 方法3:幽灵元素(ghost element) 的非常规解决方式:在垂直居中的元素上 添加伪元素,设置伪元素的 height 等于父级容器的 height,然后为文本添加 vertical-align: middle;,即可实现垂直居中
    <div class="ghost-center">
    <p>I'm vertically centered multiple lines of text in a container. Centered with a ghost pseudo element</p>
    </div>
    
    .ghost-center {
    position: relative;
    }
    .ghost-center::before {
    content: " ";
    display: inline-block;
    height: 100%;
    width: null;
    vertical-align: middle;
    }
    .ghost-center p {
    display: inline-block;
    vertical-align: middle;
    /* if this don't work, maybe U should set width like width: 100px; */
    }
    
2.1.2.2 多行定高
  • 方法1:使用 flexbox 实现垂直居中,因为对于父级容器为 display: flex 的元素来说,它的每一个子元素都是垂直居中的
    <div class="flex-center">
    <p>I'm vertically centered multiple lines of text in a flexbox container.</p>
    </div>
    
    .flex-center {
    display: flex;
    justify-content: center;
    flex-direction: column; /* 固定高度必须设置flex-direction */
    width: 240px;
    height: 200px;
    }
    
  • 方法2:为文本设置一个类似 table-cell 的父级容器,然后使用 vertical-align 实现垂直居中 NOTE: IE8- 版本无效
    <div class="center-table">
    <p>I'm vertically centered multiple lines of text in a CSS-created table layout.</p>
    </div>
    
    .center-table {
    display: table;
    width: 240px;
    height: 250px;
    }
    .center-table p {
    display: table-cell;
    vertical-align: middle;
    }
    

2.2 块级元素 block level elements

2.2.1 已知元素的高度 know the height of the element

先让元素 绝对定位 到父容器的中心点,然后设置 负向margin,负值的大小为其自身高度的一半 NOTE: 如果父元素设置了padding,则计算 负向margin 时,负值的大小为:其自身高度的一半再加上父元素的内边距

<main>  
  <div>
    I'm a block-level element with a fixed height, centered vertically within my parent.
  </div>
</main>
main {
  position: relative;
}
main div {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}

2.2.2 未知元素的高度 unknow the height of the element

如果我们不知道块级元素的高度,那么就需要先将元素定位到容器的 中心位置,然后使用 transformtranslate 属性,将元素的中心和父容器的 中心重合,从而实现垂直居中

<main>
  <div>
    I'm a block-level element with an unknown height, centered vertically within my parent.
  </div>
</main>
main {
  position: relative;
}
main div {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

2.2.3 使用flexbox

<main>
  <div>
    I'm a block-level element with an unknown height, centered vertically within my parent.
  </div>
</main>
main {
 display: flex;
 flex-direction: column;
 justify-content: center;
}

3 水平且垂直居中 horizontally & vertically

3.1 元素的宽高固定 fixed width and height

设定父容器为相对定位,设定子元素为绝对定位,将子元素定位到父容器的中心点,然后使用 负向margin ,margin 的值为其自身宽高的一半 NOTE: 如果父元素设置了 padding,则计算 负向margin 时,值为:其自身宽度/高度的一半再加上父元素的内边距

<main>
  <div>
    I'm a block-level element with fixed height and width, centered vertically within my parent.
  </div>
</main>
main {
  position: relative;
}
main div {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 100px;
  margin: -50px 0 0 -100px;
 /* U can also do this */
  margin-top: -50px;
  margin-left: -100px;
}

3.2 元素的宽高不固定 unknown width and height

设定父容器为相对定位,设定子元素为绝对定位,将子元素定位到父容器的中心点,不同的是,接下来需要使用 transform: translate(-50%, -50%); 实现垂直居中

<main>
  <div>
    I'm a block-level element with unknown height and width, centered vertically within my parent.
  </div>
</main>
main {
  position: relative;
}
main div {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

使用 transform 有一个缺陷,就是当计算结果含有小数时(比如 0.5),会让整个元素看起来是模糊的,一种解决方案就是设置父级元素的 transform-style: preserve-3d;

main {
  -webkit-transform-style: preserve-3d;
     -moz-transform-style: preserve-3d;
          transform-style: preserve-3d;
}
main div {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

3.3 使用flexbox

<main>
  <div>
    I'm a block-level element with unknown width and height, centered vertically within my parent.
  </div>
</main>
main {
  display: flex;
  justify-content: center;
  align-items: center;
}

@@author GreenMelon caigua 陈灿坚 @吾南蛮野人 1270155919 @@date 2015-09-02 01:05 @@reference

  1. Centering in CSS: A Complete Guide
  2. CSS居中完整指南
  3. 解读CSS布局之水平垂直居中
w3ctech微信

扫码关注w3ctech微信公众号

共收到1条回复

  • 竟然把transform都用上了。。。

    > 使用 transform 有一个缺陷,就是当计算结果含有小数时(比如 0.5),会让整个元素看起来是模糊的,一种解决方案就是设置父级元素的 transform-style: preserve-3d;

    这是什么原理?

    回复此楼