1. 简介
居中是我们平常遇到的很常见的一种布局方式,主要分为水平居中,垂直居中,水平垂直居中。每种情况又分为,已知宽度,不知宽度,对块级元素居中,对行内替换元素水平居中,对行内非替换元素水平居中等等。本来我按照这个分类写好了一篇文章,但是觉得太偏理论分类,不好理解。于是我换个角度重新来写,从需求的角度来分析。那就是什么时候我们需要水平居中。
2. 文本水平居中
这应该是最常见的需求了。如何让文本实现水平居中呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>inline-know-width</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
background: gray;
text-align: center;
}
</style>
</head>
<body>
<div class="wrap">
一段文本
</div>
</body>
</html>
你一定会想到使用text-align即可。结果如下所示:
但是我们此时无法选中这段文本进行操作,比如为它设置背景。其实此处文本被视作匿名行内元素来处理。(可以看CSS进阶02-盒模型进阶)。那我们试着用一个实际的行内级元素将其包裹。如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>inline-know-width</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
background: gray;
text-align: center;
}
span {
background: blue;
}
</style>
</head>
<body>
<div class="wrap">
<span>一段文本</span>
</div>
</body>
</html>
也是水平居中。
好的,看起来很完美,行内非替换元素设置text-align: center即可。但如果我们所想要的并不只是文本呢?比如,在这个行内元素内部在放一个其他的元素呢?
答案是,除了放置文本和包含文本的行内级元素,其余情况都不行。
因为非替换行内级元素无法设置宽高,而且text-align: center设置的效果是文本居中。
所以这种方法非常简单,但只适用于有限的情况。
2. 图片居中
这应该也算是一个很常见的场景。看下面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>inline-replace</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
background: gray;
text-align: center;
}
img {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="wrap" style="font-size: 0;">
<img src="icon.jpg" alt="">
</div>
</body>
</html>
可以看到同样可以使用text-align来居中,记得设置"font-size: 0;"。这种方法也可以用于其他行内替换元素,比如input等。
3. 包含有非行内元素的元素居中
前面包含的文本和图片都是行内元素,假设现在包含有一个块级元素比如div,如何让他居中呢?这也是一个很常见的场景,一个可以包含各种内容的区域在外部区域中间。
方法1:最常见的做法就是使用margin,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>block-know-width</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
background: gray;
height: 100px;
width: 100%;
}
.inner {
background: blue;
width: 200px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="wrap">
<div class="inner">inner content</div>
</div>
</body>
</html>
这种方法可以轻易实现水平居中效果,但是有个缺点,那就是必须为inner设置宽度,因为div默认是占据整行的。
方法2:利用inline-block。
我们前面说到非替换行内级元素无法设置宽高,那么如果是使用行内块元素呢?对外利用行内布局特性居中,对内依然向块级元素一样表现。此时里面可以放置各种类型的元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>inline-know-width</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
background: gray;
text-align: center;
}
.inner {
display: inline-block;
background: blue;
}
img {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="wrap" style="font-size: 0;">
<span class="inner">
<img class="content" src="icon.jpg">
</span>
</div>
</body>
</html>
可以看到,设想正确,但是同样要注意,需要设置"font-size: 0;"防止html的空格产生的间隙。
使用这种方法有个副作用,就是内部文本也会居中,可以为内部元素设置text-align:left来消除这种副作用。
第三种方法:flex,也是最应该使用的方法。目前的兼容性已经很不错了,而且会越来越好。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
.wrap {
display: flex;
justify-content: center;
background: gray;
}
</style>
</head>
<body>
<div class="wrap">
<div style="background: blue">inner content</div>
</div>
</body>
</html>
你甚至不需要为子元素设置额外的css属性。
第四种方法: grid。和flex其实是一样的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>grid</title>
<style>
.wrap {
display: grid;
justify-content: center;
background: gray;
}
</style>
</head>
<body>
<div class="wrap">
<div style="background: blue">inner content</div>
</div>
</body>
</html>
4. 其他
其实主要就是以上三种场景,至于其他场景和实现方法我们会在水平垂直居中的文章中讨论。