简介
CSS布局可以分为几大块,
- 盒子内部布局
·文本布局
·盒模型本身的布局 - 盒子之间的布局
·脱离正常流的布局
·absolute布局上下文下的布局
·float布局上下文下的布局
·正常流下的盒子布局
BFC布局上下文下的布局
IFC布局上下文的布局
table布局上下文下的布局
css grid布局上下文下的布局
具体内容
一、文本的水平垂直居中
line-height + text-align:center
<div class='wrap'>
水平垂直居中水平垂直居中
</div>
html,body{
margin: 0;
}
.wrap{
line-height: 400px;
text-align:center;
height: 400px;
font-size: 36px;
background-color: #ccc;
}
*适用范围:单行文字的水平垂直居中
二、利用盒模型的水平垂直居中、
1、padding填充
<div class="wrap">
<div class="content"></div>
</div>
@wrapWidth : 400px;
.wrap{
margin-left: auto;
margin-right: auto;
margin-top: 20px;
width: @wrapWidth;
height: @wrapWidth;
background-color: #ccc;
}
.content{
@contentWidth : 100px;
width: @contentWidth;
height: @contentWidth;
padding: (@wrapWidth - @contentWidth) / 2;
background-color: #333;
background-clip:content-box;
}
2、margin填充
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
@wrapHeight : 400px;
@contenHeight : 100px;
overflow: hidden;
width: 100%;
height: @wrapHeight;
background-color: #ccc;
.ele{
margin-left: auto;
margin-right: auto;
margin-top: (@wrapHeight - @contenHeight) / 2;
width: 100px;
height: @contenHeight;
background-color: #333;
color: #fff;
}
}
使用margin填充需要知道元素的宽度,这点不太灵活,不过css3出了一个fit-content的属性值,可以动态计算元素的宽度。
三、absolute布局上下文下的水平垂直居中
1、50% +- 50%
原理很简单,就是利用left:50%将盒子的左边先置于父容器的中点,然后再将盒子往左边偏移盒子自身宽度的50%,这里有三种具体的实现方式:
<div class="wrap">
<div class="ele margin">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>
<div class="wrap">
<div class="ele translate">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>
<div class="wrap">
<div class="ele relative">
<div class="ele-inner">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>
</div>
.wrap{
position: relative;
width: 100%;
height: 200px;
border:1px solid;
background-color: #ccc;
.ele{
position: absolute;
left: 50%;
top: 50%;
background-color: #333;
&.margin{
width: 160px;
height: 100px;
margin-left: -80px;
margin-top: -50px;
}
&.translate{
-webkit-transform:translate3d(-50%, -50%, 0);
transform:translate3d(-50%, -50%, 0);
}
.ele-inner{
position: relative;
left: -50%;
top: -50%;
width: 100%;
height: 100%;
background-color: #333;
}
&.relative{
width: 150px;
height: 100px;
background-color: transparent;
}
}
}
上面的方法中,margin方法和relative方法都需要知道元素的宽高才行(relative方法只知道高也行),适用于固定式布局,而transform方法则可以不知道元素宽度。
2、text-align:center + absolute
text-align:center本来是不能直接作用于absolute元素的,但是没有给其left等值的行级absolute元素是会受到文本的影响的。
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
text-align: center;
width: 100%;
height: 400px;
background-color: #ccc;
font-size: 0;
}
.ele{
position: absolute;
margin-left: -(100px / 2);
margin-top: (400px - 100px) / 2;
width: 100px;
height: 100px;
display: inline-block;
background-color: #333;
}
理解:text-align:center作用的是文本而不是absolute的元素,但是absolute元素为inline-block的时候,它会收到文本的影响,表面上看,这里没有文本,但是,实际上这里是有一个匿名的文本节点。这个匿名文本受到text-align影响居中了,这个时候absolute盒子的左边跟父容器的中点对齐了,所有就还需要往回移动50%,这里用的是margin-left。垂直方向是不能被操作文本的属性影响的,这里用margin-top偏移。
3、absolute + margin:auto
<div class="wrap">
<div class="ele"></div>
</div>
html,body{
width: 100%;
height: 100%;
margin: 0;
}
.wrap{
position: relative;
width: 100%;
height: 100%;
background-color: #ccc;
}
.ele{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
background-color: #333;
}
对于absolute性质的盒子,它的包含块,即上例中类名为wrap的块的宽度等于——absolute盒模型的宽度 + left + right的值,包含块的高度也是同理。让left与right为0,width为定值,margin为auto,margin-left与margin-right就会平分除去宽度剩下的宽度,让左右两边相等,达到居中。垂直方向同样道理。
这种方法能简单的做到居中,但是必须有width和height的值。
4、适用于图片居中的一个方法
<div class="wrap">
<p>
<img src="http://nec.netease.com/img/s/1.jpg" alt="" />
<img src="http://nec.netease.com/img/s/1.jpg" alt="" />
</p>
</div>
html,body{
width: 100%;
height: 100%;
margin: 0;
}
.wrap{
position:relative;
width: 100%;
height: 100%;
}
p{
position:absolute;
left:50%;
top:50%;
}
img:nth-child(1){
position:static;
visibility:hidden;
}
img:nth-child(2){
position:absolute;
right:50%;
bottom:50%;
}
这种方法主要是利用一个图片进行占位,让父容器获得高宽,从而让偏移的图片有一个参照容器做百分比计算。优点是可以不知道图片的大小,随便放张尺寸不超过父容器的图片都能做到居中。另外,兼容性好。
四、float布局上下文下的水平垂直居中
1、float + -50%
<div class="wrap">
<div class="ele">
<div class="ele-inner">居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中居<br>中居中居中居中居中居中居中居中居中居<br>中居中居中居中居中居中居中</div>
</div>
</div>
.wrap{
float: left;
width: 100%;
height: 400px;
background-color: #ccc;
.ele{
float: left;
position: relative;
left: 50%;
top: 50%;
}
.ele-inner{
position: relative;
left: -50%;
-webkit-transform : translate3d(0, -50%, 0);
transform : translate3d(0, -50%, 0);
background-color: #333;
color: #fff;
}
}
这种方法的原理是利用float属性将需要居中的元素的父元素.ele的宽度收缩,然后left:50%将.ele的左边和水平中线对齐,这个时候还没居中,还需要将其往回拉自身宽度的50%,于是.ele-inner表示真正需要水平居中的元素。它的position为relative,将其往回拉自身宽度的50%就可以了。对于垂直方向,依然是先将.ele top:50%到垂直方向中点,但是这是给.ele-inner top:50%是不起作用的,因为如果没给父元素明确高度的话,这个50%是计算不出来的,因此,就有了transform:translate3d(0,-50%,0).
2、margin-bottom:-50%
<div class="wrap">
<div class="placeholder"></div>
<div class='content'></div>
</div>
.wrap{
float: left;
width: 100%;
height: 400px;
background-color: #ccc;
@contentHeight : 100px;
.placeholder{
float: left;
width: 100%;
height: 50%;
/*居中元素.content高度一半*/
margin-bottom: -(@contentHeight / 2);
}
.content{
position: relative;
left: 50%;
transform:translate3d(-50%, 0, 0);
clear: both;
/*演示用,实际不需要定宽*/
max-width: 100px;
height: @contentHeight;
background-color: #333;
}
}
先让占位元素placeholder占据50%高度,然后给一个居中元素高度一半的负的margin-bottom,然后下面的元素只要跟着摆放救恩那个垂直居中了。水平方向就是利用translate做偏移。
五、BFC布局上下文下的水平垂直居中
详细介绍的传送门:http://div.io/topic/834?page=1#3261
六、IFC布局上下文下的水平垂直居中
display为inline性质的行级元素的布局。
1、text-align:center + vertical:middle
<div class="wrap">
<div class='placeholder'><!--占位元素,用来作为居中元素的参照物--></div>
<div class="ele"></div>
</div>
.wrap{
width: 100%;
height: 400px;
/* min-height: 400px; */
text-align:center;
font-size: 0;
background-color: #ccc;
.placeholder,
.ele{
vertical-align: middle;
display: inline-block;
}
.placeholder{
overflow: hidden;
width: 0;
min-height: inherit;
height: inherit;
}
.ele{
width: 100px;
height: 100px;
background-color: #333;
}
}
首先text-align:center让inline-block水平居中,然后给vertical-align:middle,但是仅仅给vertical-align:middle是不够的,因为此时还没有vertical-align对齐的参照物,所以就给了一个占位的inline-block,它的高度是100%。
2、text-align:center + line-height
<div class="wrap">
<div class="ele">居中居中居中居中居中居中<br>居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中</div>
</div>
.wrap{
text-align: center;
line-height: 400px;
width: 100%;
height: 400px;
background-color: #ccc;
font-size: 0;
.ele{
line-height: normal;
vertical-align: middle;
display: inline-block;
background-color: #333;
font-size: 18px;
color: #fff;
}
}
这个方法水平方向是,text-align:center就行了,至于垂直方向,起作用的就是父容器的一个line-height和居中元素的vertical-align:middle,为什么这两个属性可以让一个inline-block迟滞居中呢,这里重点是父容器在其下面产生了一个隐匿的文本节点。这个文本节点会因line-height属性的作用而拥有了一个父容器一样高的行高,此时元素有了一个vertical-align对齐的参照物,再给其vertical-align:middle值就能垂直对齐了。
3、text-align:center + font-size
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
text-align: center;
font-size: 400px * 0.873;/*约为高度的0.873*/
margin-left: auto;
margin-right: auto;
width: 400px;
height: 400px;
background-color: #ccc;
.ele{
vertical-align: middle;
width: 100px;
height: 100px;
display: inline-block;
background-color: #333;
}
}
这个方法就是将line-height换成了font-size.
七、FFC布局上下文下的水平垂直居中
1、父元素、子元素都定义flex
<div class="wrap">
<div class="ele">
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中
</div>
</div>
html,body{
width: 100%;
height: 100%;
}
.wrap{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: #ccc;
.ele{
background-color: #333;
}
}
2、只有父元素定义flex,子元素定义margin:auto
<div class="wrap">
<div class="ele">
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中
</div>
</div>
html,body{
width: 100%;
height: 100%;
}
.wrap{
display: flex;
width: 100%;
height: 100%;
background-color: #ccc;
.ele{
margin:auto;
background-color: #333;
}
}
margin:auto在这里垂直方向也生效了。
八、table布局上下文下的水平垂直居中
<div class='wrap'>
<div class='ele'>
<div class="ele-inner">居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中居中居中</div>
</div>
</div>
.wrap{
width: 100%;
height: 300px;
display: table;
background-color: #ccc;
}
.ele{
text-align:center;
vertical-align: middle;
display:table-cell;
}
.ele-inner{
display: inline-block;
background-color: #333;
}
原理是把div模拟成表格,然后给那几个属性就可以了。
九、CSS grid布局上下文下的水平垂直居中
十、button标签居中
<button>
<div>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
</div>
</button>
button{
width: 100%;
height: 400px;
background-color: #cccccc;
border-width:0;
&:focus{
outline:none;
}
div{
display: inline-block;
font-size: 18px;
background-color: #333;
color: #fff;
}
}
黑科技!!