# 水平居中
# 1. 使用 inline-block 或者 inline 和 text-align 实现
需要居中的元素为常规流中 inline / inline-block 元素, 可以简单理解为是行内元素。
.parent {
text-align: center;
}
.child {
display: inline-block;
/* or */
/* display: inline; */
}
优点:兼容性好; 不足:需要同时设置子元素和父元素
# 2. 使用 margin:0 auto 来实现
子元素需要是定宽块状元素, 设置子元素的宽度之后设置 margin 自动。IE6 下需在父元素上设置 text-align: center。
.wrapper {
/* IE 6 下设置即可 */
text-align: center;
}
.child {
width: 200px;
margin: 0 auto;
}
优点:兼容性好 缺点: 需要指定宽度
# 3. 使用 table 实现
不定宽块状元素
.child {
display: table;
margin: 0 auto;
}
优点: 只需要对自身进行设置 不足: IE6,7 需要调整结构
# 4. 使用绝对定位实现
- 不定宽块状元素 absolute + translate
.parent {
position: relative;
}
/*或者使用 margin-left 的负值为盒子宽度的一半也可以实现,不过这样就必须知道盒子的宽度,但兼容性好*/
.child {
position: absolute;
left: 50%;
transform: translate(-50%);
/* transform: translateX(-50%); */
}
不足:兼容性差,IE9 及以上可用
- 定宽元素。 absolute + margin
.wrapper {
width: 80%;
height: 500px;
background: #888;
position: relative;
}
.center {
width: 500px;
position: absolute;
left: 50%;
margin-left: -250px;
background-color: orange;
}
<div class="wrapper">
<div class="center">
如果元素 position: absolute; 那么 0)设置父元素 position: relative 1)为元素设置宽度,2)偏移量设置为
50%,3)偏移方向外边距设置为元素宽度一半乘以-1
</div>
</div>
div {
position: relative; /* 相对定位或绝对定位均可 */
width: 500px;
height: 300px;
top: 50%;
left: 50%;
margin: -150px 0 0 -250px; /* 外边距为自身宽高的一半 */
background-color: pink; /* 方便看效果 */
}
- 定宽元素。 absolute + margin
- 为元素设置宽度
- 设置左右偏移量都为 0
- 设置左右外边距都为 auto
body {
background: #ddd;
position: relative;
}
.content {
width: 800px;
position: absolute;
margin: 0 auto;
left: 0;
right: 0;
background-color: purple;
}
<div class="content">
aaaaaa aaaaaa a a a a a a a a
</div>
- 定宽元素。 relative + margin
.wrapper {
width: 80%;
height: 500px;
background: #888;
}
.center {
width: 500px;
position: relative;
left: 50%;
margin-left: -250px;
background-color: orange;
}
<div class="wrapper">
<div class="center">
如果元素positon: relative。 那么 1)为元素设置宽度,2)偏移量设置为 50%,3)偏移方向外边距设置为元素宽度一半乘以-1
</div>
</div>
# 5. 实用 flex 布局实现
实际使用时应考虑兼容性
/*第一种方法*/
.parent {
display: flex;
justify-content: center;
}
/*第二种方法*/
.parent {
display: flex;
}
.child {
margin: 0 auto;
}
缺点:兼容性差,如果进行大面积的布局可能会影响效率
# 6. 定宽浮动元素 relative + margin-left
- 为元素设置宽度
position: relative;
- 浮动方向偏移量(left 或者 right)设置为 50%
- 浮动方向上的 margin 设置为元素宽度一半乘以-1
<div class="content">
aaaaaa aaaaaa a a a a a a a a
</div>
body {
background: #ddd;
}
.content {
width: 500px; /* 1 */
float: left;
position: relative; /* 2 */
left: 50%; /* 3 */
margin-left: -250px; /* 4 */
background-color: purple;
}
# 垂直居中
- absolute + 负 margin
- absolute + translate
- flex
- table-cell + vertical-align
# 1. 绝对定位和负边距 margin
这种方式比较好理解,兼容性也很好,缺点是需要知道子元素的宽高。
定高:margin
,position + margin
(负值)
/* 定高方案1 */
.center {
height: 100px;
margin: 50px 0;
}
/* 定高方案2 */
.center {
height: 100px;
position: absolute;
top: 50%;
margin-top: -25px;
}
# 2. 绝对定位和 0
这种方法兼容性也很好,缺点是需要知道子元素的宽高
.box4 span {
width: 50%;
height: 50%;
background: #000;
overflow: auto;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
# 3. vertical-align
vertical-align 称之为 "inline-block 依赖型元素",也就是说,只有一个元素属于 inline 或是 inline-block(table-cell 也可以理解为 inline-block 水平)水平,其身上的 vertical-align 属性才会起作用。
在使用 vertical-align 的时候,由于对齐的基线是用行高的基线作为标记,故需要设置 line-height 或设置 display:table-cell;
/*第一种方法*/
.parent {
display: table-cell;
vertical-align: middle;
height: 20px;
}
/*第二种方法*/
.parent {
display: inline-block;
vertical-align: middle;
line-height: 20px;
}
其实跟上面的一样,IFC + vertical-align:middle
/* 设置 inline-block 则会在外层产生 IFC,高度设为 100% 撑开 wrap 的高度 */
.wrap::before {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
.wrap {
text-align: center;
}
.center {
display: inline-block;
vertical-align: middle;
}
# 4. 实用绝对定位
- 使用绝对定位和 translate 移动(位移)的方式 (不需要知道元素的宽高)。使用 css3 新增的 transform,transform 的 translate 属性也可以设置百分比,其是相对于自身的宽和高,所以可以讲 translate 设置为-50%,就可以做到居中了。
这种方法兼容性依赖 translate2d 的兼容性。
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
- 使用绝对定位和 calc 具体计算出偏移量(需要知道元素的宽高)。这种方法兼容性依赖 calc 的兼容性,缺点是需要知道子元素的宽高。
.center {
width: 18em;
height: 10em;
position: absolute;
top: calc(50% - 5em);
left: calc(50% - 9em);
}
<div class="center">
要求原生有固定的宽高。<br />
position: absolute;<br />
top 为 calc(50% 剪 一半高) <br />
left 为 calc(50% 剪 一半宽)
</div>
- 使用绝对定位和负 margin 具体计算出边距的值 (需要知道宽高)。已知高度的块级子元素,采用绝对定位和负边距
.center {
width: 18em;
height: 10em;
position: absolute;
top: 50%;
left: 50%;
margin-left: -9rem;
margin-top: -5rem;
}
<div class="center">
要求原生有固定的宽高。<br />
position: absolute;<br />
top和left 为 50%;<br />
margin上为高的一半<br />
margin左为宽的一半<br />
</div>
.container {
position: relative;
}
.vertical {
height: 300px; /*子元素高度*/
position: absolute;
top: 50%; /*父元素高度50%*/
margin-top: -150px; /*自身高度一半*/
}
# 5. 实用 flex 实现
目前在移动端已经完全可以使用 flex 了,PC 端需要看自己业务的兼容性情况.
- 直接使用 flex 的两个属性水平、垂直居中一步到位
.parent {
display: flex;
/* 水平居中 */
justify-content: center;
/* 垂直居中 */
align-items: center;
}
- 父元素 flex 定位,子元素定宽并设置 margin auto
.wrapper {
width: 1000px;
height: 600px;
background: #999;
display: flex;
}
.center {
width: 18em;
height: 10em;
text-align: center;
background-color: orange;
color: #fff;
margin: auto;
}
<div class="wrapper">
<div class="center">
使用flex居中<br />
父元素 display: flex; <br />
居中块: margin: auto;
</div>
</div>
# 6. 使用 translate 和 vh 单位整个窗口垂直居中
.wrapper {
overflow: hidden;
width: 100%
height: 500px;
background: #999;
}
.center {
width: 18em;
height: 10em;
text-align: center;
background-color: orange;
color: #fff;
margin: 50vh auto;
transform: translateY(-50%);
}
<div class="wrapper">
<div class="center">
基于视口的垂直居中<br />
不要求原生有固定的宽高。<br />
但是这种居中是在整个页面窗口内居中,不是基于父元素<br />
</div>
</div>
# 7. 单行文本
- line-height 设置成和 height 值
.vertical {
height: 100px;
line-height: 100px;
}
- 需要居中元素为单行文本,为包含文本的元素设置大于
font-size
的line-height
:
<p class="text">center text</p>
.text {
line-height: 200px;
}
- vertical-align
需要是 inline-block 之类的元素
/* 把此元素放置在父元素的中部 */
vertical-align: middle;
# 8. 未知高度的块级父子元素居中,模拟表格布局
兼容性也还不错. 缺点:IE67 不兼容,父级 overflow:hidden 失效
.container {
display: table;
}
.content {
display: table-cell;
vertical-align: middle;
}
# 9. display:-webkit-box
.box9 {
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
-webkit-box-orient: vertical;
text-align: center;
}
# 10. display:-webkit-box + div 块清除浮动
.floater {
float: left;
height: 50%;
margin-bottom: -120px;
}
.content {
clear: both;
height: 240px;
position: relative;
}
<div class="floater"></div>
<div class="content">Content here</div>
# 11. writing-mode
简单来说 writing-mode 可以改变文字的显示方向,比如可以通过 writing-mode 让文字的显示变为垂直方向
<div class="div1">水平方向</div>
<div class="div2">垂直方向</div>
.div2 {
writing-mode: vertical-lr;
}
显示效果如下:
水平方向
垂
直
方
向
更神奇的是所有水平方向上的 css 属性,都会变为垂直方向上的属性,比如text-align
,通过writing-mode
和text-align
就可以做到水平和垂直方向的居中了,只不过要稍微麻烦一点
<div class="wp">
<div class="wp-inner">
<div class="box">123123</div>
</div>
</div>
/* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 */
/* 定位代码 */
.wp {
writing-mode: vertical-lr;
text-align: center;
}
.wp-inner {
writing-mode: horizontal-tb;
display: inline-block;
text-align: center;
width: 100%;
}
.box {
display: inline-block;
margin: auto;
text-align: left;
}
这种方法实现起来和理解起来都稍微有些复杂
# 12. grid
css 新出的网格布局,由于兼容性不太好,一直没太关注,通过 grid 也可以实现水平垂直居中
<div class="wp">
<div class="box">123123</div>
</div>
.wp {
display: grid;
}
.box {
align-self: center;
justify-self: center;
}
代码量也很少,但兼容性不如 flex,不推荐使用
# 总结
下面对比下各个方式的优缺点,肯定又双叒叕该有同学说回字的写法了,简单总结下
- PC 端有兼容性要求,宽高固定,推荐 absolute + 负 margin
- PC 端有兼容要求,宽高不固定,推荐 css-table
- PC 端无兼容性要求,推荐 flex
- 移动端推荐使用 flex
**小贴士:**关于 flex 的兼容性决方案,请看这里《移动端 flex 布局实战 (opens new window)》
方法 | 居中元素定宽高固定 | PC 兼容性 | 移动端兼容性 |
---|---|---|---|
absolute + 负 margin | 是 | ie6+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
absolute + margin auto | 是 | ie6+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
absolute + calc | 是 | ie9+, chrome19+, firefox4+ | 安卓 4.4+, iOS6+ |
absolute + transform | 否 | ie9+, chrome4+, firefox3.5+ | 安卓 3+, iOS6+ |
writing-mode | 否 | ie6+, chrome4+, firefox3.5+ | 安卓 2.3+, iOS5.1+ |
line-height | 否 | ie6+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
table | 否 | ie6+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
css-table | 否 | ie8+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
flex | 否 | ie10+, chrome4+, firefox2+ | 安卓 2.3+, iOS6+ |
grid | 否 | ie10+, chrome57+, firefox52+ | 安卓 6+, iOS10.3+ |
# 水平垂直居中
# 1. 利用 vertical-align,text-align,inline-block 实现
.parent {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.child {
display: inline-block;
}
# 2. 利用绝对定位实现
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
/* child 元素 x y 均移动 50% */
transform: translate(-50%, -50%);
}
# 让绝对定位的 div 居中
div {
position: absolute;
width: 300px;
height: 300px;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: pink; /* 方便看效果 */
}
# 3. 利用 flex 实现
.parent {
display: flex;
justify-content: center;
align-items: center;
}