一、块状元素的流体特性与自适应布局
块状元素像放在容器中的水流一样,内容区域会随着margin
, padding
, border
的出现自动填满剩余空间,这就是块状元素的流体特性。
来一个小实验:
div {
margin-left:100px;
width:100%;
}
此时发现,左侧永远100px留白,而div随着容器宽度变化而自适应变化了
我们需要好好利用左侧100px的留白间距,岂不是就可以实现两栏自适应效果?
为了不影响原本的流体特性,我们可以使用破坏性属性,如浮动(float:left),或者绝对定位(position:absolute)。
然而,利用块状元素流体特性实现的自适应布局有个不足,就是,我们需要知道浮动或绝对定位内容的尺寸。
然后,流体内容才能有对应的margin
或padding
或border
值进行位置修正。
于是,问题来了,我们没法单纯使用一个公用的类名,类似.clearfix
这样,整站通用。因为不同自适应场景的留白距离是不一样的。
此时,我们可以利用块状元素的BFC实现更强大更智能的多栏自适应布局(本文重点)
二、元素的BFC特性与自适应布局
BFC特性很多,参考我之前的文章:深入理解BFC
而我们这里,只关心一个,和float
元素做相邻兄弟时候的表现。
流体特性div
, 当其和浮动元素当兄弟的时候,是覆盖的关系(可以脑补下文字环绕图片效果)。
如果给div overflow:hidden,触发bfc
普通流体元素BFC后,为了和浮动元素不产生任何交集,顺着浮动边缘形成自己的封闭上下文
不与浮动交集,自动退避浮动元素宽度的距离,但,本身作为普通元素的流动性依然存在
2. BFC自适应布局模块间的间距
一般而言,我们需要一点间距。我们的第一反应就是margin
div设置margin-left:10px 但是好像不起作用 ?
这里的margin并不是无效,而是值不够大
当你设置margin-left值大于浮动元素宽度,则生效
但是这样又回到了流体布局,毫无成长
但是,我们可以使用浮动元素的margin-right
或者padding-right
轻松实现间距效果
还可以使用BFC元素的padding-left
撑开间距
3. BFC自适应布局优势与纯流体特性布局相比的优势
- 自适应内容由于封闭,更健壮,容错性强。比方说,内部
clear:both
不会与兄弟float
产生矛盾。而纯流体布局,clear:both
会让后面内容无法和float
元素在一个水平上,产生布局问题。 - 自适应内容自动填满浮动以为区域,无需关心浮动元素宽度,可以整站大规模应用。而纯流体布局,需要大小不确定的
margin
/padding
等值撑开合适间距,无法CSS组件化。
4. BFC元素家族与自适应布局面面观
理论上,任何BFC元素和浮动搭配,都可以实现自动填充的自适应布局。
但是,由于绝大多数的触发BFC的属性自身有一些古怪的特性,所以,实际操作的时候,能兼顾流体特性和BFC特性来实现无敌自适应布局的属性并不多。
下面举一些例子:
对于,浮动(float),绝对定位(position:absolute)以及inline-block的包裹性我称之为“主动包裹”,其标签宽度会收缩至内部元素大小;
而overflow与zoom,我称之为“被动包裹”。
float:left 浮动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。不过,其因兼容性还算良好,与堆积木这种现实认知匹配,上手简单,因此在旧时代被大肆使用,也就是常说的“浮动布局”,也算阴差阳错开创了自己的一套布局(圣杯布局以及双飞燕布局(栅格))。
position:absolute 这个脱离文档流有些严重,不宜使用
overflow:hidden 也就是溢出剪裁什么的,本身还是个很普通的元素。因此,块状元素的流体特性保存相当完好,附上BFC的独立区域特性,可谓如虎添翼,一样。由于很多场景我们是不能overflow:hidden
的,因此,无法作为一个通用CSS类整站大规模使用。因此,float+overflow
的自适应布局,我们可以在局部(你确定不会有什么被剪裁的情况下)很happy地使用(IE6有bug不行)。
display:inline-block CSS届最伟大的声明之一,但是,在这里,就有些捉襟见肘了。display:inline-block
会让元素尺寸包裹收缩,完全就不是我们想要的block
水平的流动特性。
大家应该知道,IE6/IE7浏览器下,block
水平的元素设置display:inline-block
元素还是block
水平,也就是还是会自适应容器的可用宽度显示。于是,我们就阴差阳错得到一个比overflow:hidden
更牛逼的声明,即BFC特性加身,又流体特性保留。
当然,*zoom: 1
也是类似效果,比例缩放,跟CSS3中transform:scale差不多;不过只适用于低级的IE浏览器,IE8以下可以清除浮动。(haslayout详解)
display:table-cell 让元素表现得像单元格一样,IE8及以上以上浏览器才支持。跟display:inline-block
一样,会跟随内部元素的宽度显示,看样子也是不合适的命。但是,单元格有个非常神奇的特性,就是你宽度值设置地再大,大到西伯利亚,实际宽度也不会超过表格容器的宽度。
因此,如果我们把display:table-cell
这个BFC元素宽度设置很大,比方说3000像素。那其实就跟block
水平元素自动适应容器空间效果一模一样了。除非你的容器宽度超过3000像素,实际上,一般web页面不会有3000像素宽的模块的。
display:table-row 对width
无感,无法自适应剩余容器空间。
display:table-caption 一无是处……还有其他声明也都是一无是处,我就不全部展开了……
总结:我们对BFC声明家族大致过了一遍,能担任自适应布局重任的也就是:
overflow:auto/hidden
IE7及以上display:inline-block
IE6/IE7display:table-cell
IE8及以上