Absolute盘点8种CSS实现垂直居中⽔平居中的绝对定位居中技术
Ⅰ.绝对定位居中(Absolute Centering)技术
我们经常⽤margin:0 auto来实现⽔平居中,⽽⼀直认为margin:auto不能实现垂直居中……实际上,实现垂直居中仅需要声明元素⾼度和下⾯的CSS:
.Absolute-Center{
margin: auto;
position: absolute;
top: 0;left: 0;bottom: 0;right: 0;
}
我不是这种实现⽅法的第⼀⼈,可能这只是⾮常常见的⼀种⼩技术,我⽃胆将其命名为绝对居中(Absolute Centering),虽然如此,但是⼤多数讨论垂直居中的⽂章却从来不提这种⽅法,直到我最近浏览《How to Center Anything WithCSS》这篇⽂章的评论时候才发现这种⽤法。在评论列表中Simon和Priit都提及了此⽅法。
如果你有任何扩展的功能或建议,可以在此跟帖:
CodePen
SmashingMagazine
Twitter @shshaw
优点:
1. ⽀持跨浏览器,包括IE8-IE10.
2. ⽆需其他特殊标记,CSS代码量少
3. ⽀持百分⽐%属性值和min-/max-属性
4. 只⽤这⼀个类可实现任何内容块居中
5. 不论是否设置padding都可居中(在不使⽤box-sizing属性的前提下)
6. 内容块可以被重绘。
7. 完美⽀持图⽚居中。
缺点:
1. 必须声明⾼度(查看可变⾼度Variable Height)。
2. 建议设置overflow:auto来防⽌内容越界溢出。(查看溢出Overflow)。
3. 在Windows Phone设备上不起作⽤。
浏览器兼容性:
Chrome,Firefox, Safari, Mobile Safari, IE8-10.
绝对定位⽅法在最新版的Chrome,Firefox, Safari, Mobile Safari, IE8-10.上均测试通过。
对⽐表格:
绝对居中法并不是唯⼀的实现⽅法,实现垂直居中还有些其他的⽅法,并各有各的优势。采⽤哪种技术取决于你的浏览器是否⽀持和你使⽤的语⾔标记。这个对照表有助于你根据⾃⼰的需求做出正确的选择。
Technique Browser
Support
Responsive Overflow resize:both
Variable
Height
Major Caveats
Absolute Centering Modern &
IE8+Yes
Scroll, can
overflow
container
Yes Yes*
Variable Height not perfect
cross-browser
Negative Margins All No Scroll
Resizes but doesn’t
stay centered
No
Not responsive, margins must be
calculated manually
Scroll, can
Transforms Modern &
IE9+
Yes
Scroll, can
overflow
container
Yes Yes Blurry rendering
Table-Cell Modern &
IE8+
Yes
Expands
container
No Yes Extra markup
Inline-Block
Modern,
IE8+ & IE7*
Yes
Expands
container
No Yes Requires container, hacky styles
Flexbox Modern &
IE10+
Yes
Scroll, can
overflow
container
Yes Yes
Requires container, vendor
prefixes
Technique Browser
Support
Responsive Overflow resize:both
Variable
Height
Major Caveats
解释:
通过以上描述,绝对居中(AbsoluteCentering)的⼯作机理可以阐述如下:
1、在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
W3C中写道If ‘margin-top’, or’margin-bottom’ are ‘auto’, their used value is 0.
2、position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进⾏渲染。
<:…an element that is positioned absolutely is taken out of the flow and thustakes up no space
3、为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配⼀个边界框,此时该块block将填充其⽗元素的所有可⽤空间,⽗元素⼀般为body或者声明为position:relative;的容器。
<:For absolutely positioned elements, the top, right, bottom, and left propertiesspecify offsets from the edge of the element’s containing block (what theelement is positioned relative to).
4、 给内容块设置⼀个⾼度height或宽度width,能够防⽌内容块占据所有的可⽤空间,促使浏览器根据新的边界框重新计算margin:: The margin of the[absolutely positioned] element is then positioned inside these offsets.
5、由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。
<: If none of the three [top, bottom,height] are ‘auto’: If both ‘margin-top’ and ‘margin-bottom’ are ‘auto’, solvethe equation under the extra constraint that the two margins get equal values.AKA: center the block vertically
这么看来, margin:auto似乎⽣来就是为绝对居中(Absolute Centering)设计的,所以绝对居中(Absolute Centering)应该都兼容符合标准的现代浏览器。
简⽽⾔之(TL;DR):绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0; left: 0; bottom: 0;right: 0;设置的边界内垂直居中。
居中⽅式:
⼀、容器内(Within Container)
内容块的⽗容器设置为position:relative,使⽤上述绝对居中⽅式,可以使内容居中显⽰于⽗容器。
.Center-Container{
position: relative;
}
.Absolute-Center{
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
position: absolute;
top: 0;left: 0;bottom: 0;right: 0;
}
以下其余的demo默认上⾯的CSS样式已引⽤包括进去,在此基础上只提供额外的类供⽤户追加以实现不同的功能。
⼆、视区内(Within Viewport)
想让内容块⼀直停留在可视区域内?将内容块设置为position:fixed;并设置⼀个较⼤的z-index层叠属性值。
.Absolute-Center.is-Fixed{
position: fixed;
z-index: 999;
}
注意:对MobileSafari,若内容块不是放在设置为position:relative;的⽗容器中,内容块将垂直居中于整个⽂档,⽽不是可视区域内垂直居中。
三、边栏 (Offsets)
如果你要设置⼀个固顶的头或增加其他的边栏,只需要在内容块的样式中加⼊像这样的CSS样式代码:top:70px;bottom:auto;由于已经声明了margin:auto;,该内容块将会垂直居中于你通过top,left,bottom和right属性定义的边界框内。
你可以将内容块固定与屏幕的左侧或右侧,并且保持内容块垂直居中。使⽤right:0;left:auto;固定于屏幕右侧,使⽤left:0;right:auto;固定与屏幕左侧。
.Absolute-Center.is-Right{
left: auto;right: 20px;
text-align: right;
}
.Absolute-Center.is-Left{
right: auto;left: 20px;
text-align: left;
}
四、响应式/⾃适应(Responsive)
绝对居中最⼤的优势应该就是对百分⽐形式的宽⾼⽀持的⾮常完美。甚⾄min-width/max-width 和min-height/max-height这些属性在⾃适应盒⼦内的表现也和预期很⼀致。
.Absolute-Center.is-Responsive{
width: 60%;
height: 60%;
min-width: 200px;
max-width: 400px;
padding: 40px;
}
给内容块元素加上padding也不影响内容块元素的绝对居中实现。
五、 溢出情况(Overflow)
内容⾼度⼤于块元素或容器(视区viewport或设为position:relative的⽗容器)会溢出,这时内容可能会显⽰到块与容器的外⾯,或者被截断出现显⽰不全(分别对应内容块overflow属性设置为visible和hidden的表现)。
加上overflow: auto会在内容⾼度超过容器⾼度的情况下给内容块显⽰滚动条⽽不越界。
.Absolute-Center.is-Overflow{
overflow: auto;
}
如果内容块⾃⾝不设置任何padding的话,可以设置max-height: 100%;来保证内容⾼度不超越容器⾼度。
六、重绘(Resizing)
你可以使⽤其他class类或javascript代码来重绘内容块同时保证居中,⽆须⼿动重新计算中⼼尺⼨。当然,你也可以添加resize属性来让⽤户拖拽实现内容块的重绘。
绝对居中(Absolute Centering)可以保证内容块始终居中,⽆论内容块是否重绘。可以通过设置min-/max-来根据⾃⼰需要限制内容块的⼤⼩,并防⽌内容溢出窗⼝/容器。
.Absolute-Center.is-Resizable{
min-width: 20%;
max-width: 80%;
min-height: 20%;
max-height: 80%;
resize: both;
overflow: auto;
}
如果不使⽤resize:both属性,可以使⽤CSS3动画属性transition来实现重绘的窗⼝之间平滑的过渡。⼀定要设置overflow:auto;以防重绘的内容块尺⼨⼩于内容的实际尺⼨这种情况出现。
绝对居中(AbsoluteCentering)是唯⼀⽀持resize:both属性实现垂直居中的技术。
注意:
要设置max-width/max-height属性来弥补内容块padding,否则可能溢出。
⼿机浏览器和IE8-IE10浏览器不⽀持resize属性,所以如果对你来说,这部分⽤户体验很必要,务必保证对resizing你的⽤户有可⾏的退路。
联合使⽤resize 和 transition属性会在⽤户重绘时,产⽣⼀个transition动画延迟时间。
七、图⽚(Images)
绝对居中(AbsoluteCentering)也适⽤于图⽚。对图⽚⾃⾝应⽤class类或CSS样式,并给图⽚添加height:auto样式,图⽚会⾃适应居中显⽰,如果外层容器可以resize则随着容器的重绘,图⽚也相应重绘,始终保持居中。
需要注意的是height:auto虽然对图⽚居中有⽤,但如果是在图⽚外层的内容块上应⽤了height:auto则会产⽣⼀些问题:规则的内容块会被拉伸填充整个容器。这时,我们可以使⽤可变⾼度(Variable Height)⽅式解决这个问题。问题的原因可能是渲染图⽚时要计算图⽚⾼度,这就如同你⾃⼰定义了图⽚⾼度⼀样,浏览器得到了图⽚⾼度就不会像其他情况⼀样去解析margin:auto垂直居中了。所以我们最好对图⽚⾃⾝应⽤这些样式⽽不是⽗元素。
HTML:
<img src="placekitten/g/500/200" class="Absolute-Center is-Image" alt="" />
CSS:
.Absolute-Center.is-Image{
height: auto;
}
.Absolute-Center.is-Image img{
width: 100%;
height: auto;
}
最好是对图⽚⾃⾝应⽤此⽅法,效果如下图:
⼋、可变⾼度(Variable Height)
这种情况下实现绝对居中(AbsoluteCentering)必须要声明⼀个⾼度,不管你是基于百分⽐的⾼度还是通过max-height控制的⾼度,还有,别忘了设置合适的overflow属性。对⾃适应/响应式情景,这种⽅法很不错。
与声明⾼度效果相同的另⼀种⽅法是设置display:table;这样⽆论实际内容有多⾼,内容块都会保持居中。这种⽅法在⼀些浏览器(如
IE/FireFox)上会有问题,我的搭档Kalley
在ELL Creative(访问ellcreative )上写了⼀个基于Modernizr插件的检测函数,⽤来检测浏览器是否⽀持这种居中⽅法,进⼀步增强⽤户体验。
Javascript:
/* Modernizr Test for Variable Height Content */
Modernizr.addTest('absolutecentercontent', und(window.innerHeight /2-25)=== elem.offsetTop);
});
CSS:
.absolutecentercontent .Absolute-Center.is-Variable{
display: table;
height: auto;
}
缺点:
浏览器兼容性不太好,若Modernizr不能满⾜你的需求,你需要寻其他⽅法解决。
1. 与上述重绘(Resizing)情况的⽅法不兼容
2. Firefox/IE8:使⽤display:table会使内容块垂直居上,不过⽔平还是居中的。 IE9/10:
3. 使⽤display:table会使内容块显⽰在容器左上⾓。
4. Mobile Safari:内容块垂直居中;若使⽤百分⽐宽度,⽔平⽅向居中会稍微偏离中⼼位置。
Ⅱ.其他居中实现技术
绝对居中(Absolute Centering)是⼀种⾮常不错的技术,除此之外还有⼀些⽅法可以满⾜更多的具体需求,最常见的推荐:NegativeMargins, Transforms,Table-Cell, Inline-Block⽅式和新出现的Flexbox.⽅式。这些⽅法许多⽂章都有深⼊讲解,这⾥只做简单阐述。
九、负外边距(Negative Margins)
这或许是当前最流⾏的使⽤⽅法。如果块元素尺⼨已知,可以通过以下⽅式让内容块居中于容器显⽰:
外边距margin取负数,⼤⼩为width/height(不使⽤box-sizing: border-box时包括padding,)的⼀半,再加上top: 50%; left: 50%;。即:
.is-Negative{
width: 300px;
height: 200px;
padding: 20px;
position: absolute;
top: 50%;left: 50%;
margin-left: -170px;/* (width + padding)/2 */
margin-top: -120px;/* (height + padding)/2 */
}
测试表明,这是唯⼀在IE6-IE7上也表现良好的⽅法。
优点:
1. 良好的跨浏览器特性,兼容IE6-IE7。
css固定定位2. 代码量少。
缺点:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论