revert-layer: deshacer una capa entera
La palabra clave que retrocede por capas en lugar de por orígenes, qué ocurre cuando no hay capa anterior, y por qué deshace la contribución completa de la capa y no solo una declaración.
revert retrocede al origen anterior de la cascada. revert-layer hace lo mismo un escalón más abajo: retrocede a la capa anterior dentro del mismo origen. Es la única de las palabras clave globales que no tiene sentido sin haber entendido @layer, y también la única que permite decir “para este elemento, haz como si esta capa no hubiera dicho nada”, que resulta ser una operación mucho más útil de lo que parece.
- Predecir el valor resultante de
revert-layersegún la capa desde la que se declare. - Explicar qué pasa cuando no hay ninguna capa anterior en el mismo origen.
- Distinguir deshacer una declaración de deshacer la contribución de una capa.
- Elegir entre las cinco palabras de retroceso y defecto según el caso.
Qué hace exactamente
Si el valor cascadeado de una propiedad es revert-layer, el motor recalcula el valor como si ninguna regla de la capa actual hubiera declarado esa propiedad para ese elemento. El ejemplo mínimo, tomado de la especificación, lo muestra sin ambigüedad:
@layer una {
div { height: 100px; }
}
@layer dos {
div { height: 200px; }
div { height: revert-layer; }
}
El resultado es 100px. Dentro de la capa dos, la segunda regla gana a la primera por orden, y su valor revert-layer provoca que se descarte lo que la capa dos aportaba, con lo que el valor pasa a ser el de la capa una.
Fíjate en un detalle del ejemplo: también se descartó el 200px, que estaba en la misma capa y en otra regla. No es que revert-layer sustituya a la declaración inmediatamente anterior; deshace la contribución de la capa completa para esa propiedad.
Hay además un comportamiento que conviene tener presente porque produce efectos a distancia: las propiedades que forman pareja lógica y física se revierten juntas. Revertir block-size revierte también el height declarado en esa capa, y viceversa, porque el motor las trata como el mismo grupo.
Desde dónde se retrocede
Tres casos, y los tres se dan en la práctica.
Desde una capa intermedia, se retrocede a la capa anterior, que es el caso del ejemplo.
Desde CSS que no está en ninguna capa, se retrocede a la última capa explícita. Recuerda que lo no encapado vive en una capa implícita situada al final, así que revert-layer fuera de toda capa significa “que decida la última de mis capas”. Es una forma cómoda de anular sobrescrituras sueltas sin borrarlas.
Desde la primera capa, o cuando no hay ninguna declaración de menor precedencia en el mismo origen, el retroceso continúa hacia el origen anterior. En ese caso revert-layer acaba comportándose como revert, y el valor resultante es el que aportaría la hoja del navegador o del usuario.
Queda un caso especial que la especificación trata aparte y que conviene conocer aunque sea raro: revert-layer en un estilo importante pegado al elemento solo revierte los estilos pegados al elemento y el origen de animación intermedio, y no las reglas importantes de autor que haya en medio. La razón es evitar que una declaración en el atributo style pueda desmontar de un plumazo toda la jerarquía de capas importantes del documento.
La diferencia entre “anular una declaración” y “deshacer la contribución de una capa” parece un matiz y es una capacidad nueva. Piensa en un sistema con una capa tema que aplica color, fondo, borde y sombra a varios componentes. Antes de revert-layer, sacar un componente concreto del tema exigía enumerar todas las propiedades que el tema hubiera tocado y devolverlas una a una a un valor que tenías que averiguar leyendo el tema. Cualquier propiedad nueva que el tema añadiera después rompía silenciosamente tu exclusión, porque tu lista se había quedado corta y nadie te avisaba. Con revert-layer la exclusión se declara en términos de la capa y no de sus propiedades, y por tanto se mantiene correcta cuando el tema cambia. Esto tiene una consecuencia de diseño que va más allá del truco: convierte a las capas en algo con lo que se puede operar desde dentro del CSS, y no solo en un orden fijo declarado arriba. Puedes construir zonas que renuncian a una capa, variantes que se saltan un nivel del sistema, o modos de depuración que desactivan una capa entera para inspeccionar qué aportaba realmente. Y ahí está el uso que más rentabiliza el aprendizaje: cuando no sabes qué está poniendo una capa concreta sobre un elemento, escribe una regla que revierta esa capa para ese elemento con all: revert-layer, mira el resultado, y tendrás la respuesta exacta sin leer una línea del CSS ajeno. Es diagnóstico por diferencia, y es mucho más rápido que auditar selectores.
La familia completa
Cinco palabras que retroceden o rellenan, ordenadas de menos a más contexto que tienen en cuenta:
| Palabra | Retrocede a |
|---|---|
initial |
El valor inicial que define la especificación de la propiedad |
inherit |
El valor calculado del padre |
unset |
inherit o initial según si la propiedad es heredable |
revert-layer |
La capa anterior del mismo origen, y si no hay, al origen anterior |
revert |
El origen anterior completo |
Existe una sexta en el borrador, revert-rule, que retrocedería a la regla anterior en lugar de a la capa. Es la más reciente de la familia y no forma parte de lo que puedes escribir hoy con garantías; menciónala solo para saber que la idea está sobre la mesa.
Una precisión sobre las animaciones que distingue a las dos palabras de retroceso: para revert, el origen de animación se considera parte del origen de autor y se descarta junto con él. Para revert-layer no: el origen de animación se comporta a estos efectos como una capa propia. La consecuencia práctica es que revert-layer puede devolverte el valor que aporta una animación en curso, y revert no.
Usos concretos
Sacar un componente de un tema. El caso descrito arriba, en su forma más directa:
@layer base, tema, componentes;
@layer componentes {
.sin-tema, .sin-tema * {
all: revert-layer;
}
}
Cuidado con la brocha: all: revert-layer revierte todas las propiedades, incluidas las que sí querías conservar del tema. En un sistema real es más frecuente y más seguro revertir un grupo acotado.
Anular una variante bajo una condición. Dentro de una consulta, devolver una propiedad al estado que tenía sin esa capa, sin necesidad de repetir su valor:
@layer componentes {
.tarjeta { box-shadow: 0 1px 3px oklch(0% 0 0 / 0.2); }
@media (prefers-contrast: more) {
.tarjeta { box-shadow: revert-layer; }
}
}
Esto es mejor que escribir box-shadow: none, porque si una capa anterior aportaba una sombra distinta para contraste alto, se respeta.
Diagnosticar. Aplicar temporalmente all: revert-layer a un elemento y comparar. Lo que cambie es exactamente lo que aportaba la capa actual.
Con esto queda cerrado el mecanismo de defecto. Falta ver dónde encaja todo esto dentro del recorrido completo que hace un valor desde tu hoja de estilos hasta la pantalla, que es la cadena de valores.