对于使用CSS属性使得元素水平垂直居中问题,基本是在前端面试问题中必问的一个问题。由于这个问题的回答要分好几种情况,我也会写几篇文章分别讲述。
今天这篇文章我们首先看看,只有一个元素的时候采用绝对定位如何实现水平垂直居中的。
我已经将代码放到github上,感兴趣的同学可以去看看。
https://github.com/zhouxiongking/article-pages/blob/master/articles/position-center/position-absolute-center.html
CSS
我们假定页面只有一个div元素,目的是通过CSS属性控制该div元素的水平垂直居中。
因为这篇文章讲述的是绝对定位方法,因此要将div的position设置为absolute。为了让div的水平垂直居中看起来更形象,我们添加border属性。
通用属性
接下来我们看看两种实现方法吧。
在方法1中,我们首先需要使用margin: auto;在普通内容流中,margin: auto;相当于margin-top:0;margin-bottom:0。
其次因为div已经被设置为absolute,脱离文档流,因此可以方便设置left,top,right,bottom四个值。
将left,top,right,bottom四个之都设置为0,浏览器会重新分配一个边界框,这样整个元素就会填充body所有可用空间。
为了让元素能呈现水平垂直居中的状态,必须给div元素设置高度和宽度,添加height和width属性。
通过以上描述,我们可以得到以下的CSS属性。
css属性
通过在页面上测试,我们可以得到以下的效果。而且不管浏览器窗口大小怎么变化,这个div元素始终是水平垂直居中的状态。
方法1效果图
方法2更好理解一些,首先给div设定高度和宽度。
由于position设置为absolute;给div设定left和top属性都为50%
最后将div的margin-left和margin-top设置为宽度和高度的一半。
通过以上描述,得到以下的CSS代码。
CSS代码
通过在页面上测试,我们可以得到以下效果图。而且不管浏览器窗口大小怎么变化,这个div元素始终是水平垂直居中的状态。
方法2效果图
上述两种方法的CSS属性都未曾使用CSS3特性,因此不用担心兼容性问题。
两种方法均只需要这一个类,就可实现在任何内容块的水平垂直居中。
是否设置padding值对居中效果没有影响
元素必须设置高度和宽度,不设置的话将不会有任何效果。
由于必须设置高度,相当于定高,因此为了防止内容边界溢出,一般需要设置overflow属性。
方法的优点很明显,效果也很容易达到;但是方法缺点也是很明显的,因为有很多元素都未必是定高和定宽的。总的来说还是应该看看实际应用场景。
今天这篇文章只是讲解了,使用绝对定位让元素水平垂直居中。后面会继续讲解其他元素水平垂直居中的情况,敬请期待吧。
素分类
在讲解CSS布局之前,我们需要提前知道一些知识,在CSS中,html中的标签元素大体被分为三种不同的类型:
块状元素、内联元素(又叫行内元素)和内联块状元素。
常用的内联元素有:
<a>、<span>、<br/>、<sub>、<sup>、<label>、<b>、<i>、<u>、<del>
常用的块状元素有:
<div>、<p>、<h1>...<h6>、<ol>、<ul>、<li>、<dl>、<dt>、<dl>、<table>、<marquee>、<form>、<pre>
常用的内联块状元素(又叫行内块元素)有:
<img>、<input>
内联元素(行内)
在html中,<span>、<a>、<label>、<input>、 <img>、 <strong> 和<em>就是典型的内联元素(行内元素)(inline)元素。
当然块状元素也可以通过代码display:inline将元素设置为内联元素。如下代码就是将块状元素div转换为内联元素,从页使用div元素具有内联元素特点。
div{display:inline}
内联元素(行内)特点:
1、和其他元素都在一行上;
2、元素的高度、宽度、行高及顶部和底部边距不可设置;(padding可以设置)
3、元素的宽度就是它包含的文字或图片的宽度,不可改变。
块级元素
什么是块级元素?在html中<div>、<p>、<h1>、<form>、<ul> 和 <li>就是块级元素。
设置display:block就是将元素显示为块级元素。如下代码就是将内联元素a转换为块状元素,从而使a元素具有块状元素特点。
a{display:block;}
块级元素特点:
1、每个块级元素都从新的一行开始,并且其后的元素也另起一行。(真霸道,一个块级元素独占一行)
2、元素的高度、宽度、行高以及顶和底边距都可设置。
3、元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。
内联块状元素(行内块)
内联块状元素(inline-block)就是同时具备内联元素、块状元素的特点,
代码display:inline-block就是将元素设置为内联块状元素。(css2.1新增),<img>、<input>标签就是这种内联块状标签。
inline-block元素特点:
1、和其他元素都在一行上;
2、元素的高度、宽度、行高以及顶和底边距都可设置。
提示:下一小节是用视频动画来讲解css中的盒模型。
块元素尽量采用div嵌套, 行内元素尽量采用span嵌套
显示模式的转换
块级、行内 、行内块元素三者是可以相互转换的。
display 显示 的意思
block 块
inline 行内
块级 → 行内元素 display: inline;
<style>
div{
width:100px;
height:100px;
background-color:#036;
display:inline;
}
</style>
行内元素 → 块级元素 display: block;
<style>
a{
width:100px;
height:100px;
background-color:#960;
display:block
}
</style>
行内和块级 → 行内块 display:inline-block;
span{
width:100px;
height:100px;
background-color:#960;
didplay:inline-block;
}
水平居中设置-行内元素
如果被设置元素为文本、图片等行内元素时,水平居中是通过给父元素设置text-align:center来实现的。如下代码:
html代码:
<body>
<div class="txtCenter">我是文本,哈哈,我想要在父容器中水平居中显示。</div>
<div class="imgCenter"><img src="http://img.mukewang.com/52da54ed0001ecfa04120172.jpg" /></div>
</body>
css代码:
<style>
div.txtCenter{
text-align:center;
}
div.imgCenter{
text-align:center;
}
</style>
水平居中设置-定宽块状元素
当被设置元素为块状元素时用text-align:center就不起作用了,这时也分两种情况:定宽块状元素和不定宽块状元素。
满足定宽和块状两个条件的元素是可以通过设置"左右margin"值为"auto"来实现居中的。我们来看个例子就是设置div这个块状元素水平居中:
第一种方法
html代码:
<body>
<div>我是定宽块状元素,哈哈,我要水平居中显示。</div>
</body>
css代码:
<style>
div{
border:1px solid red;/*为了显示居中效果明显为 div 设置了边框*/
width:500px;/*定宽*/
margin:20px auto;/* margin-left 与 margin-right 设置为 auto */
}
</style>
也可以写成:
margin-left:auto;
margin-right:auto;
注意:元素的"上下margin"是可以随意设置的。这种水平居中的方法两个2个条件缺一不可
第二种方法
html代码:
<body>
<div>我是定宽块状元素,哈哈,我要水平居中显示。</div>
</body>
css代码:
<style>
div{
border:1px solid red;/*为了显示居中效果明显为 div 设置了边框*/
width:500px;/*定宽*/
position:absoute;
left:50px;
margin-left:-25px;
}
</style>
水平居中设置-不定宽块状元素
在实际工作中我们会遇到需要为"不定宽度的块状元素"设置居中,比如网页上的分页导航,因为分页的数量是不确定的,所以我们不能通过设置宽度来限制它的弹性。
不定宽度的块状元素有三种方法居中(这三种方法目前使用的都比多):
加入table标签
设置display;inline方法
设置position:relative和left:50%;
(1)第一种方法:
第一步:为需要设置的居中的元素外面加入一个table标签(包括<tbody>、<tr>、<td>)。
第二步:为这个table设置"左右margin auto"(这个和定宽块状元素的方法一样)。举例如下:
html代码:
<div>
<table>
<tbody>
<tr><td>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</td></tr>
</tbody>
</table>
</div>
css代码:
<style>
table{
margin:0 auto;
}
ul{list-style:none;margin:0;padding:0;}
li{float:left;display:inline;margin-right:8px;}
</style>
(2)第二种方法:
改变块级元素的dispaly为inline类型,然后使用text-align:center来实现居中效果。如下例子:
html代码:
<body>
<div class="container">
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</div>
</body>
css代码:
<style>
.container{
text-align:center;
}
.container ul{
list-style:none;
margin:0;
padding:0;
display:inline;
}
.container li{
margin-right:8px;
display:inline;
}
</style>
这种方法相比第一种方法的优势是不用增加无语义标签,简化了标签的嵌套深度,
但也存在着一些问题:它将块状元素的display类型改为inline,变成了行内元素,所以少了一些功能,比如设定长度值。
(2)第三种方法:
通过给父元素设置float,然后给父元素设置position:relative和left:50%,子元素设置position:relative和left:-50%来实现水平居中
代码如下:
<body>
<div class="container">
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</div>
</body>
css代码:
<style>
.container{
float:left;
position:relative;
left:50%
}
.container ul{
list-style:none;
margin:0;
padding:0;
position:relative;
left:-50%;
}
.container li{float:left;display:inline;margin-right:8px;}
</style>
这种方法可以保留块状元素仍以display:block的形式显示,优点不添加无语议表标签,不增加嵌套深度,
但它的缺点是设置了position:relative,带来了一定的副作用。
这三种方法使用得都非常广泛,各有优缺点,具体选用哪种方法,可以视具体情况而定。
隐性改变display类型
有一个有趣的现象就是当为元素(不论之前是什么类型元素,display:none除外)设置以下2个句之一:
position:absolute
float:left或float:right
元素会自动变为以display:inline-block的方式显示,当然就可以设置元素的width和height了且默认宽度不占满父元素。
如下面的代码,小伙伴们都知道a标签是行内元素,所以设置它的width是没有效果的,但是设置为position:absolute以后,就可以了。
<div class="container">
<a href="#" title="">进入课程请单击这里</a>
</div>
css代码
<style>
.container a{
position:absolute;
width:200px;
background:#ccc;
}
</style>
如何让一段文字水平居中且垂直居中
<div>水平垂直居中</div>
div{
width:200px;height:200px; /*设置div的大小*/
border:1px solid green; /*边框*/
text-align: center; /*文字水平居中对齐*/
line-height: 200px; /*设置文字行距等于div的高度*/
overflow:hidden;
}
text-align 和margin auto 区别
text-align 可以让块级元素里面的文字内容居中对齐.
文字内容==(图片 input 行内元素 行内块元素)
但是对于里面的块级元素无效
让一个块级元素居中对齐 : margin:0 auto;
【实例】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>赵丽颖的图片</title>
<style type="text/css">
body{
text-align:center; /* 所有的元素居中 */
}
div{ /*块元素的居中方法*/
width:600px;
margin:30px auto;
}
.img1{ /*行内块元素的居中方法 */
display:block;
width:600px;
margin:30px auto;
}
.img2{ /*行内块元素的居中方法 */
position:relative;
left:50%;
margin-left:-300px;
}
.form1 input{
width:200px; /*块容器包裹下的行内块元素居中方法*/
margin:10px auto;
}
.img3{ /*块容器包裹下的行内块元素居中方法*/
text-align:center;
}
</style>
</head>
<body>
<div><img src="../../photo/赵丽颖.jpeg" /></div>
<img class="img1" src="../../photo/赵丽颖.jpeg" />
<img class="img2" src="../../photo/赵丽颖.jpeg" />
<div class="form1">
<form action="" method="get" accept-charset="utf-8">
<label>电子邮箱: <input type="text" name="email" value="" placeholder="请输入电子邮箱"/></label><br/>
<label>密码: <input type="password" name="password"/></label><br/>
<label for="address">地址</label>
<input type="text" name="address" id="address" placeholder="请输入地址" />
</form>
</div>
<div class="img3">
<img src="../../photo/赵丽颖.jpeg" />
</div>
</body>
</html>
CSS布局水平居中实战
方法一:margin + width
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>css布局水平居中margin + width</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.box {
width: 100px;
margin: 0 auto;
background: red;
}
</style>
</head>
<body>
<div class="box">Demo</div>
</body>
</html>
说明:这个水平居中方法, 我们最熟悉了, 也是最常用的, width可以固定px也可以使用百分比
方法二:table + margin
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>css布局水平居中table + margin</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.box {
display: table;
margin: 0 auto;
background: red;
}
</style>
</head>
<body>
<div class="box">Demo</div>
</body>
</html>
说明:display: table在表现上类似block元素,但是宽度为内容宽。无需设置父元素样式 (支持 IE 8 及其以上版本) 兼容 IE 8 一下版本需要调整为<table>
方法三:inline-block + text-align
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>css布局水平居中inline-block + text-align</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.content {
text-align: center;
}
.box {
display: inline-block;
background: red;
}
</style>
</head>
<body>
<div class="content">
<div class="box">Demo</div>
</div>
</body>
</html>
说明:兼容性佳(甚至可以兼容 IE 6 和 IE 7)
方法四:absolute + margin-left
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>css布局水平居中absolute + margin-left</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.content {
position: relative;
}
.box {
position: absolute;
left: 50%;
width: 100px;
margin-left: -50px;
background: red;
}
</style>
</head>
<body>
<div class="content">
<div class="box">Demo</div>
</div>
</body>
</html>
说明:宽度固定相比于使用transform, 有兼容性更好
方法五:absolute + transform
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>css布局水平居中absolute + transform</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.content {
position: relative;
}
.box {
position: absolute;
left: 50%;
transform: translateX(-50%);
background: red;
}
</style>
</head>
<body>
<div class="content">
<div class="box">Demo</div>
</div>
</body>
</html>
说明:绝对定位脱离文档流, 不会对后续元素的布局造成影响。transform为 CSS3 属性, 有兼容性问题
方法六:flex + justify-content
1.1 行内元素
.parent { text-align: center; }
1.2 块级元素
1.2.1 块级元素一般居中方法
.son { margin: 0 auto; }
1.2.2 子元素含 float
.parent{ width:fit-content; margin:0 auto; } .son { float: left; }
1.2.3 Flex 弹性盒子
1) flex 2012版
.parent { display: flex; justify-content: center; }
2)flex 2009版
.parent { display: box; box-orient: horizontal; box-pack: center; }
1.2.4 绝对定位
1)transform
.son { position: absolute; left: 50%; transform: translate(-50%, 0); }
2)left: 50%
.son { position: absolute; width: 宽度; left: 50%; margin-left: -0.5*宽度 }
3)left/right: 0
.son { position: absolute; width: 宽度; left: 0; right: 0; margin: 0 auto; }
小结
以上是 CSS 水平居中的 8 种方法。
2.1 行内元素
.parent { height: 高度; } .son { line-height: 高度; }
注:① 子元素 line-height 值为父元素 height 值。② 单行文本。
2.2 块级元素
2.2.1 行内块级元素
.parent::after, .son{ display:inline-block; vertical-align:middle; } .parent::after{ content:''; height:100%; }
适应 IE7。
2.2.2 table
.parent { display: table; } .son { display: table-cell; vertical-align: middle; }
优点
缺点
2.2.3 Flex 弹性盒子
1)flex 2012版
.parent { display: flex; align-items: center; }
优点
缺点
2)flex 2009版
.parent { display: box; box-orien: vertical; box-pack: center; }
优点
缺点
2.2.4 绝对定位
1)transform
.son { position: absolute; top: 50%; transform: translate( 0, -50%); }
优点
缺点
2)top: 50%
.son { position: absolute; top: 50%; height: 高度; margin-top: -0.5高度; }
优点
缺点
3)top/bottom: 0;
.son { position: absolute; top: 0; botton: 0; margin: auto 0; }
优点
缺点
小结
以上是 CSS 垂直居中的 8 种方法及其优缺点。
链接:https://juejin.im/post/5c8f9e595188252db756920c
作者:Agoreal
*请认真填写需求信息,我们会在24小时内与您取得联系。