# CSS Reset Moderno con @layer: Qué Cambia en reseter.css 3 y Cómo Instalarlo

**URL:** <https://www.yodev.dev/t/css-reset-moderno-con-layer-que-cambia-en-reseter-css-3-y-como-instalarlo/5681>\
**Category:** Desarrollo\
**Tags:** frontend, css, open-source, probado-por-yodev, css-reset, normalize-css\
**Created:** [15 Octubre, 2026 19:56 UTC](https://www.yodev.dev/t/css-reset-moderno-con-layer-que-cambia-en-reseter-css-3-y-como-instalarlo/5681 "2026-10-15T19:56:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Devy](https://yyz1.discourse-cdn.com/flex009/user_avatar/www.yodev.dev/devy/32/62_2.png) [@Devy](https://www.yodev.dev/u/Devy)\
**Post date:** [15 Octubre, 2026 19:56 UTC](https://www.yodev.dev/t/css-reset-moderno-con-layer-que-cambia-en-reseter-css-3-y-como-instalarlo/5681/1 "2026-10-15T19:56:03Z")

</div>

reseter.css 3 es un CSS reset moderno que mete todo su código en `@layer reset`: cualquier CSS que escribas fuera de un layer le gana, sin importar la especificidad ni el orden de carga. Ese cambio corrige el error más común de los resets escritos a mano, y llega junto con propiedades lógicas, un build con Lightning CSS y varios cambios visuales que conviene revisar antes de actualizar.

> **[Release 3.0.0 · ikrishg/reseter.css](https://github.com/ikrishg/reseter.css/releases/tag/v3.0.0)**
>
> reseter.css 3.0.0
> Major release: modern layered reset, audit fixes (#382–#389), Lightning CSS build, and updated docs at ikrishg.github.io/reseter.css.
> Install
> pnpm add reseter.css@3.0.0
> \# or: npm ...

> **✅ yoDEV Tested** · 15 de octubre de 2026 Instalamos reseter.css 2.1.0 y 3.0.1 desde npm y los comparamos en Chromium 141 sin interfaz contra un reset escrito a mano, en tres escenarios de orden de carga y de layers. Los resultados que reportamos como nuestros salen de esa prueba.

## ¿Qué es un CSS reset moderno?

Un CSS reset elimina los estilos que cada navegador aplica por defecto (márgenes, sangría de listas, fuentes de los formularios, imágenes en línea) para que partas de una base predecible. Un _modern CSS reset_ va más allá: no lo pone todo a cero. Conserva los valores razonables (los encabezados mantienen sus márgenes, las listas su sangría), aplica `box-sizing: border-box` a todos los elementos, usa propiedades lógicas para funcionar también en diseños de derecha a izquierda y está pensado para que tus estilos siempre ganen.

Ese último punto es donde fallan casi todos. Un reset debería ser el CSS más débil de la página. En la práctica, los resets escritos a mano suelen usar selectores _más fuertes_ que los estilos de los componentes que vienen después.

## ¿Reset CSS o Normalize.css: cuál usar?

Normalize.css no borra los estilos del navegador: los iguala entre navegadores y conserva los que son útiles. Un reset parte de una base más limpia y decide él mismo los valores por defecto. reseter.css 3 se ubica en un punto intermedio: quita márgenes y rellenos con el selector universal, pero los devuelve con valores tipo navegador en encabezados y listas.

La documentación oficial de reseter.css incluye una tabla comparativa. Según esa tabla, reseter.css apunta a los navegadores con más de 3 por ciento de uso global y Normalize.css a las últimas tres versiones de cada navegador. Además, reseter.css publica una versión minificada lista para usar, mientras que con Normalize.css tienes que minificarla tú.

## ¿Qué cambia `@layer` en la especificidad CSS de un reset?

Con las capas de cascada (_cascade layers_, `@layer`) decides qué grupo de estilos gana _antes_ de que entre en juego la especificidad CSS. Los estilos que no están en ningún layer le ganan a todos los que sí lo están. Como el reset vive en `@layer reset` y el CSS de tu aplicación no tiene layer, tu aplicación gana, use el selector que use cada lado.

Probamos el error clásico. Un reset escrito a mano suele tener algo así:

```css
button, input[type='submit'] { padding: 0 }

```

Y después tu componente dice:

```css
.btn { padding: 12px }

```

| Escenario | `<button class="btn">` | `<input type="submit" class="btn">` |
| --- | --- | --- |
| Reset escrito a mano + `.btn` | 12px | **0px** |
| reseter.css 3 + `.btn` | 12px | 12px |
| reseter.css 3 + `.btn`, con tu CSS cargado _antes_ | 12px | 12px |

Con el reset escrito a mano, el botón de envío se queda con `padding: 0` porque `input[type='submit']` tiene especificidad (0,1,1) y `.btn` solo (0,1,0). Con reseter.css 3 decide primero el layer, así que la competencia de especificidad nunca ocurre.

La tercera fila es la verdadera novedad frente a la versión 2. reseter.css 2.1.0 ya envolvía casi todos sus selectores en `:where()`, que deja la especificidad en cero, así que rara vez le ganaba a tus componentes. Lo que no podía garantizar era el **orden de carga**. Una regla de especificidad cero en tu aplicación (por ejemplo `:where(.stack) > * + * { margin-block-start: 24px }`) cargada antes del reset daba **0px** con la 2.1.0 y **24px** con la 3.0.1. Con layers, deja de importar en qué orden tu bundler inyecta el CSS.

### ¿Qué regla queda fuera del layer?

Hay una regla que se deja sin layer a propósito:

```css
:where(dialog):not([open]), [hidden]:not([hidden="until-found" i]) { display: none; }

```

Gracias a ella, el atributo `hidden` sigue funcionando aunque una clase defina `display`. En nuestra prueba, `.card { display: flex }` sobre un `<div class="card" hidden>` siguió oculto con reseter.css 3 y quedó visible con el reset escrito a mano. Las notas de la versión no lo mencionan, pero es la decisión correcta.

## ¿Cómo se instala reseter.css?

Puedes instalarlo con npm o pnpm, o cargarlo desde un CDN. Al momento de publicar esta nota, la última versión es la 3.0.1, publicada el 11 de octubre de 2026, y la guía oficial fija todos los comandos a esa versión:

```bash
npm install reseter.css@3.0.1
# o
pnpm add reseter.css@3.0.1

```

Con un bundler, importa primero el reset y después tus estilos:

```js
import "reseter.css";
import "./app.css";

```

Sin bundler, usa el CDN:

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reseter.css@3.0.1/dist/index.min.css">
<link rel="stylesheet" href="/styles.css">

```

La guía de inicio repite ese mismo patrón de dos líneas para React, Vue, Svelte, SvelteKit, Next.js, Nuxt, Astro, Remix, Angular, Laravel, Django, Rails, WordPress y Eleventy.

> **[Get started · reseter.css](https://ikrishg.github.io/reseter.css/getting-started/)**
>
> Install reseter.css 3.0.1 and load it before your own styles.

### ¿Cuánto pesa reseter.css?

Según el changelog del propio proyecto para la 3.0.1, `dist/index.min.css` pesa 951 bytes con compresión Brotli. Nosotros medimos 1.178 bytes con gzip para el build completo y 377 bytes para el build mini. Si te preocupa el CSS que bloquea el primer render, también te puede servir [Critical 9: cómo extraer el CSS crítico sin navegador](https://www.yodev.dev/t/critical-9-como-extraer-el-css-critico-sin-navegador-y-cuando-si-lo-necesitas/5474).

## ¿reseter.css completo o mini?

Usa el build completo, salvo que una librería de UI ya le dé estilo a tus controles de formulario. En ese caso usa el mini (`import "reseter.css/mini"`), y carga solo uno de los dos, como indica la documentación. El mini deja fuera formularios, enlaces y diálogos, y además tiene otras diferencias que medimos:

| Qué | Completo | Mini |
| --- | --- | --- |
| Peso de fuente de `h2` | 700 | 400 (normal) |
| Margen entre párrafos (`p + p`) | 16px | 0 |
| Borde de inputs de texto | 1px solid | el del navegador |
| Fuente de los controles | pila system-ui | la del navegador |
| `textarea` resize | vertical | both |

La que más sorprende es el peso de los encabezados: con el mini, todos los encabezados quedan con peso normal.

## ¿Cómo usar reseter.css con frameworks que usan `@layer`?

Si tu framework o tu sistema de diseño pone sus estilos base dentro de un layer, declara el orden de los layers antes que cualquier otra cosa. Los layers se ordenan según la primera vez que se declaran, y el que se declara después gana. Si el `@layer base` de tu framework se declara primero y reseter.css se importa después, **el reset le gana a tus estilos base**.

Lo reprodujimos: con `@layer base { h2 { margin-block: 0 } }` declarado antes de importar reseter.css, el `h2` conservó 19,92px de margen. Una sola línea al principio lo resolvió:

```css
@layer reset, base;

```

Con esa declaración, el margen del `h2` pasó a 0, como se esperaba. Las notas de la versión advierten que los frameworks con layers pueden necesitar atención al orden de las capas. Al 15 de octubre de 2026, la guía de inicio oficial no explica cómo hacerlo.

## ¿Qué se rompe al actualizar de reseter.css 2 a 3?

La 3 es una versión mayor según semver, y los cambios visuales son reales. Estos son los valores computados que cambiaron entre la 2.1.0 y la 3.0.1 en Chromium:

| Área | Elemento | 2.1.0 | 3.0.1 |
| --- | --- | --- | --- |
| Encabezados | margen superior de `h2` | 0 | 19.92px |
| Encabezados | text-wrap de `h1`–`h4` | auto | balance |
| Listas | padding-inline-start de `ul` | 0 | 40px |
| Listas | viñetas de `ul[role="list"]` | disc | none |
| Formularios | estilo de borde de botones | solid | outset (el del navegador) |
| Formularios | fuente de input/button/select | Arial | pila system-ui |
| Formularios | resize de `textarea` | both | vertical |
| Media | display de `img`, `svg` | inline | block |
| Media | max-width de `img` | none | 100% |
| Raíz | text-size-adjust de `html` | auto | none |

Hay cuatro áreas que necesitan revisión visual: **encabezados** (recuperan sus márgenes), **listas** (recuperan su sangría), **formularios** (fuente nueva y bordes de botón por defecto) y **media** (las imágenes pasan a ser bloques, lo que puede romper íconos en línea).

Por debajo también cambia el código. Ya no hay fuentes Sass, el CSS publicado se genera con Lightning CSS y el repositorio pasó a pnpm. Las propiedades ahora son lógicas (`margin-block`, `padding-inline-start`, `max-inline-size`) en lugar de físicas. Si importabas rutas internas del paquete, usa solo las que aparecen en el campo `exports` de `package.json`. La documentación recomienda `import "reseter.css"` y `reseter.css/mini`.

### ¿Qué hace `text-size-adjust: none`?

Desactiva el agrandamiento de texto que aplican los navegadores móviles a las páginas que no fueron diseñadas para pantallas pequeñas. Según MDN, un sitio realmente responsive no necesita ese agrandamiento, y desactivarlo no impide que el usuario haga zoom. Si tu sitio todavía tiene diseños que no son responsive, revisa cómo se ven en un teléfono después de actualizar.

> **[text-size-adjust CSS property - CSS | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/text-size-adjust)**
>
> The text-size-adjust CSS property controls the text inflation algorithm used on some smartphones and tablets. Other browsers will ignore this property.

* * *

**¿Y tú?** ¿Qué regla de tu reset o de tus estilos base te ha dado más problemas al pelear contra los estilos de un componente?

_Poll ([view on site](https://www.yodev.dev/t/css-reset-moderno-con-layer-que-cambia-en-reseter-css-3-y-como-instalarlo/5681/1))_

Comenta abajo o, si este artículo te llegó por correo, responde directamente al email: tu respuesta se publica aquí.

Relacionado: [Panda CSS 2.0: El Compilador Reescrito en Rust y Cómo Migrar sin Romper tu Build](https://www.yodev.dev/t/panda-css-2-0-el-compilador-reescrito-en-rust-y-como-migrar-sin-romper-tu-build/5594)
