为了账号安全,请及时绑定邮箱和手机立即绑定

父容器与子容器宽、高不确定,子容器实现水平、垂直居中的几种方式

标签:
Html/CSS

   年前前端圈蛮热闹的,大家撕的挺欢的,阿当想说的并不是固步自封,抵制学习新东西,而是想说要夯实基础,然后对框架有甄别能力的基础上再去有选择的学习。归根结底还是要掌握好根本,也就是道,其余的工具都不过是术,得道了,术这些东西自然手到擒来。好了,胡扯打住。阿当说区别真前端和伪前端其中一点就是能说出几种HTML元素的垂直居中方式。
   那我在这里总结一下我get的几种方式。
   代码结构如下,父容器,子容器宽高不确定。
<div class="parent"><div class="child"></div></div>


一、实现子容器水平居中的几种方式:

  1. 子容器.child设置display: inline-block; 父容器设置text-align: center。inline-block元素宽度具有收缩性的特征,即元素默认宽度为内容宽度。这种方法兼容性好,可以做一下hack处理来实现对IE6,7的兼容,子容器 _display: inline; _zoom: 1; 因为这里是子容器是div(即块级元素),所以需要此hack兼容,众所周知,IE6,7并不支持display: inline-block;但是这个属性会触发haslayout,这里就不详细展开了,可以参考博文:http://www.cnblogs.com/pigtail/archive/2013/01/23/2871627.html
  2. 利用table元素特性。子容器.child{display: table; margin: 0 auto;}。table非常像block,但是区别于block的一点是,table具有收缩性(收缩性在这里只是一个比喻,引用自张鑫旭老师,用来形象解释该类属性的特征,从而能够从感性上理解而非死记硬背)即元素默认宽度由内容区决定,表现形式类似inline-block,float,absolute绝对定位等 元素。)同时利用其类block的一点即margin-left: auto, margin-right: auto; 从而实现父容器,子容器宽度都不确定的情况下,子容器绝对居中的效果。优点是代码量小,且都作用于子容器,简单粗暴。缺点是display: table,需要IE8+支持。兼容IE6/7的话,只能将源代码的子容器div标签改成table标签,这样一来,语义化就值得商榷了。
  3. 利用定位,即.parent{position: relative}; .child{position: absolute; left: 50%; transform: translateX(-50%)}。如上所述,position设为absolute之后,宽度具有收缩性,宽度默认由内容区决定,子元素先left: 50%,相对父元素向左偏移一半的距离,然后transform: translateX(-50%),相对于元素自身向右偏移一半的距离,从而实现绝对居中的效果。因为这种方法使用了CSS3的transform属性,故兼容性较差,IE9以上支持, 且IE9需加私有前缀-ms-; 参考http://caniuse.com/#search=transform
  4. 利用弹性盒子布局。父容器display: flex; justify-content: center 或者 父容器display: flex; 子容器 margin: 0 auto。采用Flex布局的元素(即display设置为flex之后),称为Flex容器(flex container),简称"容器",它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。而flex-item的宽度默认为auto,具有收缩性,此时宽度由内容区决定,此时我们可以使用flex布局中的justify-content属性,该属性定义了flex item在主轴(x轴,横轴)上的对齐方式,将其设置为在主轴上居中对齐,从而实现子容器居中。此时我们也可以利用flex item元素宽度默认为auto的特性,使用 margin-left:auto,margin-right: auto, 实现该子容器的水平居中效果。flex布局强大,但是兼容性比较差,IE10,IE11对弹性布局都是部分支持,IE10需加私有前缀。
       结语:我在上述四种实现水平居中的方式里都在反复提及一个概念。即在使用了某种css属性之后,宽度不确定的子容器,此时它的宽度具有了收缩性(宽度由内容宽度决定),从而实现了其在父元素上的水平居中效果!

二、实现子容器的垂直居中的几种方式:

  1. 父容器display: table-cell; vertical-align: middle。
    这里再补充一个巧用vertical-align:middle特性的实现的类似方法(这个方法从张鑫旭老师那里get到的),实现思路就是:
    a. 使得需垂直居中的元素display设为inline-block;
    b. 设置一个用于辅助的宽度0高度100%的兄弟元素(其作用用于辅助);
    c. 将两者的vertical-align设置为middle。
    实践如下:
    这里加了一个span元素(可以是任意标签哈),将该span元素CSS属性设置为display: inline-block; height: 100%;(width:0; 这里没必要设置了,前面一直在讲inline-block元素具有收缩性,这里span木有内容因而宽度默认即为0)。然后把子容器.child的CSS属性设置为:display: inline-block; vertical-align: middle;

<div class="parent"><div class="child"></div><span></span></div>
一丝大神也有对这个方法的介绍,参照http://www.iyunlu.com/view/css-xhtml/77.html,方法也很巧妙,是利用添加伪元素来替代span, .parent:before{content: ''; display: inline-block; height: 100%; vertical-align: middle;}。 实现思路是一样的。//但是要考虑到IE8+以上才支持:after or :before 伪元素 :)
这是我的demo页面,http://codepen.io/CoolHector/pen/KzwvpQ
我给子容器插入了一段文本来充开内容宽度。

  1. 父容器position: relative; 子容器position: absolute; top: 50%; transform: translateY(-50%);
  2. 父容器,display: flex; align-items: center。

    综上,实现子容器水平、垂直居中对齐的方式有(父容器,子容器宽高不确定。)

  3. 父容器.parent{text-align: center; display: table-cell; vertiacal-align: middle;}。 子容器.child{display: inline-block;}
  4. 利用定位。父容器.parent{position: relative;} 子容器.child{position: absolute; top: 50%, left: 50%; transform: translate(-50%, -50%); }
  5. 利用弹性布局。父容器display: flex; justify-content: center; align-items: center;

参考

网易云课堂 页面架构

拓展阅读

  1. 关于display: table-cell:http://www.zhangxinxu.com/wordpress/?p=1187
    以及http://www.blueidea.com/tech/web/2008/6257.asp(注意这篇文章有三页~别匆匆一瞥就关了)
  2. 关于display: flex 弹性布局:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool
  3. 关于BFC与hasLayOut: http://www.cnblogs.com/pigtail/archive/2013/01/23/2871627.html
    未知高度多行文本垂直居中: http://www.iyunlu.com/view/css-xhtml/77.html

    ps 原文本人发布在博客园,这里又用MarkDown修改了一下发布在慕课网,今天是5.20,单身狗闲来无事,只好码字为乐。如果看官能有所收获,欢迎推荐,评论,你的支持是我写作的动力。

点击查看更多内容
11人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消