CSS 属性继承控制:`all: unset` 与 `all: revert` 在重置样式中的区别

CSS 属性继承控制:all: unsetall: revert 在重置样式中的区别

大家好!今天我们来深入探讨 CSS 中两个非常强大的属性:all: unsetall: revert,特别是在重置样式方面的应用和区别。 这两个属性都用于重置元素的所有样式,但它们的工作方式却截然不同,理解它们之间的差异对于编写可维护且易于理解的 CSS 至关重要。

1. CSS 属性继承机制回顾

在深入 all: unsetall: revert 之前,我们需要先简要回顾一下 CSS 的属性继承机制。 CSS 样式表是由许多规则组成的,这些规则定义了元素的外观。 当一个元素没有显式地指定某个属性值时,它会尝试从其父元素继承该属性的值。

并非所有的 CSS 属性都可以被继承。 例如,widthheightmarginpaddingborder 等属性默认情况下是不被继承的。 可以通过 inherit 关键字强制继承某个属性。

2. all 属性

all 属性是一个简写属性,用于一次性设置元素的所有 CSS 属性的初始值、继承值或取消设置。 它允许我们一次性控制所有属性的 inheritance 和 cascading 行为。 all 属性本身不具备继承性,设置在父元素上的 all 不会影响子元素,除非子元素本身显式或隐式地继承了某些属性。

3. all: unset 详解

all: unset 关键字将元素的所有属性重置为它们未设置状态时的值。 这意味着:

  • 如果属性是可继承的:该属性的值将被设置为 inherit,即从父元素继承。
  • 如果属性是不可继承的:该属性的值将被设置为它的初始值(initial value),这是 CSS 规范中定义的每个属性的默认值。

换句话说,unset 关键字会移除所有显式应用于该元素的样式,并根据属性的继承性,要么恢复到继承的值,要么恢复到初始值。

代码示例:

<!DOCTYPE html>
<html>
<head>
<style>
  body {
    font-family: sans-serif;
    color: blue;
  }

  .container {
    background-color: lightgray;
    padding: 20px;
    border: 1px solid black;
  }

  .unset-example {
    all: unset; /* 应用 all: unset */
  }

  .initial-values {
    display: inline-block;
    padding: 5px;
    border: 1px solid red;
    width: 200px; /* 不可继承 */
    color: green; /* 可继承 */
  }

</style>
</head>
<body>

<div class="container">
  <div class="initial-values">
    This is the initial state.
  </div>
  <div class="unset-example initial-values">
    This is with all: unset.
  </div>
</div>

</body>
</html>

分析:

  • .container 元素定义了背景颜色、内边距和边框。
  • .initial-values 元素定义了内联块显示,内边距,边框,宽度和文本颜色。
  • .unset-example 元素同时拥有 .initial-values.unset-example 这两个类。
  • 由于 .unset-example 应用了 all: unset,所以它会重置所有样式。

结果:

  • .unset-examplewidth 属性是不可继承的,因此它会重置为初始值 auto (假设没有其他影响宽度的样式规则)。
  • .unset-examplecolor 属性是可继承的,因此它会从父元素(body)继承 blue
  • .unset-example 的其他属性(如背景颜色、内边距和边框)由于在 .initial-values 中定义,并且 .unset-example 重置了这些属性,所以会恢复到它们的初始值(通常是 none0 等)。如果这些属性可以继承,那么会从父元素继承。

表格总结 all: unset

属性类型 行为 示例
可继承 重置为 inherit,从父元素继承 color: blue (如果父元素设置了颜色,子元素将继承该颜色)
不可继承 重置为属性的初始值 (CSS 规范中定义的默认值) width: auto (通常,元素的宽度将根据内容自动调整)

4. all: revert 详解

all: revert 关键字将元素的所有属性恢复到用户代理样式表(浏览器默认样式)或用户样式表(用户自定义样式)中指定的值。 这意味着:

  • 它会撤销当前样式表中对元素所做的所有更改,包括来自 CSS 文件、<style> 标签和内联样式表的样式。
  • 它会查找用户代理样式表(浏览器默认样式)中该属性的默认值,并将该值应用于元素。
  • 如果用户定义了用户样式表,则会应用用户样式表中的值。

revert 的关键在于它会考虑到样式表的层叠顺序,并恢复到较低优先级的样式。 它不会像 unset 那样仅仅重置为初始值或继承值,而是试图恢复到更早的状态,即浏览器或用户定义的样式。

代码示例:

<!DOCTYPE html>
<html>
<head>
<style>
  body {
    font-family: sans-serif;
    color: blue;
  }

  .container {
    background-color: lightgray;
    padding: 20px;
    border: 1px solid black;
  }

  .revert-example {
    all: revert; /* 应用 all: revert */
  }

  .initial-values {
    display: inline-block;
    padding: 5px;
    border: 1px solid red;
    width: 200px; /* 不可继承 */
    color: green; /* 可继承 */
  }

</style>
</head>
<body>

<div class="container">
  <div class="initial-values">
    This is the initial state.
  </div>
  <div class="revert-example initial-values">
    This is with all: revert.
  </div>
</div>

</body>
</html>

分析:

  • .container 元素定义了背景颜色、内边距和边框。
  • .initial-values 元素定义了内联块显示,内边距,边框,宽度和文本颜色。
  • .revert-example 元素同时拥有 .initial-values.revert-example 这两个类。
  • 由于 .revert-example 应用了 all: revert,它会恢复到浏览器默认样式或用户样式(如果存在)。

结果:

  • .revert-example 的所有样式都将被浏览器默认样式覆盖。 例如,display 可能会恢复到 inlinepaddingborder 可能会消失,文本颜色可能会恢复到浏览器的默认颜色。 具体的表现取决于浏览器默认样式表的设置。
  • unset 不同,revert 不仅仅是重置为初始值或继承值,而是试图恢复到更早的默认状态。

表格总结 all: revert

样式来源 行为 示例
当前样式表 撤销当前样式表中对元素所做的所有更改 如果元素设置了 color: red;all: revert 会撤销该设置,恢复到浏览器默认颜色或用户样式。
用户代理样式表 恢复到浏览器默认样式表中的默认值 元素的 display 可能会恢复到 inline (浏览器的默认值)。
用户样式表 如果用户定义了用户样式表,则会应用用户样式表中的值,覆盖浏览器默认样式。 如果用户在用户样式表中设置了 font-family: Arial;all: revert 会应用该设置,即使浏览器默认字体是 Times New Roman。

5. all: revert-layer (CSS Cascade Layers)

CSS Cascade Layers(层叠层)引入了对层叠顺序的更精细控制。 all: revert-layer 属性将元素的所有属性恢复到当前层叠层中定义的样式。 如果在当前层叠层中没有找到该属性的定义,它会继续在较低优先级的层叠层中查找,直到找到该属性的定义或到达用户代理样式表。

@layer base {
  body {
    font-family: sans-serif;
    color: black;
  }
}

@layer theme {
  body {
    color: blue;
  }

  .revert-layer-example {
    color: red;
  }
}

.revert-layer-example {
    all: revert-layer; /* 应用 all: revert-layer */
}

在这个例子中,假设 base 层具有最低的优先级,而 theme 层具有较高的优先级。 .revert-layer-example 最初在 theme 层中被设置为红色。 应用 all: revert-layer 会将颜色恢复到 theme 层中之前的值,即 body 元素定义的蓝色。 如果 theme 层中没有定义颜色,它将回退到 base 层定义的黑色。 如果在任何层中都没有找到定义,它将回退到用户代理样式表。

revert-layer 使得在特定样式层内重置样式变得非常方便,而不会影响其他层的样式。

6. all: initial

为了完整起见,我们还需要提及 all: initial。 这个关键字将元素的所有属性设置为它们的 CSS 规范中定义的初始值。 与 unset 不同,它不会考虑属性的继承性,而是强制所有属性都使用它们的初始值。

7. unset vs revert:关键区别和使用场景

现在我们来总结一下 all: unsetall: revert 之间的关键区别,以及它们各自的使用场景:

  • 行为差异:

    • all: unset: 将属性重置为未设置状态时的值。 可继承属性设置为 inherit,不可继承属性设置为其初始值。
    • all: revert: 恢复到用户代理样式表或用户样式表中的值。 撤销当前样式表中对元素所做的更改。
  • 使用场景:

    • all: unset: 适用于需要清除元素的所有样式,并希望依赖继承或属性初始值的情况。 例如,在构建自定义组件时,可以先使用 unset 清除所有样式,然后根据需要重新定义样式。
    • all: revert: 适用于需要恢复到浏览器默认样式或用户自定义样式的情况。 例如,在 debugging 时,可以使用 revert 快速查看元素在没有自定义样式时的外观。 或者,在处理第三方库的样式冲突时,可以使用 revert 恢复到默认样式,避免样式污染。
  • 优先级:

    • all: unset 的优先级高于继承值和初始值。
    • all: revert 的优先级低于当前样式表中的样式,但高于用户代理样式表和用户样式表。

表格对比 all: unsetall: revertall: initial

属性 行为 优先级 使用场景
all: unset 可继承属性设置为 inherit (从父元素继承),不可继承属性设置为其初始值 (CSS 规范中定义的默认值)。 高于继承值和初始值。 清除元素的所有样式,并依赖继承或属性初始值。例如,构建自定义组件时,先清除所有样式,然后重新定义。
all: revert 恢复到用户代理样式表(浏览器默认样式)或用户样式表(用户自定义样式)中指定的值。撤销当前样式表中对元素所做的所有更改。如果存在 CSS Cascade Layers,all: revert 会恢复到层叠上下文中更早的样式。 低于当前样式表中的样式,但高于用户代理样式表和用户样式表。 恢复到浏览器默认样式或用户自定义样式。例如,debugging 时,快速查看元素在没有自定义样式时的外观。处理第三方库的样式冲突时,恢复到默认样式,避免样式污染。需要还原更早的样式层叠上下文。
all: initial 将元素的所有属性设置为它们的 CSS 规范中定义的初始值。 不考虑属性的继承性。 高于继承值和用户代理样式表,但低于显式设置的样式。 强制元素的所有属性都使用它们的初始值。通常用于创建一个干净的起点,但可能会导致意外的结果,因为它会覆盖所有继承的样式。

8. 最佳实践和注意事项

  • 谨慎使用 all 属性: all 属性非常强大,但也可能导致样式覆盖和难以调试。 在使用时要小心,确保你真正理解其影响。
  • 只在必要时使用: 不要滥用 all: unsetall: revert。 只在需要重置或恢复大量样式时才使用它们。
  • 考虑使用 CSS Reset 或 Normalize.css: 对于全局样式重置,建议使用成熟的 CSS Reset 或 Normalize.css 库,而不是手动使用 all 属性。 这些库已经过充分测试,并考虑了各种浏览器的兼容性问题。
  • 注意层叠顺序: revert 的行为受到层叠顺序的影响。 确保你理解样式表的优先级规则,以便正确地使用 revert
  • 结合 CSS Cascade Layers 使用 revert-layer 利用 CSS Cascade Layers 和 revert-layer 可以更好地控制样式的层叠和重置,提高代码的可维护性。

9. 示例:使用 all: unset 创建自定义按钮

这是一个使用 all: unset 创建自定义按钮的示例:

<!DOCTYPE html>
<html>
<head>
<style>
  .custom-button {
    all: unset; /* 清除所有默认样式 */
    display: inline-block;
    padding: 10px 20px;
    background-color: #4CAF50;
    color: white;
    text-align: center;
    text-decoration: none;
    font-size: 16px;
    border: none;
    cursor: pointer;
    border-radius: 5px;
  }

  .custom-button:hover {
    background-color: #3e8e41;
  }
</style>
</head>
<body>

<button class="custom-button">Click Me</button>

</body>
</html>

在这个例子中,我们首先使用 all: unset 清除了按钮的所有默认样式,然后重新定义了按钮的样式,包括背景颜色、文本颜色、内边距、边框和鼠标悬停效果。

示例:使用 all: revert 恢复到浏览器默认样式

<!DOCTYPE html>
<html>
<head>
<style>
  button {
    background-color: red;
    color: white;
    padding: 10px;
    border: none;
  }

  .revert-button {
    all: revert; /* 恢复到浏览器默认样式 */
  }
</style>
</head>
<body>

<button>Default Button</button>
<button class="revert-button">Reverted Button</button>

</body>
</html>

在这个例子中,我们首先定义了按钮的自定义样式,然后使用 all: revert.revert-button 元素的样式恢复到浏览器默认样式。

选择合适的重置方式取决于你的具体需求。 unset 适用于需要一个干净的起点,而 revert 适用于恢复到更早的状态。 revert-layer 更侧重于在特定的层叠层中进行重置。

希望今天的讲解能够帮助大家更好地理解 all: unsetall: revert 的区别和用法。

总结

all: unsetall: revert 都是强大的 CSS 属性,但它们的作用方式不同。 unset 用于重置为初始值或继承值,而 revert 用于恢复到用户代理或用户样式表。 理解它们之间的差异对于编写可维护和可预测的 CSS 代码至关重要。

更多IT精英技术系列讲座,到智猿学院

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注