看了这篇文章,你能够了解到如下布局方法:css
最近开发遇到一些布局上的问题,因为不肯定因素比较多,好比不定宽高、单行多行的状况须要显示的样式基本相同。这样的状况会比较复杂,后来找到display:table-cell这个布局神器,这些问题也就不是问题了。好比如下这种状况:布局
基于这样的需求,咱们一般都是每一种状况须要单独的写一份hack样式,这样写起来很麻烦。咱们多么但愿写一份样式,无论你里面的节点如何变,定不定宽高,多行与否都能表现一致。针对水平|垂直居中的状况,我找到了table-cell布局的方式,基本能解决。下面会总结一下table-cell的布局原理以及列举一些平常布局所遇到的状况。flex
虽然table布局由于它的一些非语义化、布局代码冗余,以及很差维护改版等缺点被赶出了布局界。可是在css不给力时期,table布局也曾风靡一时,就算如今看来table的一些布局的特性也是很是给力的,而幸亏css也吸收了table布局一些好的特性为己用。让咱们可使用更少、更语义化的标签来模拟table布局,能够跳过table布局的缺点又实现咱们想要的效果,因此咱们首先须要了解table的一些特性以及对应的css属性。
咱们在不居中使用到的也就是table、tr、td的一些特性,因此咱们只须要了解这三个标签的特性就足够了。spa
1) table可设置宽高、margin、border、padding等属性。属性值的单位可使用px,百分比值。
2) table的宽度默认由内容的宽高撑开,若是table设置了宽度,宽度默认被它里面的td平均分,若是给某一个td设置宽度,那么table剩余的宽度会被其余的td平均分(有点相似flex布局)
3) 给table设置的高度起到的做用只是min-height的做用,当内容的高度高于设置的高度时,table的高度会被撑高。code
1) 给tr设置高度只起到min-height的做用,默认会平分table的高度。
2) tr中的td默认高度会继承tr的高度,若给任一td设置了高度,其余td的高度也一样变高。适合多列等高布局
3) 设置宽度、margin、都不起做用继承
1) td默认继承tr的高度,且平分table的宽度
2) 若table(display:table)不存在,给td设置的宽高不能用百分比只能用准确的数值
3) 给td设置vertical-align: middle; td元素里面(除float、position:absolute)全部的块级、非块级元素都会相对于td垂直居中
4) 给td设置text-align: center; td元素里面全部非block元素(除float、position:absolute)都会相对于td水平居中,虽然block元素不居中,但其中的文字或inline元素会水平居中图片
了解了table的一些属性,当咱们遇到一些水平垂直居中的布局时,就会变得so easy了。开发
图片自己就是inline-block元素,那么咱们只要给它的父级元素加个display:table-cell就行了rem
.box{ height: 200px; width: 200px; display: table-cell; text-align: center; border: 1px solid #ccc; vertical-align: middle; } <div class="box"> <img src="https://ss1.baidu.com/70cFfyinKgQFm2e88IuM_a/forum/pic/item/242dd42a2834349b406751a3ceea15ce36d3beb6.jpg"> </div>
就是那么简单。demoget
咱们平时常见的就是单行水平垂直居中,其实就是简单的text-align:center; 而后再是line-height:xx 就搞定了。可是多行的就相对于复杂点。可是使用了table-cell以后,就变得很简单了
固然,里面也能够是多个标签造成的多行,而后进行水平垂直居中
demo1 demo2
其实实现的原理仍是使用table-cell,先把外层box设置为table-cell,再把里面的元素设置为inline|inline-block(不定宽高|元素居中)或者block(宽度100%|文字居中)那么就能够控制里面的元素水平垂直居中了。基于这样的布局方式,你就能够把什么定高|不定高|定宽|不定宽|多行|单行的水平垂直居中都搞定了。
因为display:table-cell对浮动元素是不起做用的,当咱们须要两个元素一个左浮动一个右浮动,而且这连个元素还居中的时候。上面的方法就不起做用了。那咱们能够换个法子,既然display:table-cell;的垂直居中不能直接对浮动元素起做用,那就来个间接的嘛。给两个浮动的元素外面一个display:inline-block;的元素,而且清除浮动。而后让display:table-cell的垂直居中对inline-block元素起做用就行了。demo
若是你的需求还须要在两个浮动的元素中再添加水平垂直居中的话,那么一样的道理,只须要在这两个元素中构造符合table-cell布局的结构就行了。
常常会有这样的需求,一列里面可能会有一、二、3个子元素,无论几个都是要居中的。有了table-cell就能够轻松解决了。
实现原理也基本是把外层box设置为display:table-cell;而后设置居中。里面的元素item设置成inline或者line-block;就能够了,无论里面的item的个数多少,都会居中的,包括item是图片也会这样。[demo]()
有这样的需求,一行有三个item,三个item的高度不定,可是这一行的三个item最终的高度以最高的那个为准。按照之前的作法要不就是砍掉需求,必须定高。实在不行就是等加载完以后用js计算三个item的高度,而后把最高的高度给其余item设置高度。这样有点恶心,而且会出现抖动。有了table-cell以后,这个就不成问题了,由于在一个tr中,里面的td必须是等高的,而无论里面内容的高度。demo
认证看代码你会发现跟咱们平时的定高布局布局不同,每行外面必须得有一个ul来保证里面item的等高,而且里面还须要使用多余的li来控制间距。这样作的缘由是由于tr里面的元素不会自动换行,因此必须手动换行,给外面加个ul,(说好的tr呢?)是这样的,被设置为display:table-cell的元素会跟相邻的兄弟元素共同生成一个虚拟的table、tr把本身包起来,谁叫td只能包在table里面呢。可是你直接写td标签是不会产生这样的效果的。而使用多余的li来控制间距是由于table-cell元素不认识margin,因此只能这样作了。
在生成机构的时候就须要判断何时该换行了,而不是像之前同样在一个ul里面生成所有的li了
使用table-cell还能够实现不少的布局,须要本身去发挥想象。总结下来也就须要记住几点,设置了display:table-cell的元素具备如下特性。
这就是所谓的table布局大法。