>

那多少个年我们意气风发道消逝过的成形

- 编辑:至尊游戏网站 -

那多少个年我们意气风发道消逝过的成形

CSS 属性flow-root

2017/04/26 · CSS · flow-root

原文出处: 大漠   

今天我们来介绍CSS中的一个新属性flow-root。这个属性是CSS Display Module Level3中的一个属性。简单讲这个属性是display中的一个新属性,对于display属性,大家熟悉的可能是常见的几个属性,比如block、inline、inline-block、flex、grid、table和table-cell等,其实除了这些常见的属性值之外,还有很多其他的值。如果想了解更多,那可以点击这里阅读。

那flow-root既然是display的新属性值,那这个属性值有什么特性呢?这就是今天要聊的东西。

清除浮动--全面解读(摘自网摘--那些年我们一起清除过的浮动),全面解读网摘

BFC

在学习flow-root之前,咱们要先了解CSS中一个非常重要的概念,那就是BFC(Block Formatting Context)的概念。那什么是BFC呢?

在W3C规范中的BFC是这样定义的:

浮动元素和绝对定位元素,非块级盒子的块级容器(例如,inline-block、table-cells和table-captions),以及overflow值不为visiable的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。

在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)。对于从右到左的格式来说,则触 碰到右边缘。

规范中的描述可能难让人理解,我们再来看看BFC的一种通俗理解:

首先BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列

必竟这篇文章不是主要介绍CSS中的BFC的,如果你想深入的了解CSS中的BFC相关知识,可以阅读下面的文章:

  • 深入理解BFC和Margin Collapse
  • CSS layout入门
  • CSS深入理解流体特性和BFC特性下多栏自适应布局
  • 前端精选文摘:BFC 神奇背后的原理
  • 从莫名的熟悉到明确的概念:CSS BFC(Block Formatting Context)
  • BFC(块级格式化上下文)
  • CSS之BFC详解
  • CSS学习专题-BFC
  • Melon Space
  • 详说 Block Formatting Contexts (块级格式化上下文)
  • CSS中BFC的概念及外层div包裹内层div处理方法
  • How does the CSS Block Formatting Context work?
  • CSS 101: block formatting contexts
  • CSS 101: Block Formatting Contexts
  • 了解CSS中的块格式化上下文
  • 理解CSS中的块级格式化上下文
  • CSS中的BFC

一、清除浮动和闭合浮动

  所谓清除浮动,是指显示上正确。避免了文档流自动包裹浮动元素的特性(常见的是footer部分设置clear:both;属性);

而闭合浮动,是确实解决了高度塌陷的问题,使得wrap元素具有了高度。可疑包裹进浮动的元素。所以说,称之为闭合浮动更为合适。

浮动和清除浮动

了解了BFC之后,在简单的回忆一下CSS中的float属性。众所周知,在CSS的布局中,早期采用布局多半是依赖于float属性,但元素浮动之后会造成容器的高度坍塌。为了避免这个现象,有了各式各样的清除浮动的黑魔法。至于浮动和清除浮动的相关知识,欢迎阅读下面的相关文章:

  • CSS的Float之一
  • CSS的Float之二
  • float深入剖析
  • float是如何工作的
  • Clear Float

二、闭合浮动的原理

flow-root

了解了BFC、浮动和清除浮动之后,咱们回到今天要聊的flow-root。W3C规范中是这样描述flow-root的:

The element generates a block container box, and lays out its contents using flow layout. It always establishes a new block formatting context for its contents.

简单地说,元素容器会生成一个块盒子,并且块盒子里的内容是使用流布局。它总是为它建立一个新的块格式化上下文内容。如果你对CSS中浮动有所了解之后,你不难发现,容器里的元素浮动之后,会造成容器的坍塌现象之类的。

图片 1

通过clearfix之后,能让其变得正常:

图片 2

看到这里,或许你知道flow-root的特性是什么了。其实正如你所想的一样:flow-root是最新一种创建BFC的属性。正因为如此,大多数人都认为flow-root就是一个简单的clearfix黑魔法,也有很多人说他是最新清除浮动的最简易方案。但这个特性其实真的很有实用性。

  常用的清除浮动方法有许多,可分为两类

  那么其中的原理是什么呢,在这之前需要先了解一下hasLayout 和 Block formatting contexts。

所谓Block formatting contexts是指块级格式化上下文,简称BFC。

那么如何触发BFC呢?

  • float 除了none以外的值   
  • overflow 除了visible 以外的值(hidden,auto,scroll )   
  • display (table-cell,table-caption,inline-block)   
  • position(absolute,fixed)   
  • fieldset元素

需要注意的是,display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes),而匿名框中的display:table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是 display:table。所以通过display:table和display:table-cell创建的BFC效果是不一样的。

 fieldset 元素在www.w3.org里目前没有任何有关这个触发行为的信息,直到HTML5标准里才出现。有些浏览器bugs(Webkit,Mozilla)提到过这个触发行为,但是没有任何官方声明。实际上,即使fieldset在大多数的浏览器上都能创建新的块级格式化上下文,开发者也不应该把这当做是理所当然的。CSS 2.1没有定义哪种属性适用于表单控件,也没有定义如何使用CSS来给它们添加样式。用户代理可能会给这些属性应用CSS属性,建议开发者们把这种支持当做实验性质的,更高版本的CSS可能会进一步规范这个。

 

BFC的特性:

使用display:flow-root

今天开始你可以使用display:flow-root。这周Firefox 53和Chrome 58两大主流浏览器在这周都发布相关消息:支持flow-root属性值。

来看一个简单的示例,比如我们一个这样的结构:

浮动元素

浮动元素

我们的CSS是这样的:

.floatElement{ float: left; /*或者right*/ }

1
2
3
.floatElement{
    float: left; /*或者right*/
}

如果仅这样操作,都会造成容器wrapper的高度塌陷。以前我们都是通过clearfix的方案(最常用的吧)来解决:

.wrapper::after { content:''; display: table; clear: both }

1
2
3
4
5
.wrapper::after {
    content:'';
    display: table;
    clear: both
}

上面的解决方案都是老的,其实今天我们可以在.wrapper容器上这样使用就可以达到类似clearfix的效果:

.wrapper{ display: flow-root; }

1
2
3
.wrapper{
    display: flow-root;
}

虽然主流浏览器Firefox 53+Chrome 58+Opera 45+都支持flow-root属性(有关于浏览器对该属性的兼容性,可以通过Caniuse.com来查询)。但实际当中,我们必竟有很多业务需求是需要兼容一些低版本的。对于一位CSS的极度爱好者,总是喜欢在项目中不断的尝试使用一些新特性。为了更好对flow-root做降级处理,我们可以通过CSS的条件属性@supports()来做相应的处理。比如上面的代码我们可以这样使用:

.floatElement{ float: left; /*或者right*/ } .wrapper::after { content:''; display: table; clear: both } @supports(display:flow-root){ .wrapper{ display: flow-root; } .wrapper::after{ content:none; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.floatElement{
    float: left; /*或者right*/
}
.wrapper::after {
    content:'';
   display: table;
   clear: both
}
@supports(display:flow-root){
    .wrapper{
        display: flow-root;
    }
    .wrapper::after{
        content:none;
    }
}

当然你还可以把这样使用:

.floatElement{ float: left; /*或者right*/ } @supports not (display:flow-root) { .wrapper::after { content: ''; display: table; clear:both; } }

1
2
3
4
5
6
7
8
9
10
.floatElement{
    float: left; /*或者right*/
}
@supports not (display:flow-root) {
    .wrapper::after {
        content: '';
        display: table;
        clear:both;
    }
}

是不是很意思呀。我们来看一个@Rachel Andrew在Codepen上面写的一个示例:

这里使用到了CSS的@supports(),如果你从未接触过,建议你点击这里进行阅读。

1)块级格式化上下文会阻止外边距叠加

当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加。换句话说,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。

总结

这篇文章简单的介绍了CSS中的一个新属性flow-root,简单的讲他是最新一种BFC,也是最新的浮除浮动的方案。虽然目前仅几个最新浏览器支持,但完全可以通过@supports()属性做完美降级处理。

2 赞 2 收藏 评论

图片 3

2)块级格式化上下文不会重叠浮动元素

根据规定,一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。这就意味着浏览器将会给块级格式化上下文创建隐式的外边距来阻止它和浮动元 素的外边距叠加。由于这个原因,当给一个挨着浮动的块级格式化上下文添加负的外边距时将会不起作用(Webkit和IE6在这点上有一个问题——可以看这 个测试用例)。 

3)块级格式化上下文通常可以包含浮动

详见: W3C CSS2.1 - 10.6.7 'Auto' heights for block formatting context roots    

通俗地来说:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC任然属于文档中的普通流。

至此,您或许明白了为什么 overflow:hidden或者auto可以闭合浮动了,真是因为父元素创建了新的BFC。对于张鑫旭在对《overflow与zoom”清除浮动”的一些认识 》一文中对于用包裹来解释闭合浮动的原理,我觉得是不够严谨的,而且没有依据。并且说道“Firefox等浏览器并没有haslayout的概念”,那么现代浏览器是有BFC的,从表现上来说,hasLayout 可以等同于 BFC。

IE6-7的显示引擎使用的是一个称为布局(layout)的内部概念,由于这个显示引擎自身存在很多的缺陷,直接导致了IE6-7的很多显示 bug。当我们说一个元素“得到 layout”,或者说一个元素“拥有 layout” 的时候,我们的意思是指它的微软专有属性 hasLayout  ... rties/haslayout.asp 为此被设为了 true 。IE6-7使用布局的概念来控制元素的尺寸和定位,那些拥有布局(have layout)的元素负责本身及其子元素的尺寸设置和定位。如果一个元素的 hasLayout 为false,那么它的尺寸和位置由最近拥有布局的祖先元素控制。

触发hasLayout的条件:

  • position: absolute   
  • float: left|right   
  • display: inline-block   
  • width: 除 “auto” 外的任意值   
  • height: 除 “auto” 外的任意值 (例如很多人清除浮动会用到 height: 1%  )   
  • zoom: 除 “normal” 外的任意值 (MSDN)  ... properties/zoom.asp   
  • writing-mode: tb-rl (MSDN)  ... ies/writingmode.asp

在 IE7 中,overflow 也变成了一个 layout 触发器:

  • overflow: hidden|scroll|auto ( 这个属性在IE之前版本中没有触发 layout 的功能。 )  
  • overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前IE版本中同样没有触发 layout 的功能)

hasLayout更详细的解释请参见 old9翻译的 大名鼎鼎的 《On having layout》一文(英文原文:

IE8使用了全新的显示引擎,据称不使用 hasLayout属性了,因此解决了很多深恶痛绝的bug。

综上所述:

在支持BFC的浏览器(IE8+,firefox,chrome,safari)通过创建新的BFC闭合浮动;

在不支持 BFC的浏览器 (IE6-7),通过触发 hasLayout 闭合浮动。

三、闭合浮动方法——精益求精

上面已经列举了7种闭合浮动(第七种即:after伪元素)的方法,通过第三节分析的原理,我们发现其实更多的:display:table- cell,display:inline-block等只要触发了BFC的属性值都可以闭合浮动。从各个方面比较,after伪元素闭合浮动无疑是相对比 较好的解决方案了,下面详细说说该方法。

.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; }

.clearfix { *zoom:1; }

1) display:block 使生成的元素以块级元素显示,占满剩余空间;

2) height:0 避免生成内容破坏原有布局的高度。

3) visibility:hidden 使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互;

4)通过 content:"."生成内容作为最后一个元素,至于content里面是点还是其他都是可以的,例如oocss里面就有经典的 content:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",有些版本可能content 里面内容为空,一丝冰凉是不推荐这样做的,firefox直到7.0 content:”" 仍然会产生额外的空隙;

5)zoom:1 触发IE hasLayout。

通过分析发现,除了clear:both用来清除浮动的,其他代码无非都是为了隐藏掉content生成的内容,这也就是其他版本的闭合浮动为什么会有font-size:0,line-height:0。

 

精益求精方案一:

相对于空标签闭合浮动的方法代码似乎还是有些冗余,通过查询发现Unicode字符里有一个“零宽度空格”,也就是U+200B ,这个字符本身是不可见的,所以我们完全可以省略掉 visibility:hidden了

.clearfix:after {content:"200B"; display:block; height:0; clear:both; }

.clearfix { *zoom:1; }.

精益求精方案二:

由Nicolas Gallagher 大湿提出来的,原文:A new micro clearfix hack,该方法也不存在firefox中空隙的问题。

/* For modern browsers */

.cf:before,.cf:after {

content:"";

display:table;

}

.cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */

.cf { zoom:1; }

 需要注意的是:

上面的方法用到了  :before伪元素,很多人对这个有些迷惑,到底我什么时候需要用before呢?为什么方案一没有呢?其实它是用来处理margin边距重叠的,由于 内部元素 float 创建了BFC,导致内部元素的margin-top和 上一个盒子的margin-bottom 发生叠加。如果这不是你所希望的,那么就可以加上before,如果只是单纯的闭合浮动,after就够了!并不是如同大漠《Clear Float》一文所说的:但只使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug,这不是bug,是BFC应该有的特性。

图片 4

请看优雅的Demo

进一步了解请看: 《clearfix改良及overflow:hidden详解【译】》

在实际开发中,改进方案一由于存在Unicode字符不适合内嵌CSS的GB2312编码的页面,使用方案7完全可以解决我们的需求了,改进方案二 等待大家的进一步实践。方案3、4通过overflow闭合浮动,实际上已经创建了新的 块级格式化上下文,这将导致其布局和相对于浮动的行为等发生一系列的变化,清除浮动只不过是一系列变化中的一个作用而已。所以为了闭合浮动去改变全局特 性,这是不明智的,带来的风险就是一系列的bug,比如firefox 早期版本产生 focus,截断绝对定位的层等等。始终要明白,如果单单只是需要闭合浮动,overflow就不要使用,而不是某些文章所说的“慎用”。

前前后后花了三天写完了这篇文章。如果觉得本文对您有帮助,您的留言就是对我最大的支持,同时由于精力有限,欢迎指出文中错误与不足,共勉之!

参考资料:

 

  • Page breaks and block-formatting contexts: Allowed page breaks (13.3.3)
  • Clearfix and block formatting contexts: Everything you Know about Clearfix is Wrong
  • Block formating contexts, “hasLayout” – IE Window vs CSS2.1 browsers: simulations.
  • New block formatting contexts next to floats
  • Control Block Formatting Context
  • On having layout, [译文]On having layout  
  • “HasLayout” Overview
  • hasLayout Property
  • IE hasLayout

 

 

转自:

一、清除浮动和闭合浮动 所谓清除浮动,是指显示上正确...

本文由设计建站发布,转载请注明来源:那多少个年我们意气风发道消逝过的成形