水平居中的几种方式
1、text-align: center
text-align属性规定了元素中文本的水平对齐方式,通过指定行框与哪个点对齐,从而设置块级元素内文本的水平对齐方式,因此也可以用来实现内联元素的水平居中。
- 作用元素:文本、行内元素和行内块级元素
- 优点:简单便捷,兼容性好,所有浏览器都支持text-align属性
- 缺点:只能作用于行内元素或行内文本;属性会继承,会对后代元素的行内内容对齐方式产生影响;如果子元素宽度大于父元素宽度则无效,只有后代行内内容中宽度小于设置text-align属性的元素宽度的时候,才会水平居中。
示例:
div span {
text-align: center;
}
2、margin: 0 auto
通过margin来实现元素的水平居中的原理是根据W3C关于margin规范提出的在margin有节余的同时如果左右margin设置了auto,将会均分剩余空间,另外,如果上下的margin设置了auto,其计算值为0。
- 作用元素:确定宽度的块级元素
- 优点:简单便捷,兼容性好,所有浏览器都支持margin属性
- 缺点:只能作用于确定了宽度的块级元素,并且元素宽度必须小于父元素宽度
示例:
#container div {
width: 500px;
margin: 0 auto;
}
扩展:
使用margin: 0 auto 实现元素的水平居中的主要限制在于必须确定宽度,后来大家提出了各种方法突破这一限制:
(1)table标签(或display: table),再添加margin: 0 auto
示例:
<style id="text/css">
#container {
width: 400px;
height: 200px;
border: 1px sold red;
}
#first {
display: table;
margin: 0 auto;
background-color: green;
}
</style>
<body>
<div id="container">
<div id="first">first</div>
</div>
</body>
页面效果:
(2)CSS3中的fit-content配合margin
示例:
<style id="text/css">
#container {
width: 400px;
height: 200px;
border: 1px sold red;
}
#first {
width: fit-content;
margin: 0 auto;
background-color: green;
}
</style>
<body>
<div id="container">
<div id="first">first</div>
</div>
</body>
页面效果:
3、绝对定位
父元素采用相对定位,子元素采用绝对定位,left、right、top和bottom属性的定位是相对于父元素的,而margin、transform是相对于子元素自身尺寸的,因此组合使用可以实现元素的水平据中。
- 作用元素:如果使用margin只能作用于确定了宽度的块级元素,如果使用transform可以作用于行内元素。
- 优点:margin的兼容性好;可以实现块级元素和行内元素的水平居中。
- 缺点:子元素脱离了标准文档流;代码较多;使用margin必须制定宽度,使用transform兼容性不好(IE9+)
示例:
<!DOCTYPE html>
<html lang="en">
<header>
<meta charset="UTF-8">
<title>水平居中</title>
<style type="text/css">
#container {
width: 400px;
height: 200px;
border: 1px solid red;
position: relative;
}
#container div {
width: 200px;
height: 100px;
position: absolute;
left: 50%; /*父元素宽度的一半,此处类似于left: 200px*/
margin-left: -100px; /*自身宽度的一半*/
background-color: green;
}
</style>
</header>
<body>
<div id="container">
<div>first</div>
</div>
</body>
</html>
页面效果:
下面我们来尝试使用transform来实现未定义宽度的行内元素水平居中。
示例:
<style type="text/css">
#container {
width: 400px;
height: 200px;
border: 1px solid red;
position: relative;
}
#first {
position: absolute;
transform: translateX(-50%); /*自身宽度的一半*/
background-color: green;
left: 200px;
}
</style>
页面效果:
注:为什么我们需要把父元素的position属性设为relative呢?这是因为绝对定位中left、right、top、bottom进行定位时将元素的第一个非static定位的祖先元素作为参考原点,如果向上一直不能找到满足要求的祖先元素则会以html元素作为参考原点,此处将父元素的position属性取relative还有一个原因就是相对定位并没有脱离标准文档流,大家可以尝试给父元素position属性取其他值查看页面效果。
4、flex布局
关于flex布局的详细信息可以查看我的博客弹性盒布局
利用flex布局实现元素的水平居中的主要重点在于利用flex-direction确定主轴方向,利用父元素容器的justify-content: center实现子元素的主轴水平居中,利用父元素的align-items: center或子元素的align-self: center来实现子元素的交叉轴水平居中。
- 作用元素:可以作用于弹性盒布局中的所有弹性子元素
- 优点:功能强大,简单方便,可以响应式处理页面
- 缺点:PC端兼容性不好,移动端应用更为广泛,尤其andriod浏览器
示例:
<style type="text/css">
#container {
width: 400px;
height: 200px;
border: 1px solid red;
display: flex;
justify-content: center;
}
#first {
background-color: green;
}
</style>
页面效果:
总结:
- 对于水平居中,我们首先应该想到text-align: center;,但是text-align只能作用于行内元素,因此我们如果需要实现块级元素的水平居中可以先给元素添加属性display: inline;或display: inline-block;。
- 如果不能通过text-align: center;实现我们优先考虑margin: 0 auto;,但是margin:0 auto只能作用于已定义宽度的块级元素,因此对于未知宽度的块级元素我们可以考虑通过给元素添加display: table;或width: fit-content;。
- 如果使用text-align或margin: 0 auto;都无法实现那我们只能使用绝对定位了,通过margin可以实现已定义宽度块级元素的水平居中,通过transform可以实现未知宽度的块级元素和行内元素。
- 移动端或需要响应式布局的情形下优先考虑通过flex布局实现