文本的水平垂直居中

*对一个元素水平垂直居中,在我们的工作中是会经常遇到的,也是CSS布局中很重要的一部分,本文就来讲讲CSS水平垂直居中的一些方法。* 1. 文本的水平垂直居中
line-height + text-aligncenter
代码:
<div class='wrap'>
水平垂直居中水平垂直居中
</div>
html,body{
margin: 0;
}

.wrap{
line-height: 400px;
text-align:center;

height: 400px;
font-size: 36px;
background-color: #ccc;
}
*这种方法只适合单行文字的水平垂直居中* 2.利用盒模型的水平垂直居中 我们一般讲的盒模型都是说的块级盒的盒模型,也只有块级盒的盒模型用得多一点,块级盒块级盒又是分别由content-box,padding-box,border -box,缘盒组成的,如下图: 也就说我任一个子盒子的水平和垂直方向的边与最外面盒子的间距都是可以控制的,因此也就有如下居中方法: 填充填充 代码:
<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;
}
也可以用CSS3的计算值()动态计算: DEMO链接
<div class="wrap">
<div class="content"></div>
</div>
.wrap{
margin-top: 20px;
margin-left: auto;
margin-right: auto;
width: 400px;
height: 400px;
background-color: #ccc;
.content{
padding: -webkit-calc(~"(100% - 100px) / 2");
padding: calc(~"(100% - 100px) / 2");
width: 100px;
height: 100px;
background-color: #333;
background-clip: content-box;
}
}
注意这里我在calc中使用了一个〜“”的写法,这是少中的一个语法,告诉较少这里不被少所编译,要被被少编译了的话,css的calc函数的参数就不是100% 100像素,而是0%了。 缘填充 代码:
<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;
}
}
使用余量填充我们需要知道元素的宽度,这点不太灵活,不过CSS3搞出了一个加适合内容的属性值,可以动态计算元素的宽度,DEMO链接 使用盒模型进行布局不会产生回流,兼容也好,使用盒模型布局是一种布局思想,其实只是靠它就能实现很多视觉格式化才能实现的布局,这是另一个话题,这里不展开。 三。绝对布局上下文下的水平垂直居中 50%+ -50% 原理很简单,就是利用左:50%将盒子的左边先置于父容器的中点,然后再将盒子往左偏移盒子自身宽度的50%,这里有三种具体实现: DEMO链接
<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;
}
}
}
上面三个方法中,方法和相对余量方法都需要知道元素的宽高才行(相方法只知道高也行),适用于固定式布局,而变换方法则可以不知道元素宽高
text-aligncenter + absolute
文本aign:中心本来是不能直接作用于绝对元素的,但是没有给其留下等值的行级绝对元素是会受文本的影响的,可以参考张老师的这篇文章 DEMO链接 代码:
<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;
}
简单解释下,首先,文本对齐:中心作用的是文本而不是绝对的元素,但是,当绝对元素为内联块的时候,它会受到文本的影响,然后你可能会问这里没文本啊,我只能告诉你说这下面是有的,是个匿名的文本节点具体的这里不展开,可以参考标准,然后理解这句话: 如果内联框根本不包含字形,则它被认为包含一个支撑(零宽度的不可见字形),该元素的第一个可用字体的A和D 然后这个匿名文本由于受到文本对齐:中心影响居中了,这个时候绝对盒子的左边跟父容器的中点对齐了,所以就还需要往回拉50%,这里用的是利润率左,你也可以用其它方式拉。然后就是垂直方向的对齐,垂直方向是不能被操作文本的属性影响的,所以我这里用的是上边距来让它偏移下去。 绝对+边距:自动 代码:
<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;
}
}
关于这种布局的原理,在标准中能找到如下解释: w3c.org中有这样一句话: 确定这些元素使用的值的约束是: ‘left’+’margin-left’+’border-left-width’+’padding-left’+’width’+’padding-right’+’border-right -width’+’margin-right’+’right’=包含块的宽度 这句话话是绝对性质的盒子,它的包含块的宽度等于它的盒模型的宽度+左+右值,包含块的高度同理,盒模型包括边框,边框,填充盒,内容盒,而在这个居中方法中,.ele的左+右值是0,width是定值,width所在盒子包括了除了margin-box外的那三个框,margin都是auto值,按照上面那个公式,margin-left + margin-right的值应该等于包含块的宽度 - 左的值 - right的值 - width的值,也就是说margin-left + margin-right的值等于除了width所占宽度外的剩下宽度,拥有剩下宽度后,就是平分其宽度,以让左右两边相等,达到居中,标准中给出了答案: 如果三者都不是“自动”:如果“margin-left”和“margin-right”均为“auto”,则在额外的约束下解决方程式,即两个边距获得相等的值,除非这会使它们为负值,在这种情况下,当包含块的方向为’ltr’(’rtl’)时,将’margin-left’(’margin-right’)设置为零并解决’margin-right’(’margin-left’) 这里的“three”指的是left,width,right。如果左,右和宽都不为汽,同时margin-left和margin-right都是auto,除非特别情况,它们俩就是相等的,而这个例子中不在特殊情况之列,因此两者平分,此时达到了水平居中。而对于垂直方向的余量的自动值的计算,标准中也有如下两句话,跟水平方向的同理(这里的“三“指的是”top,height,bottom“): 垂直尺寸的使用值必须满足这个约束: ‘top’+’margin-top’+’border-top-width’+’padding-top’+’height’+’padding-bottom’+’border-bottom -width’+’margin-bottom’+’bottom’=包含块的高度 如果三个都不是“自动”:如果“margin-top”和“margin-bottom”都是“auto”,则在两个边距获得相等值的额外约束下求解方程。 垂直方向也就因此也居中了。 这种方法能简单的做到居中,但是必须有宽度和高度值 适用于图片居中的网易NEC的一个方法 DEMO链接 代码:
<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;
}
&:nth-child(2){
position:absolute;
right:50%;
bottom:50%;
}
}
}
这种方法主要是利用了一个图片进行占位,以让父容器获得高宽,从而让进行-50%偏移的图片能有一个参照容器作百分比计算。优点是可以不知道图片的大小,随便放张尺寸不超过父容器的图片上去都能做到居中。另外,兼容性好,如果是不使用第n个孩子选择器的花,IE6都是能顺利兼容的 四。浮布局上下文下的水平垂直居中 浮动+ -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;
}
}
这种方法的原理,首先是利用浮法属性将需要居中的元素的父元素.ele的宽度收缩,然后左:50%将.ele的左边和水平中线对齐,这个时候还没居中,还需要将其往回拉自身宽度的50%,于是.ele-内便是真正需要水平居中的元素,我给它一个位置:相对的,将其往回拉自身宽度的50%就行了对于垂直方向,依然是先将.ele顶部:50%到垂直方向中点,但是这时给.ele-inner top:50%是不起作用的,因为如果没给父元素明确高度的话,这个50%是计算不出来的,因此,就有了transform:translate3d(0,-50%,0)。 这种方法的好处是元素可以不定宽,任何时候都可以做到居中 我当时在w3cplus的站上发现这个方法后,当时觉得这个方法很好,兼容性好,又还可以不定宽,但当我用了一段时间后,发现了一个问题: 就是当居中元素的父元素左:50%时,如果元素宽度足够大,会超出外面的容器,而如果外面的容器又正好是溢出:汽车的话,那就会在外面产生滚动条,问题DEMO链接在这里,后来我找到了一个办法:DEMO链接,基本思想就是利用元素超出父元素的左边不会产生滚动条的特性,有点奇幻技巧,但是能解决问题,有兴趣的可以看看 边际底线:-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%的高度,然后给一个居中元素高度一半的负的边距,然后下面的元素只要跟着摆放就能垂直居中了。水平方向就是利用翻译做偏移,这个没什么好说的,你也可以换成其他办法。 这种方法就是各种固定死,首先最外层的父容器需要一个固定高度,以让.placeholder的高度:50%有效,然后,下边距也需要固定死,而且得需要知道居中元素高度。单纯就水平方向来说,这个方法比较适合需要兼容低版本IE的固定式布局的项目,因为兼容性好。 五.BFC布局上下文下的水平垂直居中 BFC的全称是块级排版上下文,这里有篇文章对齐进行了简单的介绍,BFC布局上下文下的布局其实就是利用盒模型本身进行的布局,前面在利用盒模型布局的那一节中已经讲过了,这里就不重复了 六.IFC布局上下文下的水平垂直居中 IFC还是个什么概念呢,你可以看看官方文档,也可以简单的理解为显示为inline性质的行级元素的布局。 text-align:center + vertical-align: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;
}
}
行级元素会受到文本对齐和垂直对齐的影响,关于vertical-align,不太好理解,我多贴几篇文章:@灵感想的,张鑫旭的,MDN上的,css-trick上的,以及官方文档,这里首先是用文本的中心让内联块水平居中,然后给一个垂直对齐:中间,但是仅仅给垂直对齐:中间是不够的,因为此时它还没有垂直对齐对齐的参照物,所以就给了一个占位的内联块,它的高度是100%。 这个方法对于居中元素不需要定宽高,而且元素根据垂直对齐值的不同不仅仅可以实现居中,还可以将其放在上面下面等。缺点是父元素需定高 text-align:center + line-height DEMO链接 代码:
<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;
}
}
这个方法,首先是水平方向,文本对齐:中心就行了,至于垂直方向,起作用的就是父容器的一个行高和居中元素的垂直对齐:中,为什么这两个属性可以让一个内联-block垂直居中呢,这里重点是父容器在其下面产生了一个隐匿的文本节点,这个我在上面text-align:中心+绝对那个方法的讲解中说到过了,然后这个隐藏文本节点会因行高属性的作用而拥有了一个父容器一样高的行高,此时元素有了一个垂直对齐对齐的参照物,再给其垂直对齐:中间值就能垂直对齐了。 使用这个方法,居中元素无需定宽高,但缺点是得给父容器一个固定的行高才行。 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;
}
}
这个方法来自淘宝,基本原理还是让隐匿文本节点所占据的行高等于父容器的高度,然后给居中元素一个垂直对齐:中间对齐的一个参照只是这里把定义行高值换成了定义字体大小值,让字体SIZ足够大从而让其行高等于父容器高度。为了证明这个字体大小的作用,我把居中元素换成文本 代码:
<div class="wrap">
a
</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;
}
效果:



可以看到字母一个垂直居中了,这个字母一个就对应那个隐匿文本节点

七.FFC布局上下文下的水平垂直居中
父元素,子元素都定义弹性:

代码:

<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;
}
}
只有父元素定义弯曲,子元素定义保证金:自动: 代码:
<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;
}
}
flexbox的标准中有这句话(参考链接:http://www.w3.org/TR/css-flexbox-1/#item-margins):

相邻柔性物品的边缘不会崩溃。自动边距在相应尺寸上吸收额外的空间,可用于对齐并将相邻的柔性物品分开; 请参阅使用自动边距对齐。

意思就是说flex项目的margin不会折叠,在flex-item有明确大小并且margin:auto时外边距吸收了伸缩包含块下的额外的空间,并且能被用于居中以及会让其相邻的flex item尽可能的往这个flex item所在的那一个方向靠。

参考链接:图CSS3 Flexbox属性(简体中文):Flexbox是一个非常强大的布局模块,

八。表布局上下文下的水平垂直居中
代码:

<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网布局上下文下的水平垂直居中
CSS3网格布局是IE搞出来的一个布局模块,目前似似还只有IE0和IE11支持,我没有研究过其居中的方法,有兴趣的可以看看大漠老师的介绍文章

十。其它未知归属的水平垂直居中方法
使用按钮标签

代码:

<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;
}
}

这种方法属于奇淫技巧,利用按钮标签天生外挂的这一技能对其里面的元素进行居中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值