css基础--float 的天然克星 clear/BFC

1、什么是clear属性
clear: none | left | right | b
none:默认值,左右浮动来就来。
left:左侧抗浮动。
right:右侧抗浮动。
both:两侧抗浮动。
假设容器宽度足够宽,有10个

  • 元素,设置了如下CSS代码:
  • li {   
    width: 20px; 
    height: 20px;   
    margin: 5px;   
    float: left; } 
    li:nth-of-type(3) {   
    clear: both; 
    }
    

    最后显示如下图所示
    在这里插入图片描述
    原因在于,clear属性是让自身不能和前面的浮动元素相邻,注意这里“前面的”3个字,也就是clear属性对“后面的”浮动元素是不闻不问的,因此才2行显示而非3行。
    2、成事不足败事有余的clear
    clear属性只有块级元素才有效的,而::after等伪元素默认都是内联水平,这就是借助伪元素清除浮动影响时需要设置display属性值的原因

    .clear:after {   
    content: '';   
    display: table; 
    // 也可以是'block',或者是'list-item'   
    clear: both; }
    

    如下图的清除浮动方法

    <div class="father">   
    <img src="me.jpg">   
    <div class="animal"> 小猫1,小猫2,    
    <div class="clear"></div> 
    小猫3,小猫4,小猫3,小猫4,小猫5,小猫6,小狗1,小狗2,小狗3,小狗4,小狗5,小狗6   
    </div> 
    </div>
    

    在这里插入图片描述
    由于clear:both的作用本质是让自己不和float元素在一行显示,并不是真正意义上的清除浮动,因此float元素一些不好的特性依然存在,于是,会有类似下面的现象。
    (1)如果clear:both元素前面的元素就是float元素,则margin-top负值即使设成-9999px,也不见任何效果。
    (2)clear:both后面的元素依旧可能会发生文字环绕的现象。举个例子,如下HTML和CSS:

    <div class="father">   
    <img src="zxx.jpg"> 
    我是帅哥,好巧啊,我也是帅哥,原来看这本书的人都是帅哥~ </div> <div>虽然你很帅,但是我对你不感兴趣。</div>
    .father:after {  
    content: '';   
    display: table;   
    clear: both; } 
    .father img {   
    float:left;   
    width: 60px; 
    height: 64px; } 
    .father + div {   margin-top: -2px; }
    

    虽然.father父元素的最后设置了clear:both来阻止浮动对后面元素的影响,但是最后结果错位依然发生了,如图6-17所示
    在这里插入图片描述
    由此可见,clear:both只能在一定程度上消除浮动的影响,要想完美地去除浮动元素的影响,还需要使用其他CSS声明。
    3、 BFC的定义
    BFC全称为block formatting context,中文为“块级格式化上下文”。相对应的还有IFC,也就是inline formatting context,中文为“内联格式化上下”。
    如果一个元素具有BFC,内部子元素再怎么翻江倒海、翻云覆雨,都不会影响外部的元素。所以,BFC元素是不可能发生margin重叠的,因为margin重叠是会影响外面的元素的;BFC元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违BFC元素的子元素不会影响外部元素的设定。
    那什么时候会触发BFC呢?常见的情况如下:
    (1)根元素;
    (2)float的值不为none;
    (3)overflow的值为auto、scroll或hidden;
    (4)display的值为table-cell、table-caption和inline-block中的任何一个;
    (5)position的值不为relative和static。
    换言之,只要元素符合上面任意一个条件,就无须使用clear:both属性去清除浮动的影响了。
    4、BFC与流体布局

    <div class="father">  
     <img src="me.jpg">  
      <p class="animal">小猫1,小猫2,...</p>
      </div> 
      img { float: left; }
      .animal { 
      overflow: hidden;
      }
    

    本来animal的内容显然受到了设置了float属性值的图片的影响而被环绕了。此时如果我们给.animal元素设置具有BFC特性的属性,如overflow:hidden。则根据BFC的表现原则,具有BFC特性的元素的子元素不会受外部元素影响,也不会影响外部元素。于是,这里的.animal元素为了不和浮动元素产生任何交集,顺着浮动边缘形成自己的封闭上下文,如图6-19所示(垂直虚线为辅助示意)
    在这里插入图片描述
    普通流体元素在设置了overflow:hidden后,会自动填满容器中除了浮动元素以外的剩余空间,形成自适应布局效果,而且这种自适应布局要比纯流体自适应更加智能。比方说,我们让图片的尺寸变小或变大,右侧自适应内容无须更改任何样式代码,都可以自动填满剩余的空间。例如,我们把图片的宽度从60px改成30px,结果如图6-20所示
    在这里插入图片描述
    如果想要保持合适的间距,那也很简单,如果元素是左浮动,则浮动元素可以设置margin-right成透明border-right或padding-right;又或者右侧BFC元素设置成透明border-left或者padding-left,但不包括margin-left,因为如果想要使用margin-left,则其值必须是浮动元素的宽度加间隙的大小,就变成动态不可控的了,无法大规模复用
    和基于纯流体特性实现的两栏或多栏自适应布局相比,基于BFC特性的自适应布局有如下优点:
    (1)自适应内容由于封闭而更健壮,容错性更强。比方说,内部设置clear:both不会与float元素相互干扰而导致错位,也就不会发生类似于图6-22所示的问题。
    在这里插入图片描述
    (2)自适应内容自动填满浮动以外区域,无须关心浮动元素宽度,可以整站大规模应用。比方说,抽象几个通用的布局类名

    .left { 
    float: left; 
    } 
    .right { 
    float: right; 
    } 
    .bfc { 
    overflow: hidden;
    }
    

    任何BFC元素和float元素相遇的时候,都可以实现自动填充的自适应布局。但是,由于绝大多数的触发BFC的属性自身有一些古怪的特性,所以,实际操作的时候,能兼顾流体特性和BFC特性来实现无敌自适应布局的属性并不多。下面我们一个一个来看,每个CSS属性选一个代表来进行说明。
    (1)float:left。浮动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。
    2)position:absolute。这个脱离文档流有些严重。
    (3)overflow:hidden。这个超棒!不像浮动和绝对定位,玩得有点儿过。其本身还是一个很普通的元素,因此,块状元素的流体特性保存得相当完好,附上BFC的独立区域特性,可谓如虎添翼、宇宙无敌!而且overflow:hidden的BFC特性从IE7浏览器开始就支持,兼容性也很不错。唯一的问题就是容器盒子外的元素可能会被隐藏掉,一定程度上限制了这种特性的大规模使用。不过,溢出隐藏的交互场景比例不算很高,所以它还是可以作为常用BFC布局属性使用的。
    (4)display:inline-block。这是CSS世界最伟大的声明之一,但是用在这里,就有些捉襟见肘了。display:inline-block会让元素尺寸包裹收缩,完全就不是我们想要的block水平的流动特性。只能是一声叹息舍弃掉!然而,峰回路转,世事难料。大家应该知道,IE6和IE7浏览器下,block水平的元素设置display:inline-block元素还是block水平,也就是还是会自适应容器的可用宽度显示。于是,对于IE6和IE7浏览器,我们会阴差阳错得到一个比overflow:hidden更强大的声明,既BFC特性加身,又流体特性保留。
    (5)display:table-cell。其让元素表现得像单元格一样,IE8及以上版本浏览器才支持。跟display:inline-block一样,它会跟随内部元素的宽度显示,看样子也是不合适的命。但是,单元格有一个非常神奇的特性,就是宽度值设置得再大,实际宽度也不会超过表格容器的宽度。第3章单元格一柱擎天的例子利用的就是这种特性,如图6-23所示
    在这里插入图片描述
    因此,如果我们把display:table-cell这个BFC元素宽度设置得很大,比方说3000px,那其实就跟block水平元素自动适应容器空间效果一模一样了,除非你的容器宽度超过3000px。实际上,一般Web页面不会有3000px宽的模块,所以,要是实在不放心,设个9999px好了

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

    还是有两点制约,一是需要IE8及以上版本的浏览器;二是应付连续英文字符换行有些吃力。
    (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及以上版本浏览器。
    提炼出两套IE7及以上版本浏览器适配的自适应解决方案
    1)借助overflow属性,如下:

    .lbf-content { overflow: hidden;}
    

    (2)融合display:table-cell和display:inline-block,如下:

    .lbf-content {   
    display: table-cell; 
    width: 9999px;   
    /* 如果不需要兼容IE7,下面样式可以省略 */ 
    *display: inline-block; 
    *width: auto;
    }
    

    这两种基于BFC的自适应方案均支持无限嵌套,因此,多栏自适应可以通过嵌套方式实现。这两种方案均有一点不足,前者如果子元素要定位到父元素的外面可能会被隐藏,后者无法直接让连续英文字符换行。
    关于display:table-cell元素内连续英文字符无法换行的问题,事实上是可以解决的,就是使用类似下面的CSS代码:

    .word-break {   
    display: table;   
    width: 100%;   
    table-layout: fixed;   
    word-break: break-all; 
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值