Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 878|回复: 0

CSS垂直居中解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-4 19:32:52 | 显示全部楼层 |阅读模式

    问题场景

    应用的地方比较普遍,这里有两个赤裸裸的栗子:

     

    也有很多流行的方案,这里只针对各种方案的适用场景来做一些分析

    问题抽象

    其实,垂直居中问题可以简化成这样:一个容器HTML元素(#container),一个需要居中的HTML元素(#center)。特殊的情形下可能会出现body为#container,#center是图片,此处不予讨论。 #center 可能有高度,也可能没有,也可能是响应式的。总之,代码的结构如下图所示:


    再有就是浏览器的兼容性问题:IE6,IE7.....不说了,都是泪。总之,我们要做的就是在相应的代码处填入代码以期达到下图目的。:

    方案一:负外边距(Negative Margins)

    这种方案应该是最流行的,思路也比较简单,浏览器的兼容性(IE6+)也比较好,但是必须要指定#center的高度,也无法进行响应式处理(类似height:60%,max-width:400px;)

     
    如果能确定#center高度,并且无需响应式,这种方案是最棒的!

    方案二:绝对定位居中(Absolute Centering)

    该方法兼容IE8+,虽然可以自适应,虽然padding可以不用操心,但是还是必须声明高度!关于这种方案的工作原理:

    • 在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
    • position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。
    • 为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative;的容器。
    • 给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto
    • 由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。
    • 总之:绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0; left: 0; bottom: 0;right: 0;设置的边界内垂直居中。

    方案三:变形(Transforms)

    这种方案是方案一的一种延伸,它解决了方案一必须指定高度,不支持响应式的问题,但是浏览器兼容性不佳,只支持IE9+,但是在移动版的浏览器却可以放心的使用哦!


    另外,这种方案可能需要在transform上加入前缀,不过如果有less和sass这样的东西就好多了,瞬间,又有了对IE的鄙视!

    方案四:表格单元格(table-cell)

    思路是这样的: <table><tr><td>I am Centered</td></tr></table>,代码是这样的:

    • 1.需要木有语义的多余的标签嵌套
    • 2.兼容IE8+
    • 3.可能在一些浏览器上有问题(特别是IE)

    由于兼容上的一些问题,这个方案,不太建议。

    方案五:行内块元素(inline-block)

    思路为:期望在#container中:text-align:center;,在#center中:vertical-align:middle;达到目的,但是#center却无法撑开#container,咋办呢? 可以在#container里面加入一个多余的display为inline-block的div(作为#container的一个child),将#container的高度撑开,就像这样:


    如果支持:before或者:after的浏览器,就可以高大山一些:


    但是,还存在如下两个问题:

    • 由于两个inline-block的元素之间默认是有间隙的,所以需要在#center中margin-right为负值或者在#container中font-size:0px;(如果#center为图片的情况下)进行调整
    • #center的宽度不能大于#container的100%-间隙,否则before将会被挤走

    方案六:Flexbox

    这个应该是最简单的,如下:


    原理为:margin:auto;自动获取伸缩容器中剩余的空间,设置垂直方向margin值为auto,可以使伸缩项目在伸缩容器的两上轴方向都完全集中。我觉得,实际上相当于这样:


    关于Flexbox,请参见 这里
    但是flex的缺点也是显而易见的,不支持老旧的浏览器。

    总结

    以上各种方案,各有优缺,希望大家赶紧提建议,我也将能够通用的代码全部整到了github上(这里

    参考

    • http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/
    • http://www.w3cplus.com/css3/a-guide-to-flexbox.html
    • http://www.smashingmagazine.com/2013/05/22/centering-elements-with-flexbox/
    • http://www.zhangxinxu.com/wordpress/2010/10/%E6%88%91%E6%89%80%E7%9F%A5%E9%81%93%E7%9A%84%E5%87%A0%E7%A7%8Ddisplaytable-cell%E7%9A%84%E5%BA%94%E7%94%A8/
    • http://www.zhangxinxu.com/wordpress/2013/11/margin-auto-absolute-%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D-%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/
    • http://www.zhangxinxu.com/wordpress/2009/08/大小不固定的图片、多行文字的水平垂直居中
    • http://designshack.net/articles/css/how-to-center-anything-with-css
    • http://css-tricks.com/centering-in-the-unknown/
    • https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 04:11 , Processed in 0.061741 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表