SS深入理解流体特性和BFC特性下多栏自适应布局


会触发BFC呢?常见的如下:   

   · float的值不为none

  • overflow的值为auto,scrollhidden
  • display的值为table-celltable-captioninline-block中的任何一个。
  • position的值不为relativestatic

BFC特性很多,而我们这里,只关心一个,和float元素做相邻兄弟时候的表现。

会发现,普通流体元素BFC后,为了和浮动元素不产生任何交集,顺着浮动边缘形成自己的封闭上下文。如下截图:

BFC与浮动边缘对齐~

同时,元素原本的流体特性依然保留了

2. BFC自适应布局模块间的间距
然而,模块过于亲密接触,可能不是我们想要的。一般而言,我们需要一点间距。

说到间距,我们的第一反应就是margin. 于是,我们给BFC元素增加一个margin-left:20px, CSS代码如下:

.float-left {
    float: left;
}
.follow-content {
    margin-left: 20px;
    background-color: #cad5eb;
    overflow: hidden;
}

结果……纳尼~  怎么还是像狗屁膏药贴在一起啊??
margin-left:20px无效截图

您可以狠狠地点击这里:BFC元素增加一个margin无效demo

实际上,这里的margin并不是无效,而是值不够大,鞭长莫及啊!那我们把margin-left:20px改成margin-left:150px就应该有间距了? 一试便知!

.float-left {
    float: left;
}
.follow-content {
    margin-left: 150px;
    background-color: #cad5eb;
    overflow: hidden;
}

结果,当当当当:
margin值很大收获的间距

注意:我这里举margin这个例子,不是让大家这样使用,只是为了让大家可以深入理解BFC元素与浮动元素混排的特性表现。实际开发,我们完全没有必要对BFC元素设置margin, 因为又回到了流体布局,明明是固定的15像素间距,但是,每个布局都要写一个不同的margin值,完全没有重用价值。

扫描二维码关注公众号,回复: 908011 查看本文章

但是,间距部分的高潮来了!

我们可以使用浮动元素的margin-right或者padding-right轻松实现间距效果。间距是20像素,直接:

.float-left {
    float: left;
    margin-right: 20px;
}

与浮动元素的宽度是多少没有任何关系。不仅如此,我们还可以使用BFC元素的padding-left撑开间距(虽然margin-left作用鸡肋)。

于是,我们可能就会有:

.l { float: left; }
.ovh { overflow: hidden; }

的自适应固定搭配。再配合zxx.lib.cssCSS样式库的marginpadding家族,快速布局可谓所向披靡。

3. 与纯流体特性布局的优势
BFC自适应布局优势我总结了下面2点:

  1. 自适应内容由于封闭,更健壮,容错性强。比方说,内部clear:both不会与兄弟float产生矛盾。而纯流体布局,clear:both会让后面内容无法和float元素在一个水平上,产生布局问题。
  2. 自适应内容自动填满浮动以为区域,无需关心浮动元素宽度,可以整站大规模应用。而纯流体布局,需要大小不确定的margin/padding等值撑开合适间距,无法CSS组件化。

而CSS代码就是非常简单的:

.float-left {
    float: left; margin-right: 20px; 
}
.bfc-content {
    overflow: hidden; background-color: #beceeb;
}

可以说,有了BFC自适应布局,基本上没有了纯流体特性布局存在的价值。然而,只是理论上如此。如果,BFC自适应布局真那么吊炸天,那为何并没有口口相传呢?

那我们就得进一步深入理解了。

4. BFC元素家族与自适应布局面面观
理论上,任何BFC元素和浮动搞基的时候,都可以实现自动填充的自适应布局。

但是,由于绝大多数的触发BFC的属性自身有一些古怪的特性,所以,实际操作的时候,能兼顾流体特性和BFC特性来实现无敌自适应布局的属性并不多。下面我们牵驴遛马一个一个瞅瞅(类似行为仅出1个代表示意,你懂的,如float:left/right):

  1. float:left 浮动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。不过,其因兼容性还算良好,与堆积木这种现实认知匹配,上手简单,因此在旧时代被大肆使用,也就是常说的“浮动布局”,也算阴差阳错开创了自己的一套布局。
  2. position:absolute 这个脱离文档流有些严重,过于清高,不跟普通小伙伴玩耍,我就不说什么了……
  3. overflow:hidden 这个超棒的哦!不像浮动和绝对定位,玩得有点过。也就是溢出剪裁什么的,本身还是个很普通的元素。因此,块状元素的流体特性保存相当完好,附上BFC的独立区域特性,可谓如虎添翼,宇宙无敌!哈无诶瓦(However), 就跟清除浮动:
    .clearfix { overflow: hidden; _zoom: 1; }

    一样。由于很多场景我们是不能overflow:hidden的,因此,无法作为一个通用CSS类整站大规模使用。因此,float+overflow的自适应布局,我们可以在局部(你确定不会有什么被剪裁的情况下)很happy地使用。

  4. display:inline-block CSS届最伟大的声明之一,但是,在这里,就有些捉襟见肘了。display:inline-block会让元素尺寸包裹收缩,完全就不是我们想要的block水平的流动特性。唉,只能是一声叹气一枪毙掉的命!然而,峰回路转,世事难料。大家应该知道,IE6/IE7浏览器下,block水平的元素设置display:inline-block元素还是block水平,也就是还是会自适应容器的可用宽度显示。于是,我们就阴差阳错得到一个比overflow:hidden更牛逼的声明,即BFC特性加身,又流体特性保留。
    .float-left {
        float: left;
    }
    .bfc-content {
        display: inline-block;
    }

    当然,*zoom: 1也是类似效果,不过只适用于低级的IE浏览器,如IE7~

  5. display:table-cell 让元素表现得像单元格一样,IE8+以上浏览器才支持。跟display:inline-block一样,会跟随内部元素的宽度显示,看样子也是不合适的命。但是,单元格有个非常神奇的特性,就是你宽度值设置地再大,大到西伯利亚,实际宽度也不会超过表格容器的宽度。
    表格单元格不会超出表格宽度特性

    因此,如果我们把display:table-cell这个BFC元素宽度设置很大,比方说3000像素。那其实就跟block水平元素自动适应容器空间效果一模一样了。除非你的容器宽度超过3000像素,实际上,一般web页面不会有3000像素宽的模块的。所以,要是你实在不放心,设个9999像素值好了!

    .float-left {
        float: left;
    }
    .bfc-content {
        display: table-cell; width: 9999px;
    }

    看上去,好像还不错。但是,还是有两点制约,一是IE8+以上浏览器兼容,有些苦逼的团队还要管IE6;二是应付连续英文字符换行有些吃力(可以嵌套table-layout:fixed解决)。但是,总体来看,适用的场景要比overflow:hidden广博很多。

  6. display:table-row 对width无感,无法自适应剩余容器空间。
  7. display:table-caption 一无是处……还有其他声明也都是一无是处,我就不全部展开了……

总结:我们对BFC声明家族大致过了一遍,能担任自适应布局重任的也就是:

  1. overflow:auto/hidden IE7+
  2. display:inline-block IE6/IE7
  3. display:table-cell IE8+

由于overflow有剪裁和出现滚动条等隐患,不适合作为整站通用类,于是,最后,类似清除浮动的通用类语句:

.clearfix {
    *zoom: 1;
}
.clearfix:after {
    content: ''; display: table; clear: both;
}

两栏或多栏自适应布局的通用类语句是(block水平标签,需配合浮动):

.cell {
    display: table-cell; width: 9999px;
    *display: inline-block; *width: auto;
}

这就是zxx.lib.cssCSS样式库中.cell的由来!

当然,由于和浮动元素合作,清除浮动还是要的,于是,就有了.fix + .l/.r + .cell的无敌组合,可以多栏,也可以无限嵌套。

如果是局部,且确认安全;或有连续英文字符换行的隐患,你也可以使用.fix + .l/.r + .ovh的无敌组合,可以多栏,也可以无限嵌套。


猜你喜欢

转载自blog.csdn.net/dreamerzhang66/article/details/80270635