overflow创建的BFC和float创建的BFC 为什么会有这样的区别?

现在的css布局,浮动用的比较少了,但是还是想 问一下 浮动的BFC。

创建BFC的情况
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_display/...

overflow:hidden 创建的BFC

https://play.tailwindcss.com/kTidNfCuyn

image.png

特点:即便img 右侧没有足够的空间,这个BFC还是选择了在img的右侧,通过延申高度来放下文字

Float创建的BFC

https://play.tailwindcss.com/T78TTJPgxf
image.png
文字比较多的受直接到下一行显示,而不是在img右侧延申高度。

文字比较少的时候:
image.png

文字 再少
image.png

问题: 为什么会有这样的区别?

阅读 1.5k
avatarAI BotBETA

在CSS中,Block Formatting Context(BFC)是一个独立的渲染区域,它决定了其子元素如何布局,以及与其他元素的关系和相互作用。overflow: hiddenfloat都可以创建BFC。

overflow: hidden 创建的BFC

当使用overflow: hidden创建BFC时,该BFC会尽可能地扩展其高度以包含其内部的所有内容,即使这意味着它需要延伸到其包含块的外部。因此,当图片右侧没有足够的空间时,BFC会选择在图片的右侧延申高度来放下文字。这是因为overflow: hidden的BFC会考虑其所有内容,包括那些超出了其包含块边界的内容。

Float创建的BFC

相比之下,当使用float创建BFC时,该BFC的高度只会被其内部的块级元素所影响。如果BFC内部只有行内元素(如文本),那么BFC的高度将只会被这些行内元素所影响,而不会延申到其包含块的外部。因此,当文本不足以填满图片的右侧空间时,文本会直接跳到下一行显示,而不是在图片的右侧延申高度。

区别的原因

这两种BFC的区别主要是因为它们对内部内容的高度计算方式不同。overflow: hidden的BFC会考虑其所有内容的高度,而float的BFC则只会考虑其内部的块级元素的高度。这种差异导致了它们在处理内部内容布局时的不同行为。

在现代的CSS布局中,确实浮动(float)的使用已经相对较少,更多的是使用Flexbox和Grid等更现代、更灵活的布局方式。然而,理解浮动和BFC的概念对于理解CSS布局仍然非常重要,因为它们在一些特定的布局场景中仍然非常有用。

4 个回答

overflow创建的BFC和float创建的BFC它们都是BFC应该没有区别。故这里的行为不同跟是怎么产生的BFC是没有关系的。

这应该和block width的计算(width:auto or width: fit-content)、float元素流出normal flow以及float与之后的bfc不会发生重叠有关。

行为1:

  • float元素是流出normal flow,故后来的在normal flow中元素应该会视它不存在。
  • float相邻的bfc不会和该float元素的margin-box有重叠(设置上面图片的margin-right: 10px的话,图片的右侧和右侧的bfc之间会有空隙。)。
  • 既要视该float元素不存在又不和它重叠,该bfc会变窄,变窄到占据该行剩余的宽度。

    • 前提应该是widthauto的时候。

      • 此时,'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block,这里的width of containing block的值应该会自动变小,其他不设置都为0,进而width最终的计算值会变小。(如何你设置padding的话,会发现文字空间会被挤得更窄)
      • 如果该元素的最小内容宽度溢出了,也不会换行的,此时设置了overflow:hiddden溢出的部分被隐藏了。
    • 如果我们显示设置了width的值话,是不会自动调节它的大小的。如果设置width200px,此时剩余空间不足,当前行溢出?or移到下一行?

      • 应该会移动到下一行,这样显示的话比溢出的效果要好。

相关文档规定:
css2 9.4.1 block formatting context

This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats)

css2 bfc-next-to-float

The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself. ""If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space.They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.

行为2:

相关官方规定:
css2 blockwidth Floating, no-replaced elements

If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines(解读:应该说的是最大内容宽度) other than where explicit line breaks occur, and also calculate the preferred minimum width(解读:应该说的是最小内容宽度), e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, find the available width(解读:这里应该就是包含块的大小,300px,这里没有变窄?): in this case, this is the width of the containing block minus the used values of 'margin-left', 'border-left-width', 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width)(解读:当文本比较长的时候,最后取值应该是available width 。当文本较短的时,最后取值应该是preferred with。shrink-to-fit width应该和width:fit-content是一样的吧?长度算好了,就看它在哪一行了,当前行还是另起一行?另一个解答中说明该问题。).

BFC(Block Formatting Context)是CSS中的一个概念,它用于决定块级元素如何进行排版。在某些情况下,创建BFC可以解决元素溢出、边框合并等问题。

Overflow创建的BFC

当一个元素设置 overflow(溢出)属性为 autoscrollhidden 时,该元素会创建一个BFC。BFC的规则如下:

  1. 块级元素参与BFC。
  2. overflow 不是 visible 的块级元素。
  3. 没有浮动(float)的子元素。
  4. 没有 clear 的子元素。

Float创建的BFC

当一个元素应用了浮动(float)属性,并且没有设置 clear 属性时,该元素会创建一个BFC。BFC的规则对浮动元素稍有不同:

  1. 块级元素参与BFC。
  2. 元素应用了浮动(float)属性。
  3. 没有其他浮动(float)的兄弟元素。
  4. 没有 clear 的子元素。

区别

  • 布局范围:overflow创建的BFC包含整个元素,而float创建的BFC只包含浮动元素的范围。
  • 包含浮动:float创建的BFC可以包含浮动元素,而overflow创建的BFC不能。

使用场景

  • 清除浮动:通常使用clearfix清除浮动,但也可以使用overflow: hidden清除浮动。
  • 防止溢出:使用overflow可以防止子元素溢出父元素。

总结

虽然两者都能创建BFC,但它们的规则和用途有所不同。在实际使用中,根据具体需求选择使用overflow或float创建的BFC即可。

有很多种方法可以触发 BFC, 但是多少都带有一点副作用,如果希望没有副作用的方式来触发,那么可以使用 display: flow-root,会发现其行为和设置 overflow:hidden 是类似的。相反这也说明了使用 float 的方式其布局的行为是和其他方式是不同的,就如例子看到的当空间不足时就直接跳到下面。这个行为在规范中是有说明的 https://drafts.csswg.org/css2/#propdef-float,具体在第 7 条

  1. A left-floating box that has another left-floating box to its left may not have its right outer edge to the right of its containing block’s right edge. (Loosely: a left float may not stick out at the right edge, unless it is already as far to the left as possible.) An analogous rule holds for right-floating elements.

大概意思就是说,在这种场景下,如果浮动元素的右边碰到容器的右边,那么这个时候浮动元素需要放置在尽量左边的位置上,因此就会向下跳,让其尽量靠左。

推荐问题
宣传栏