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.
softw.engineer
Software Engineer · softw.engineer

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ú.
¿Qué te pareció esto?
Tu feedback nos ayuda a crear mejor contenido
¿Qué opinas?
Déjanos tu comentario o pregunta sobre este artículo.