# CSS

# 对BFC的理解,如何创建BFC

面试官:请说说什么是BFC?大白话讲清楚 (opens new window)

# BFC到底是什么东西

BFC 全称:Block Formatting Context, 名为 "块级格式化上下文"。

W3C官方解释为:BFC它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,Block Formatting Context提供了一个环境,HTML在这个环境中按照一定的规则进行布局。

简单来说就是,BFC是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。那么怎么使用BFC呢,BFC可以看做是一个CSS元素属性

# 怎样触发BFC

这里简单列举几个触发BFC使用的CSS属性

  • overflow: hidden
  • display: inline-block
  • position: absolute
  • position: fixed
  • display: table-cell
  • display: flex

# BFC的规则

  • BFC就是一个块级元素,块级元素会在垂直方向一个接一个的排列
  • BFC就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签
  • 垂直方向的距离由margin决定, 属于同一个BFC的两个相邻的标签外边距会发生重叠
  • 计算BFC的高度时,浮动元素也参与计算。

# BFC的作用

  • 解决margin的重叠问题:由于BFC是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个BFC,就解决了margin重叠的问题。
  • 解决高度塌陷的问题:在对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。解决这个问题,只需要把父元素变成一个BFC。常用的办法是给父元素设置overflow:hidden
  • 创建自适应两栏布局:可以用来创建自适应两栏布局:左边的宽度固定,右边的宽度自适应。
.left {
     width: 100px;
     height: 200px;
     background: red;
     float: left;
 }
 .right {
     height: 300px;
     background: blue;
     overflow: hidden;
 }
 
<div class="left"></div>
<div class="right"></div>

左侧设置float:left,右侧设置overflow: hidden。这样右边就触发了BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠,实现了自适应两栏布局。

# BFC 如何影响 margin 重叠?

BFC 可以在某些情况下防止 margin 重叠,但并不是所有情况。具体来说,BFC 可以防止以下几种情况的 margin 重叠:

  1. 父元素与子元素之间的 margin 重叠
    • 当一个块级元素包含另一个块级元素时,子元素的 margin 会与父元素的 margin 重叠。如果父元素形成了一个 BFC,这种重叠会被防止。
  2. 浮动元素与相邻元素之间的 margin 重叠
    • 浮动元素的 margin 有时会与相邻的非浮动元素的 margin 重叠。如果浮动元素和相邻元素都形成了 BFC,这种重叠会被防止。

# 为什么上下相邻的两个容器的 margin 仍然会重叠?

即使两个容器都形成了 BFC,它们之间的 margin 仍然可能会重叠,因为 BFC 主要影响的是内部元素的布局,而不是外部元素之间的关系。具体来说:

  1. BFC 影响的是内部布局

    • BFC 主要用于防止内部元素的 margin 与外部元素的 margin 重叠,而不是防止外部元素之间的 margin 重叠。
  2. 外部 margin 重叠

    • 即使两个容器都形成了 BFC,它们仍然是独立的块级元素,它们之间的 margin 仍然会按照标准的 margin 重叠规则进行处理。

# px、em、rem

三者的区别:

  • px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
  • em和rem相对于px更具有灵活性,他们是相对长度单位,其长度不是固定的,更适用于响应式布局。
  • em是相对于其父元素来设置字体大小,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而rem是相对于根元素,这样就意味着,只需要在根元素确定一个参考值。

使用场景:

  • 对于只需要适配少部分移动设备,且分辨率对页面影响不大的,使用px即可 。
  • 对于需要适配各种移动设备,使用rem,例如需要适配iPhone和iPad等分辨率差别比较挺大的设备。

# 1px 问题

1px问题是指在高DPI(dots per inch,每英寸点数)或高PPI(pixels per inch,每英寸像素数)屏幕,尤其是Retina屏幕(苹果公司对于高分辨率显示屏的一种称呼)上,当使用CSS定义1px宽度的边框或线条时,实际渲染出来的线条可能会显得过粗。这是因为移动设备的屏幕像素密度通常比传统计算机屏幕高得多,导致CSS中定义的1px并不等同于物理屏幕上的1个像素点。例如,在一个2倍DPR(device pixel ratio,设备像素比)的屏幕上,1个CSS像素实际上会被渲染为2x2=4个物理像素。因此,为了使边框或线条在高分辨率屏幕上看起来更加细腻,开发者们需要寻找方法来实现视觉上接近1px的边框或线条。

# 解决1px问题的方法

  1. 使用0.5px边框:直接在CSS中设置border: 0.5px solid #000;。然而,这种方法在一些旧版本的浏览器或设备上可能不被支持,会自动四舍五入到最接近的整数值。
  2. 使用伪元素和transform:创建一个伪元素,并使用transform: scaleY(0.5);来缩小其高度,从而达到视觉上0.5px的效果。这种方法兼容性较好,广泛应用于各种设备和浏览器。
  3. 使用box-shadow:通过设置box-shadow: 0 0.5px 0 #000;来模拟边框效果。不过,这种方法可能会产生轻微的模糊感,且不是所有情况下都适用。
  4. 使用SVG:利用SVG的矢量特性,可以精确控制线条的粗细,不受屏幕分辨率的影响。这种方法适用于需要绘制复杂形状或路径的情况。
  5. 使用viewport单位和REM单位:通过动态计算并设置合适的viewport单位(如vw, vh)或REM单位,结合媒体查询,根据不同的屏幕尺寸和DPR值来调整边框的宽度。
  6. 使用图片作为边框:虽然不太常用,但也可以使用预设好的1px宽度的图片作为边框背景,通过CSS的border-image属性来应用。这种方法的缺点是灵活性较差,难以适应不同的颜色需求。
上次更新: 11/6/2024, 4:10:52 PM