了解CSS布局和BFC(块格式化上下文)

您可能从未听说过BFC(块格式设置上下文)一词,但是如果您使用CSS进行布局,则您可能已经知道它的作用。在本文中,我将解释创建块格式上下文的现有方法,以及为什么它在CSS布局中很重要,并向您展示一种新的创建方法。

一旦了解了CSS布局中的一些概念,它们便可以真正增强CSS的功能。本文是关于块格式化上下文(BFC)的。您可能从未听说过该术语,但是如果您曾经使用CSS进行过布局,则可能知道它是什么。了解BFC是什么,它为什么起作用以及如何创建BFC很有用,并且可以帮助您了解CSS中布局的工作原理。

在本文中,我将通过您熟悉的示例来说明BFC是什么。然后,我将向您展示display的新价值,只有在您了解BFC是什么以及为什么需要BFC之后,它才有意义。

什么是BFC?

通过一个简单的float示例,最容易理解块格式化上下文(BFC)的行为。在下面的示例中,我有一个框,其中包含一个向左浮动的图像和一些文本。

<div class="outer">
      <div class="float">I am a floated element.</div>
      I am text inside the outer box.
    </div>

.outer {
      border: 5px dotted rgb(214,129,137);
      border-radius: 5px;
      width: 450px;
      padding: 10px;
      margin-bottom: 40px;
    }

    .float {
      padding: 10px;
      border: 5px solid rgba(214,129,137,.4);
      border-radius: 5px;
      background-color: rgba(233,78,119,.4);
      color: #fff;
      float: left;  
      width: 200px;
      margin: 0 20px 0 0;
    }

如果我们有大量的文字,它会围绕浮动的图片,然后边框会围绕整个图片。

文本环绕一个float元素

如果我删除了一些文本,则表示图像周围没有足够的内容,并且由于float已从文档流中移出,因此边框会上升并在图像下方延伸到文本的高度。

如果没有足够的文本,边框将不考虑浮动元素所需的高度

发生这种情况的原因是,当我们浮动一个元素时,文本所在的框保持相同的宽度,为浮动元素留出空间的缩写是文本的线框。这就是为什么背景和边框会出现在浮动框后面的原因。

通常,有两种方法可以解决此布局问题。一种方法是使用clearfix hack,其作用是在文本和图像下方插入一个元素并将其设置为同时清除两者。另一种方法是使用溢出属性,其值不同于默认值visible。

.outer {
      overflow: auto;
    }

使用将overflow: auto导致边框框包含float

在CodePen运行

overflow以这种方式工作的原因是,使用除初始值之外的任何值visible都会创建一个BFC,并且BFC的功能之一就是它包含float

BFC是布局中的迷你布局

您可以将BFC视为页面内的迷你布局。一旦元素创建了BFC,所有内容都将包含在其中。如我们所见,这包括float,这些元素不再从边框的底部溢出来。BFC还导致其他一些有用的行为。

BFC防止margin塌陷

了解margin塌陷是另一项被低估的CSS技能。在下一个示例中,我有一个div,背景色为灰色。

这个div内部有两个段落。外部div元素的底边距为40像素;这些段落的顶部和底部边距也为20像素。

.outer {
       background-color: #ccc;
      margin: 0 0 40px 0;
    }

    p {
      padding: 0;
      margin: 20px 0 20px 0;
      background-color: rgb(233,78,119);
      color: #fff;
    }

由于p元素的边距和外部div的边距之间没有任何关系,因此两者将折叠,因此段落最终与框的顶部和底部齐平。我们在段落的上方和下方均看不到任何灰色。

边距坍塌,因此我们看不到盒子的顶部和底部是灰色的

但是,如果我们将框设为BFC,则现在包含段落及其边距,因此它们不会折叠,并且可以看到边距后面的容器的灰色背景。

.outer {
       background-color: #ccc;
      margin: 0 0 40px 0;
      overflow: auto;
    }

使用该容器,BFC的margin不会坍塌

在CodePen运行

BFC再一次完成了将子元素包含在其中的工作,阻止它们溢出。

BFC阻止content包裹float

您还将熟悉BFC的这种行为,因为它是使用float的任何列类型布局的工作方式。如果某个元素创建了BFC,则该元素将不会包装任何float。在以下示例中,我做了如下标记:

<div class="outer">
      <div class="float">I am a floated element.</div>
      <div class="text">I am text</div>
    </div>

具有float的元素向左浮动,因此div中紧随其后的文本将环绕浮动。

文本环绕float元素

我可以通过将包装文本的div设置为BFC来防止这种包装行为。

.text {
      overflow: auto;
    }

包含文本的div现在是BFC,因此文本不会自动换行

本质上,这是我们可以创建具有多列的float布局的方法。浮动项目也会为该项目创建一个BFC,因此,如果右边的一个比左边的一个高,那么我们的列就不会试图彼此环绕。

在CodePen运行

还有什么创造了BFC?

除了用于overflow创建BFC之外,其他一些CSS属性还会创建BFC。如我们所见,float元素会创建BFC。因此,您的浮动元素中将包含任何子元素。

在元素上使用position: absoluteposition: fixed

使用display: inline-blockdisplay: table-celldisplay: table-captiontable-celltable-captions为HTML元素的默认属性,他们为每个element将创建一个BFC。

using column-span: all,用于跨多列布局的列。除了将Flex和Grid项分别描述为Flex格式设置上下文和Grid格式设置上下文之外,Flex和Grid项还创建类似于BFC的内容。这反映了每个人都参与的布局类型。“块格式化上下文”表示该项目正在参与“块布局”,“ Flex格式化上下文”表示该项目正在参与“ Flex布局”。实际上,结果是相同的,包含float且边距不会崩溃。

创建BFC的新方法

使用overflow或使用其他方法创建BFC有两个问题。

首先,这些方法基于实际设计的目的会产生副作用。溢出方法会创建一个BFC并包含float,但是在某些情况下,您可能会发现不想要的滚动条或阴影被修剪了。这是由于事实,溢出属性旨在允许您告诉浏览器在溢出情况下该怎么做-导致滚动条或剪辑内容。浏览器完全按照您的指示执行操作!

即使在没有任何不良副作用的情况下,使用overflow也可能会使其他开发人员感到困惑。为什么将溢出设置为自动或滚动?原始开发者的意图是什么?他们是否需要此组件上的滚动条?

有用的是创建一种懒加载的BFC的方法,该BFC不会造成其他行为,只能创建该mini layout,并且能够安全地在其中进行操作。该方法不会引起任何意外的问题,并且还可以使开发人员明确其意图。CSS委员会认为这也可能非常方便,因此我们有了display属性的新值: flow-root

您可以display: flow-root在本文中的任何情况下使用创建新的BFC都是有利的-包含float,防止边距崩溃或防止项目包装float。

如果您的浏览器支持display: flow-root最新的Firefox或Chrome浏览器,则可以在CodePen中查看所有这些信息。

浏览器对display: flow-root的支持

flow-root

浏览器对flow-root的支持是有限的,但是会增加,即使您现在无法在代码中使用方便的flow-root功能,您现在也可以了解BFC是什么,以及在使用overflow或其他方法包含float的操作。例如,如果要在不支持的浏览器中为flex或grid布局创建后备,了解BFC将停止包裹float的项目这一事实非常有用。

您还了解一些关于浏览器如何布局网页的基本知识。尽管它们本身似乎无关紧要,但这些知识点可以缩短创建和调试CSS布局所需的时间。

参考

Understanding CSS Layout And The Block Formatting Context

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容