面试题之css(一)

1. 什么是回流和重绘?它们和 BFC 有什么关系?

回流(Reflow)

回流是指当元素的尺寸、位置、或其他属性发生变化时,浏览器重新计算文档的布局(或几何结构)的过程。任何会影响元素几何属性的操作都会触发回流,例如:

  • 页面一开始渲染时
  • 添加或删除 DOM 元素
  • 改变元素的尺寸、边距、填充或边框
  • 改变元素的内容
  • 改变页面的样式(例如改变displaypositionfloat等属性)
  • 调整浏览器窗口大小

回流是一个代价较高的操作,因为它不仅影响单个元素,还可能影响它的子元素、兄弟元素或父元素。因此,频繁的回流会对页面性能产生负面影响。

重绘(Repaint)

重绘是指当元素的外观发生变化但不会影响布局时,浏览器重新绘制元素的过程。例如:

  • 改变元素的背景颜色、文字颜色
  • 改变元素的阴影效果
  • 改变元素的可见性(例如visibility属性)

重绘的代价通常比回流要低,因为它只需要更新元素的外观,而不需要重新计算其布局。

BFC 与回流的关系

回流(Reflow)是指浏览器重新计算元素几何属性(位置和大小)并重新布局的过程。回流会影响页面性能,尤其是当回流影响到大量元素时。

隔离性减少回流:

BFC 通过其特性提供了一种布局隔离机制,使得 BFC 内部的布局变化不会影响 BFC 外部的布局。这样做有以下好处:

  • 局部化布局变化:当一个 BFC 内部的元素发生变化(例如尺寸变化或位置变化)时,浏览器只需要重新计算这个 BFC 内部的布局,而不需要重新计算整个文档的布局。这大大减少了回流的范围和影响。

    例如,如果一个元素的高度发生变化,而这个元素是一个 BFC 的子元素,则只有这个 BFC 内部的元素需要重新布局,而不是整个页面。

  • 降低回流频率:由于 BFC 隔离了内部和外部的布局变化,不同 BFC 之间的变化不会互相影响。这意味着,即使一个 BFC 内部频繁变化,也不会导致其他部分的频繁回流,从而减少整体的回流频率。

BFC 与重绘的关系

重绘(Repaint)是指当元素的外观(如颜色、背景等)发生变化时,浏览器重新绘制这些元素的过程。重绘的代价通常比回流低,但频繁的重绘也会影响性能。

隔离性对重绘的影响:

BFC 的隔离性主要影响回流,但间接也能减少重绘的开销。由于 BFC 内部的布局变化不会导致外部布局的变化,减少了需要重新绘制的区域,优化了渲染性能。


2. 设备像素,CSS 像素,设备独立像素,DPR,PPI 之间的区别

设备像素(Device Pixel)

设备像素是物理屏幕上的一个点,是显示器或移动设备屏幕的最小单位。设备像素的数量决定了屏幕的分辨率。

CSS 像素(CSS Pixel)

CSS 像素是 Web 开发中使用的抽象单位,它与设备像素之间存在一定的关系,但并不直接映射到具体的物理像素上。浏览器会根据设备像素比(Device Pixel Ratio,简称 DPR)将 CSS 像素转换为实际的设备像素。

设备独立像素(Device-Independent Pixel, DIP)

设备独立像素是一个抽象的单位,用来在不同设备上保持一致的显示效果。在 CSS 中,1 个设备独立像素通常等于 1 个 CSS 像素。设备独立像素的概念有助于实现响应式设计和跨设备兼容性。

设备像素比(Device Pixel Ratio, DPR)

设备像素比是指设备像素与设备独立像素的比值,表示一个 CSS 像素对应的设备像素数目。例如,如果一个设备的 DPR 为 2,那么 1 个 CSS 像素将对应 4 个设备像素(2x2)。

像素密度(Pixels Per Inch, PPI)

像素密度是指每英寸(inch)的屏幕上的像素数量,通常用于描述屏幕的清晰度和显示质量。PPI 越高,屏幕显示的细节就越丰富。


3. 什么是 CSS 选择器?

元素选择器(Type Selector)

选择所有指定类型的元素。
示例:p { color: red; } 选择所有 <p> 元素。

类选择器(Class Selector)

选择具有特定类名的元素。
示例:.className { color: blue; } 选择所有具有 class="className" 的元素。

ID 选择器(ID Selector)

选择具有特定 ID 的元素。
示例:#idName { color: green; } 选择具有 id="idName" 的元素。

属性选择器(Attribute Selector)

选择具有特定属性的元素。
示例:[type="text"] { border: 1px solid black; } 选择所有 type="text" 的元素。

伪类选择器(Pseudo-classes)

选择处于特定状态的元素。
示例:a:hover { color: orange; } 选择鼠标悬停的 <a> 元素。

伪元素选择器(Pseudo-elements)

选择元素的特定部分。
示例:p::first-line { font-weight: bold; } 选择所有 <p> 元素的第一行。

组合选择器(Combinators)

组合多个选择器来选择元素。

示例:

  • 子选择器(Child Selector):ul > li { color: purple; }
  • 后代选择器(Descendant Selector):div p { color: brown; }
  • 相邻兄弟选择器(Adjacent Sibling Selector):h1 + p { margin-top: 0; }
  • 通用兄弟选择器(General Sibling Selector):h1 ~ p { margin-top: 0; }

选择器优先级

CSS 选择器的优先级由以下规则确定,从低到高:

  1. 元素选择器和伪元素(如 div, p, ::before, ::after
  2. 类选择器、属性选择器和伪类(如 .class, [type="text"], :hover
  3. ID 选择器(如 #id
  4. 内联样式(直接在元素上使用 style 属性)
  5. 重要性(!important):可以打破上述所有规则,具有最高优先级。

优先级依次为:内联样式 > ID 选择器 > 类选择器、属性选择器、伪类选择器 > 元素选择器、伪元素选择器。!important 具有最高优先级,可以覆盖其他所有样式声明。

优先级冲突的解决

当多个选择器匹配同一个元素并且具有相同的优先级时,后定义的样式将覆盖前面定义的样式。这是因为 CSS 遵循“层叠”规则,后面的样式会覆盖前面的样式。