## CSS @layer: El Problema de Especificidad Está Resuelto Las guerras de especificidad CSS han plagado a los desarrolladores por décadas. Hacks con `!important`, selectores demasiado específicos y escapes a CSS-in-JS eran soluciones comunes. En 2026, `@layer` tiene soporte universal y cambia fundamentalmente cómo organizamos estilos. ## Soporte de Navegadores (2026) | Navegador | Soporte | Notas | |-----------|---------|-------| | Chrome 99+ | Completo | Desde Marzo 2022 | | Edge 99+ | Completo | Basado en Chromium | | Firefox 97+ | Completo | Desde Feb 2022 | | Safari 15.4+ | Completo | Desde Marzo 2022 | **Soporte global: ~98%** Puedes usar `@layer` en todas partes sin fallbacks. ## El Problema que Resuelve @layer ### Antes: Pesadillas de Especificidad ```css /* Estilos del framework */ .btn { color: blue; } /* Tus estilos - misma especificidad, depende del orden */ .btn { color: red; } /* Adición posterior - necesita mayor especificidad */ button.btn { color: green; } /* Desesperación */ .btn { color: purple !important; } ``` ### Después: Orden Explícito de Capas ```css @layer framework, components, utilities; @layer framework { .btn { color: blue; } } @layer components { /* Siempre gana sobre framework, sin importar especificidad */ .btn { color: red; } } @layer utilities { /* Siempre gana sobre components */ .btn { color: green; } } ``` ## Cómo Funciona @layer ### Orden de Capas = Prioridad Las capas posteriores ganan sobre las anteriores, sin importar la especificidad del selector: ```css /* Declarar orden por adelantado */ @layer reset, base, components, utilities; @layer reset { /* Menor prioridad */ * { margin: 0; padding: 0; } } @layer utilities { /* Mayor prioridad */ .hidden { display: none !important; } } ``` ### Capas Anónimas Los estilos fuera de cualquier capa tienen la mayor prioridad: ```css @layer base { .card { background: white; } } /* Estilos sin capa ganan sobre TODAS las capas */ .card { background: gray; } ``` ## Patrones de Producción ### Patrón 1: Integración de Frameworks ```css /* Definir orden de capas */ @layer reset, vendor, components, utilities, overrides; /* Importar framework en capa vendor */ @import url('normalize.css') layer(vendor); @import url('tailwind-base.css') layer(vendor); @layer components { /* Tus estilos de componentes siempre ganan sobre vendor */ .card { /* No necesitas mayor especificidad */ } } @layer overrides { /* Fixes rápidos que ganan sobre todo lo que tiene capa */ .legacy-fix { margin-top: 10px; } } ``` ### Patrón 2: Arquitectura de Librería de Componentes ```css @layer tokens, base, layout, components, variants, utilities; @layer tokens { :root { --color-primary: #3b82f6; --spacing-md: 1rem; } } @layer base { body { font-family: system-ui; } h1, h2, h3 { line-height: 1.2; } } @layer layout { .container { max-width: 1200px; margin: 0 auto; } .grid { display: grid; } } @layer components { .btn { padding: var(--spacing-md); } .card { border-radius: 8px; } } @layer variants { .btn--primary { background: var(--color-primary); } .btn--large { padding: calc(var(--spacing-md) * 1.5); } } @layer utilities { .mt-4 { margin-top: 1rem; } .hidden { display: none; } } ``` ### Patrón 3: Aislamiento de Estilos de Terceros ```css @layer third-party, app; /* Todo lo de terceros va en una capa */ @layer third-party { @import url('some-widget.css'); @import url('date-picker.css'); } @layer app { /* Tus estilos siempre ganan */ .date-picker-override { /* Funciona sin !important o hacks de especificidad */ } } ``` ### Patrón 4: Sistema de Temas ```css @layer theme-base, theme-dark, theme-overrides; @layer theme-base { :root { --bg: white; --text: #1a1a1a; } } @layer theme-dark { [data-theme="dark"] { --bg: #1a1a1a; --text: white; } } @layer theme-overrides { /* Modo alto contraste, preferencias de usuario, etc. */ @media (prefers-contrast: high) { :root { --bg: white; --text: black; } } } ``` ## Capas Anidadas Las capas pueden anidarse para organización: ```css @layer components { @layer buttons { .btn { /* ... */ } } @layer cards { .card { /* ... */ } } } /* Referenciar capas anidadas con notación de punto */ @layer components.buttons { .btn-new { /* ... */ } } ``` ## @layer con @import Importar hojas de estilo externas en capas específicas: ```css /* Método 1: En declaración @import */ @import url('bootstrap.css') layer(vendor); /* Método 2: Envolver imports */ @layer vendor { @import url('bootstrap.css'); } /* Con media queries */ @import url('print.css') layer(print) print; ``` ## Combinando con Otro CSS Moderno ### Con CSS Nesting ```css @layer components { .card { padding: 1rem; .card-header { font-weight: bold; } &:hover { box-shadow: 0 4px 6px rgba(0,0,0,0.1); } } } ``` ### Con Container Queries ```css @layer components { .card-container { container: card / inline-size; } @container card (width > 400px) { .card { flex-direction: row; } } } ``` ## Estrategia de Migración ### Paso 1: Auditar Estilos Actuales Identifica tus problemas actuales de cascada: - ¿Dónde usas `!important`? - ¿Dónde dependes de especificidad de selectores? - ¿Qué estilos de terceros entran en conflicto? ### Paso 2: Definir Estructura de Capas ```css /* Empezar simple */ @layer reset, vendor, base, components, utilities, overrides; ``` ### Paso 3: Migrar Gradualmente ```css /* Mover estilos existentes a capas */ @layer base { /* Estilos base existentes */ } @layer components { /* Estilos de componentes existentes */ } /* Mantener estilos sin capa para debugging */ .temporary-fix { /* Sigue funcionando, mayor prioridad */ } ``` ### Paso 4: Eliminar Hacks de Especificidad ```css /* Antes */ .sidebar .nav .nav-item.active a { color: blue; } /* Después */ @layer components { .nav-link.active { color: blue; } } ``` ## Errores Comunes ### Error 1: Declaración de Orden Sin Estilos ```css /* ❌ Esto solo declara orden */ @layer a, b, c; /* Los estilos aún necesitan ser agregados */ @layer a { /* ... */ } ``` ### Error 2: Olvidar Prioridad de Sin Capa ```css @layer components { .btn { background: blue; } } /* ❌ Esto SIEMPRE gana - podría ser no intencional */ .btn { background: red; } ``` ### Error 3: Anidar Capas en Exceso ```css /* ❌ Demasiado complejo */ @layer components.forms.inputs.text.validation { } /* ✅ Mantenerlo plano cuando sea posible */ @layer components { .input-validation { } } ``` ## Puntos Clave 1. **Soporte universal** - 98% cobertura de navegadores, úsalo ya 2. **Orden vence especificidad** - Las capas posteriores siempre ganan 3. **Sin capa gana todo** - Estilos fuera de capas tienen mayor prioridad 4. **Aislamiento de frameworks** - Importa CSS de terceros en capas dedicadas 5. **Migración gradual** - Agrega capas incrementalmente a proyectos existentes `@layer` es la característica CSS que finalmente resuelve el problema de gestión de cascada. En 2026, no hay excusa para guerras de especificidad o hacks con `!important`. Organiza tus estilos en capas y recupera el control de tu cascada.