CSS 居中 完整指南

541 阅读6分钟

CSS居中是CSS应用中的一个典型代表,很多人抱怨它,为什么这么难?但是我认为这个问题并不是很难,而是因为有很多方式可以实现它。

1. 水平居中 

1.1 行内元素或者inline-*元素(比如text或者link)

使用以下代码在块级父元素内将行内元素水平居中:

.center-children {
  text-align: center;
}  // 写在块级父元素CSS中

对inline, inline-block, inline-table, inline-flex等也是有效的

1.2 块级元素

设置块级元素的margin-left和margin-right为auto来居中,块级元素本身要具有固定的宽度,否则将占满整个屏幕,不需要居中。

.center-me { 
   margin: 0 auto;
   width: 300px; // 设置块级元素宽度
 } 

无论居中的块级元素或父级元素的宽度如何,都可以使用。

请注意,不能将元素浮动到中心(使用float)

1.3 多个块级元素

如果有两个或多个需要在水平方向上居中放置的块级元素,则最好为它们提供不同的显示类型(display type)。

HTML

<main class="inline-block-center">   
   <div>块级元素1</div>     
   <div>块级元素2 可以选择展示更多的内容, ‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>   
   <div>块级元素3</div>    
</main>  

 <main class="flex-center">    
  <div>块级元素1</div>    
  <div>块级元素2 可以选择展示更多的内容,‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>    
  <div>块级元素3</div>   
 </main>

CSS

main {
  background: white;
  margin: 20px 0;
  padding: 10px;
}

main div {
  background: black;
  color: white;
  padding: 15px;
  max-width: 125px;
  margin: 5px;
} 

.inline-block-center { 
   text-align: center;
  }

.inline-block-center div {  
   display: inline-block; 
   text-align: left;
  }

.flex-center {  
   display: flex; 
   justify-content: center;
  }

除非要把多个块级元素相互堆叠,否则自动边距(auto margin)技术仍然可以使用。

HTML

 <main> 
    <div>块级元素1 独自占一行</div>   
    <div>块级元素2 可以选择展示更多的内容, ‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>    
    <div>块级元素3 独自占一行</div> 
 </main> 

CSS

main { 
   background: white; 
   margin: 20px 0; 
   padding: 10px; 
 }

 main div { 
   background: black; 
   margin: 0 auto;  
   color: white; 
   padding: 15px; 
   margin: 5px auto;
 }

 main div:nth-child(1) {  
   width: 200px;
 }

 main div:nth-child(2) {  
   width: 400px;
 }

 main div:nth-child(3) { 
   width: 125px;
 }

2. 垂直居中 

2.1.行内元素或者inline-*元素(比如text或者link)

<1>单独一行

有时inline或者text元素可以垂直居中显示,只是因为它们的padding-top和padding-bottom相同。

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}

如果出于某些原因,无法选择padding属性,并且想要将一些不需要换行(wrap)的文本(text)居中,可以选择把行高(line-height)设置为与元素高度相同,使文本居中。

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

<2>多行

padding-top和padding-bottom相同也可以使多行的文本居中。

但是如果padding相同的方法行不通,则文本可能是一个表格单元中,无论这个表格单元是还是通过CSS创建的。

在这种情况下,使用vertical-align属性可以处理此问题,这与通常处理行中需要对齐元素时,使用的对齐方式不同。

HTML

<table>
  <tr>
    <td>
      在实际表格单元格中将多行文字垂直居中。
    </td>
  </tr>
</table>

<div class="center-table">
  <p>在CSS创建的表格布局中的多行文本垂直居中。</p>
</div>

CSS

table {
  background: white;
  width: 240px;
  border-collapse: separate;
  margin: 20px;
  height: 250px;
}

table td {
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  /* default is vertical-align: middle; */
}

.center-table {
  display: table;
  height: 250px;
  background: white;
  width: 240px;
  margin: 20px;
}
.center-table p {
  display: table-cell;
  margin: 0;
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  vertical-align: middle;
}

如果出现类似表格的,可以使用flexbox。 可以很容易地使单个flex-child居中在flex-parent中。

HTML

<div class="flex-center"> 
 <p>在flexbox容器中将多行文本垂直居中。</p>
</div>

CSS

div {  
  background: white;  
  width: 240px;  
  margin: 20px;
}
.flex-center {
  background: black; 
  color: white;  
  border: 10px solid white;  
  display: flex;  
  flex-direction: column;  
  justify-content: center;  
  height: 200px;  resize: vertical;   
  overflow: auto;
}
.flex-center p {  
  margin: 0; 
  padding: 20px; 
}

请记住,只有父容器的高度固定(px,%等)才真正重要。

如果这两些方法都不可行,则可以采用“ghost element”,其中将满高的伪元素(height: 100%)放置在容器内,并使文本与之垂直对齐。

HTML

<div class="ghost-center">  
  <p>在容器中垂直居中放置多行文本。 以幽灵伪元素(ghost pseudo element)为中心</p>
</div>

CSS

div {  
  background: white;  
  width: 240px;  
  height: 200px;  
  margin: 20px;
  color: white;
  resize: vertical;
  overflow: auto;
  padding: 20px;
}
.ghost-center { 
  position: relative;
}
.ghost-center::before { 
   content: " "; 
   display: inline-block; 
   height: 100%;
   width: 1%; 
   vertical-align: middle;
}
.ghost-center p {
   display: inline-block;  
   vertical-align: middle; 
   width: 190px;  
   margin: 0;  
   padding: 20px;  
   background: black;
}

2.2块级元素

<1>知道元素高度

知道元素高度,可以像这样垂直居中:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; 
  /* account for padding and border if not using box-sizing: border-box; */
}

HTML 

    <main>        <div>            我是一个具有固定高度的块级元素,在我的父元素中垂直居中。        </div>   </main>

CSS

main {  background: white;  height: 300px;  margin: 20px;  width: 300px;  position: relative;  resize: vertical;  overflow: auto;}main div {  position: absolute;  top: 50%;  left: 20px;  right: 20px;  height: 100px;  margin-top: -70px;  background: black;  color: white;  padding: 20px;}

<2>不知道元素高度

不知道网页布局中的高度是很常见的。

原因有很多,例如

  • 如果宽度改变,文本重排可以改变高度。
  • 文本样式的变化可以改变高度。
  • 文本量的变化可以改变高度。
  • 具有固定纵横比的元素(如图像)可以在调整大小时改变高度。

仍然可以通过在将其向下一半后将其向上推到一半高度来将其居中:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

<3>元素是否拉伸了容器的高度

 如果不关心元素是否拉伸了容器的高度,只需要垂直居中的内容,使用表格或 CSS 显示将元素变成表格就可以了。

HTML

<main>
  <div>
     我是一个高度未知的块级元素,在我的父元素中垂直居中。
  </div>
</main>

CSS

main {
  background: white;
  height: 300px;
  margin: 20px;
  width: 300px;
  position: relative;
  padding: 20px;
  display: table;
}
main div {
  background: black;
  color: white;
  padding: 20px;
  display: table-cell;
  vertical-align: middle;
}

<4>使用flexbox

flexbox 中要容易得多

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

3.水平垂直居中

可以以任何方式组合上述方案以获得水平垂直居中。 发现这通常分为三个方案:

3.1 元素有固定的宽高

使用等于该宽度和高度一半的负边距,在将其绝对定位在 50% / 50% 后,将使其居中并具有强大的跨浏览器支持:

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

  position: absolute;
  top: 50%;
  left: 50%;

  margin: -70px 0 0 -170px;
}

HTML

 <main>     <div>         我是一个块级元素,具有固定的高度和宽度,在我的父元素中垂直居中。     </div>       </main>

CSS

main {
  position: relative;
  background: white;
  height: 200px;
  width: 60%;
  margin: 0 auto;
  padding: 20px;
  resize: both;
  overflow: auto;
}

main div {
  background: black;
  color: white;
  width: 200px;
  height: 100px;
  margin: -70px 0 0 -120px;
  position: absolute;
  top: 50%;
  left: 50%;
  padding: 20px;
}

3.2 元素没有固定的宽高

如果不知道宽度或高度,可以使用 transform 属性和在两个方向上 50% 的负平移(它基于元素的当前宽度/高度)到中心:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

3.3使用flexbox

要使用 flexbox 在两个方向上居中,需要使用两个居中属性:

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

4.4 使用grid

这只是一个小技巧,几乎适用于一个元素:

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}

HTML

   <div class="center-me">        我是中心    </div>

CSS

body, html {
  height: 100%;
  display: grid;
}
.center-me {
  margin: auto;
}