Saltar al contenido
← Blog
Frontend2 de agosto de 20266 min de lectura

CSS moderno: 7 features que eliminan librerías de JavaScript

CSS ha evolucionado más en los últimos 3 años que en la década anterior. Funciones como :has(), container queries y text-wrap:balance hacen innecesario JavaScript para cosas que antes requerían librerías.

MM

softw.engineer

Software Engineer · softw.engineer

CSS moderno: 7 features que eliminan librerías de JavaScript

CSS moderno: 7 features que eliminan librerías de JavaScript

El CSS de 2026 hace cosas que en 2020 requerían React, una librería de animación y 200 líneas de JavaScript. Si sigues escribiendo JS para cosas que CSS ya resuelve nativamente, estás añadiendo peso innecesario a tu bundle.

1. :has() — el selector del padre que cambia todo

:has() es probablemente la adición más importante a CSS en la última década. Permite estilizar un elemento basándose en sus hijos. Antes, necesitabas JavaScript para esto.

/* Tarjeta con imagen: padding reducido */
.card:has(img) {
  padding: 0;
}

/* Formulario con campo inválido: borde rojo */
form:has(input:invalid) button {
  opacity: 0.5;
  pointer-events: none;
}

/* Modal abierto: bloquear scroll del body */
body:has(.modal.open) {
  overflow: hidden;
}

Soporte: 92%+ global. Chrome desde 2022, Safari desde 2023, Firefox desde finales de 2023. En 2026, puedes usarlo en producción sin preocupaciones.

El caso más poderoso: menús que cambian estilo según su contenido.

nav:has(.submenu:hover) .submenu {
  display: block;
}

Un menú dropdown completamente en CSS. Sin hover states de JavaScript. Sin onMouseEnter. Sin librería de popovers.

2. Container queries: responsive design de verdad

Media queries responden al tamaño del viewport. Pero un componente en una sidebar estrecha necesita responsive diferente al mismo componente en el ancho completo de la página.

Container queries resuelven esto. Tu componente responde a su contenedor, no al navegador.

.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

@container sidebar (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 120px 1fr;
  }
}

@container sidebar (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
}

El mismo .card se ve diferente según donde lo pongas. Sin JavaScript midiendo el ancho. Sin ResizeObserver. CSS puro.

Esto cambia cómo diseñas componentes. En lugar de pensar "esto va en móvil o desktop", piensas "esto va en un contenedor estrecho o amplio". Tu componente es reutilizable en cualquier contexto.

3. text-wrap: balance — tipografía sin esfuerzo

Los titulares largos a veces se rompen en líneas feos. La última línea tiene una palabra. La primera tiene cinco. text-wrap: balance lo arregla automáticamente.

h1 {
  text-wrap: balance;
  max-width: 30ch;
}

El navegador balancea el texto en líneas de longitud similar. Tus titulares se ven como un diseñador los compuso a mano. Sin JavaScript. Sin medir anchos. Una propiedad.

Hay también text-wrap: pretty que optimiza para evitar viudas (una palabra sola en la última línea de un párrafo):

p {
  text-wrap: pretty;
}

Pequeño detalle. Gran diferencia percibida.

4. Nesting nativo: adiós Sass (para la mayoría)

El nesting es nativo en CSS desde 2023. Ya no necesitas un preprocesador para esto.

.card {
  padding: 1.5rem;
  background: var(--card-bg);
  border-radius: 12px;

  & .title {
    font-size: 1.25rem;
    font-weight: 600;
  }

  & .description {
    color: var(--muted);
    line-height: 1.6;
  }

  &:hover {
    box-shadow: 0 8px 24px rgba(0,0,0,0.1);
    transform: translateY(-2px);
  }

  &.featured {
    border-color: var(--accent);
  }
}

Soporte: todos los navegadores modernos desde 2023. Si tu proyecto no necesita variables de Sass, mixins o funciones complejas, ya no necesitas Sass para nada.

5. Subgrid: grids perfectos heredados

El problema clásico de CSS grid: cuando anidas grids, pierdes la alineación del grid padre. Subgrid lo resuelve.

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

.product-card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
}

Cada .product-card hereda las filas del grid padre. Sus títulos, descripciones y precios se alinean perfectamente sin importar cuánto texto tenga cada uno. Antes, necesitabas JS para medir y igualar alturas.

6. accent-color — checkboxes y radios con tu marca

Los checkboxes, radios y sliders nativos del navegador son azules por default. Cambiar su color solía requerir CSS hacks elaborados o librerías enteras.

:root {
  --brand: #3E45EB;
}

input[type="checkbox"],
input[type="radio"],
input[type="range"] {
  accent-color: var(--brand);
}

Una propiedad. Todos tus inputs nativos adoptan tu color de marca. Sin resetear estilos. Sin librería de checkboxes personalizados.

progress {
  accent-color: var(--brand);
}

Incluso las barras de progreso. Minimalismo funcional.

7. scroll-snap — carruseles sin librerías

Swiper.js pesa 40KB minificado. Slick Carousel pesa 35KB. Para carruseles simples, scroll-snap hace lo mismo con cero JavaScript.

.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 1rem;
  scrollbar-width: none;
}

.carousel::-webkit-scrollbar {
  display: none;
}

.carousel-item {
  flex: 0 0 80%;
  scroll-snap-align: center;
}

Scroll horizontal con snap automático al item más cercano. Touch-friendly por defecto en móvil. Funciona con teclado. Accesible. Sin JS.

Si necesitas paginación o autoplay, ahí sí añades JavaScript. Pero la base, el snap y el scroll horizontal, es CSS puro.

El impacto real en tu bundle

Cuando quitas librerías que CSS ya reemplaza:

  • Sass: -50KB de build tooling + tiempo de compilación
  • jq (jQuery): -90KB para animaciones y toggles
  • Swiper: -40KB para carruseles
  • Popper.js: -20KB para tooltips (con :has())
  • Masonry.js: -15KB (con subgrid + grid)

Total potencial: más de 200KB de JavaScript eliminado. En mobile, eso es 1-2 segundos de carga más rápida.

Cuándo seguir usando JavaScript

CSS moderno es poderoso, pero no todo es reemplazable:

  • Animaciones complejas con timeline: GSAP sigue siendo mejor
  • Drag and drop: CSS no tiene onDrag
  • Validación de formularios con lógica de negocio: HTML5 validation + CSS para UI, JS para lógica
  • Virtualización de listas largas: CSS no puede reciclar elementos del DOM
  • Carruseles con autoplay y paginación: scroll-snap + un poco de JS

La regla: si CSS puede hacerlo con una propiedad, no uses JavaScript. Si CSS necesita hacks feos, probablemente JS es más limpio.

Soporte de navegadores en 2026

Todas las features mencionadas tienen soporte de 90%+ en navegadores modernos. La excepción es :has() en algunos navegadores legacy, pero incluso ahí está por encima del 92%.

Si necesitas soportar navegadores viejos, usa @supports:

.card {
  padding: 2rem;
}

@supports selector(:has(*)) {
  .card:has(img) {
    padding: 0;
  }
}

Los navegadores modernos aplican el padding reducido. Los viejos usan el padding por defecto. Progressive enhancement real.


CSS dejó de ser un lenguaje de estilos y se convirtió en un lenguaje de layout, interacción y responsive design. Si sigues pensando en CSS como lo hacías en 2019, estás escribiendo código innecesariamente complejo y pesado.

Las herramientas están ahí. El soporte está ahí. El único que falta eres tú.

#CSS#frontend#modern#performance#browser-features

Compartir

¿Qué te pareció esto?

Tu feedback nos ayuda a crear mejor contenido

¿Qué opinas?

Déjanos tu comentario o pregunta sobre este artículo.