14 puntos por GN⁺ 2025-08-30 | 3 comentarios | Compartir por WhatsApp
  • Las principales causas recientes del deterioro del rendimiento de los sitios web son el uso excesivo de JavaScript y los scripts de seguimiento, y en muchos casos pueden sustituirse suficientemente solo con HTML/CSS
  • Funciones agregadas recientemente como anidación de CSS, colores relativos y nuevas unidades de viewport (lvh, svh, dvh) permiten resolver de forma simple tareas que antes dependían de JS o de preprocesadores
  • CSS no es solo una herramienta de estilos, sino un lenguaje potente capaz de implementar animaciones, validación de entradas, temas en modo oscuro y menús acordeón
  • También en términos de rendimiento, CSS usa aceleración por GPU y funciona en un hilo separado, por lo que es más fluido y eficiente que JS en animaciones y transiciones
  • La autora destaca CSS no solo como una herramienta práctica, sino como un medio de expresión y arte, y recomienda que los desarrolladores aprovechen más el potencial del CSS moderno

Introducción: la complejidad de la web y un nuevo intento

  • Muchos sitios web sufren degradación de rendimiento y complejidad por el uso excesivo de frameworks de JavaScript
    • Las apps de React tardan varios segundos en cargar, y NextJS provoca errores de hidratación
    • La carpeta node_modules ocupa varios gigabytes
  • Incluso sin JavaScript, es posible implementar funciones potentes solo con HTML y CSS
    • Salvo casos como carritos de compra complejos en sitios de comercio electrónico o dashboards, JavaScript podría no ser indispensable
  • Este artículo presenta las funciones más recientes de CSS e invita a los desarrolladores a explorar distintas posibilidades sin depender solo de JavaScript

Malentendidos y percepción sobre CSS

¿CSS realmente es difícil e incómodo?

  • La percepción negativa sobre CSS proviene de una falta de aprendizaje básico
    • Muchos desarrolladores se saltan los fundamentos de CSS y se concentran en JavaScript o TypeScript
    • CSS no es una simple herramienta de estilos, sino un lenguaje específico de dominio con funciones potentes
  • CSS permite implementar diseños complejos fácilmente con herramientas como flexbox
    • Ejemplo: con display: flex y justify-content: center es sencillo centrar un div
    • Las herramientas de desarrollador del navegador ofrecen widgets para ajustar visualmente propiedades de flexbox
  • Si se profundiza solo en un lado (por ejemplo, JS) y se descuida CSS, es natural que la carga aumente

El dolor de escribir CSS, y cómo ha cambiado

  • Antes CSS no era especialmente cómodo, por eso aparecieron herramientas como Sass y Tailwind
    • Ejemplo: había que manejar cadenas largas de selectores como .post > .buttons .like:hover
  • Últimamente se han agregado funciones de mejora de calidad (como anidación), por lo que ahora se puede desarrollar cómodamente solo con CSS base
    • La anidación de CSS (nesting) reúne los estilos relacionados en un solo lugar y mejora la legibilidad
      • Ejemplo: .post { & > .buttons { .like { &:hover { ... } } } }
      • La relación padre-hijo queda clara y permite usar nombres de clase más cortos y simples
  • Los colores relativos (relative colors) facilitan el ajuste de colores
    • Con hsl(from #123456 h s calc(l + 10)) se puede ajustar la luminosidad
    • color-mix() mezcla dos colores para generar colores dinámicos
  • La sintaxis de rangos en media queries permite establecer condiciones intuitivas como (width <= 768px)
  • La unidad lh permite aplicar estilos basados en la altura de línea
  • La propiedad scrollbar-gutter resuelve el problema de desplazamientos del layout por la barra de scroll
  • Baseline garantiza compatibilidad de funciones entre los principales navegadores
    • newly available funciona en navegadores recientes
    • widely available tiene soporte hasta en navegadores de hace 2.5 años
    • Ejemplo: la anidación de CSS es compatible con todos los navegadores desde diciembre de 2023

¿Por qué desarrollar solo con CSS/HTML?

  • Algunos usuarios desactivan JavaScript por defecto (por seguridad, privacidad, etc.)
  • Si un sitio se ofrece solo con CSS/HTML puro, aumenta la posibilidad de que esos usuarios también puedan usarlo
  • Desde la perspectiva del desarrollo y del usuario, usar solo CSS/HTML tiene grandes ventajas en velocidad, accesibilidad y uso de CPU/batería
    • Las animaciones CSS se ejecutan en el hilo compositor, reduciendo la carga de CPU
    • JavaScript se ejecuta mediante el event loop y puede introducir una pequeña latencia
  • Mejora la accesibilidad y la facilidad de uso
    • Efectos hover en botones, animaciones de toast y validación de entradas pueden implementarse fácilmente con CSS

Ejemplos prácticos de CSS y funciones principales

Implementar animaciones de entrada naturales con @starting-style

  • Antes, para implementar animaciones de aparición de elementos se necesitaban estructuras complejas como keyframes o disparadores con JS
  • Con la llegada de @starting-style, definir el estado inicial se volvió simple. Permite implementar fácilmente la animación del estado inicial de un elemento (por ejemplo, un fade-in)
    • Se configura con transition: opacity 1s; @starting-style { opacity: 0; }
    • Funciona sin @keyframes ni JavaScript adicional
  • Basta con declarar el estado inicial junto con la transición para que la animación se aplique de forma natural
    • Ejemplo: suaviza la transición de opacidad y posición de un mensaje toast

Configurar temas claro/oscuro fácilmente

  • color-scheme: light dark cambia el tema automáticamente según la preferencia del usuario
  • La función light-dark(#000, #FFF) permite especificar colores para modo claro u oscuro
  • Los botones de radio y el selector :has permiten que el usuario elija el tema
    • Es posible cambiar de tema solo con CSS, sin JavaScript
    • Opcionalmente se puede agregar JavaScript para guardar/cargar el tema

Crear UI personalizada con radios/checkboxes y :has, :checked, etc.

  • Interacciones complejas como pestañas, acordeones y toggles también pueden implementarse sin JavaScript
  • Los botones de radio pueden estilizarse de forma personalizada con :checked y :has
    • Ejemplo: label:has(input:checked) aplica estilos al botón seleccionado
    • El elemento input se puede ocultar con opacity: 0 manteniendo la accesibilidad para lectores de pantalla
  • El elemento details es ideal para implementar menús acordeón como los de FAQ
    • El atributo name permite controlar que solo uno quede abierto a la vez
    • Se pueden agregar animaciones según el estado [open]

Validación de entradas y reflejo del estado

  • La combinación de atributos HTML como pattern y required con pseudoclases CSS (:valid, :invalid, :user-valid, etc.) permite ofrecer validación en tiempo real y retroalimentación visual
  • Mejoran la experiencia de usuario cambios como modificar el outline o el borde de los campos de entrada
  • El atributo pattern de HTML permite validar la entrada
    • Ejemplo: \w{3,16} permite letras, números y guion bajo de 3 a 16 caracteres
  • :valid y :invalid de CSS permiten aplicar estilos según la validez
    • :user-valid y :user-invalid aplican estilos solo después de que el usuario haya escrito
  • Con el selector :has también se pueden estilizar otros elementos según el estado del input
  • En algunos casos (por ejemplo, condiciones de entrada complejas) sí hace falta JS, pero en la mayoría HTML/CSS es suficiente

Uso correcto de las unidades de viewport

  • Las unidades vw/vh presentan problemas de precisión en móvil debido a la aparición y desaparición de la barra de direcciones (navegación)
  • Se recomienda usar nuevas unidades de viewport como lvh/svh/dvh (largest/smallest/dynamic viewport height)
    • lvh: para pantalla completa (por ejemplo, un fondo completo)
    • svh: para botones, enlaces, etc. que siempre deben permanecer visibles
    • dvh: para asignar tamaño de forma dinámica según cambios como el scroll
  • La superposición del teclado puede manejarse con la propiedad interactive-widget o la VirtualKeyboard API
    • <meta name="viewport" content="width=device-width, interactive-widget=resizes-content">
    • En navegadores basados en Chromium: navigator.virtualKeyboard.overlaysContent = true

Lista de deseos para CSS (lo que falta o se quisiera ver)

  • Bloques reutilizables: aplicar otras clases dentro de una clase (por ejemplo, @apply border)
  • Selectores combinados con media queries: combinar @media con selectores de clase
  • Variable nth-child: span { --nth: nth-child(); } para estilos dinámicos
  • Selector nth-letter: aplicar estilo a una letra específica (por ejemplo, p::nth-letter(2))
  • Eliminar unidades: generar valores sin unidad con calc(100vw / 1px)
  • Función image(): soporte para color alternativo y fragmentos de imagen
  • Etiqueta style dentro de body: soporte oficial del estándar para aliviar el problema de FOUC

Cierre: CSS y el arte de la web

  • CSS no es una simple herramienta, sino un medio de expresión creativa
  • Las herramientas de IA o las cadenas de build (linters, herramientas de minificación) pueden limitar la creatividad
  • CSS cumple al mismo tiempo con rendimiento, accesibilidad y expresión artística
  • Este artículo está escrito con unos 49 kB de HTML/CSS sin JavaScript
    • Todos los widgets interactivos y los elementos visuales fueron implementados a mano
    • Ejemplo: CSS Click Game demuestra las posibilidades de CSS como lenguaje de programación

3 comentarios

 
duqduqduq 2025-09-01

Yo era full stack, pero conforme tu carrera va subiendo de nivel, de algún modo ya no tienes oportunidades de hacer FE, así que no lo toqué durante unos 10 años. Hace poco tuve que dar una capacitación en una empresa y, para hacer una introducción breve, me puse a revisarlo, y de verdad me sorprendió cuánto ha cambiado. Si además lo combinas con SCSS, está aún mejor. Pero el terreno de CSS es bastante peculiar. Aprenderlo es fácil, pero creo que usarlo lo bastante bien como para que te reconozcan depende mucho del sentido estético y la creatividad de cada quien. En esta era web donde la usabilidad y el diseño importan más, me da pena que el valor de los publishers no parezca estar siendo mejor reconocido.

 
ahwjdekf 2025-09-01

Esta vez, como hobby para probar tecnologías de desarrollo web, me lancé desde cero absoluto y a lo bruto a crear un tablero básico usando nextjs, authjs, tailwind y shadcn... y al final la mayor dificultad de aprendizaje fue CSS.

 
GN⁺ 2025-08-30
Opiniones de Hacker News
  • Agradezco la función de anidación que se agregó recientemente a CSS, pero en general CSS de verdad me parece un lenguaje raro y, personalmente, bastante malo; quizá sea porque yo no lo uso bien, pero es tan complejo y desordenado que se siente como mover runas incomprensibles de un lado a otro. El sistema de estilos y el de layout están mezclados, y como la herencia y la contención funcionan distinto, confunde aún más. Creo que haber combinado estilos y layout fue un error. No me parece que agregar más funciones a un sistema ya roto de raíz pueda ser la solución.

    • Yo también me he ganado la vida con CSS durante los últimos 10 años, pero CSS se siente menos como un lenguaje diseñado y más como algo que se fue extendiendo sobre la marcha. Solo le van pegando módulos nuevos encima de propiedades existentes, y eso hace que choquen entre sí o se comporten apenas distinto, complicando mucho el debugging. Ejemplos de eso son cómo el box model y el layout flex se comportan de forma distinta, o cómo gap funciona distinto en flex y en grid (enlace). Una vez que armas un layout, en la práctica queda casi fijo; sin encapsulación compleja nativa o basada en JS, es difícil cambiarlo con flexibilidad. Y entonces aparecen problemas como que el grosor de la fuente cambie inesperadamente o que el menú móvil se muestre también en desktop.
    • No estoy de acuerdo. Creo que la razón por la que se ven tantas opiniones negativas sobre CSS es que la gente no lo aprende bien o, sobre todo, no entiende el cascade. Hace tiempo me metí a fondo en la especificación de CSS, y terminé pensando que es un lenguaje bastante bien diseñado para su propósito de separar la semántica del markup y el estilo.
    • Creo que separar estilos y layout es imposible. Cualquiera que haya hecho desarrollo de UI siente que ambos elementos están ligados por naturaleza y dependen entre sí. Por ejemplo, la longitud y el tamaño del texto, el overflow, el margin, el padding, todo se afecta mutuamente. Si cambias el borde o el espaciado de un elemento, también cambia el espacio disponible para el contenido interno. No se pueden separar por completo.
    • Creo que el verdadero problema de CSS es el cascading, y de hecho gran parte del desarrollo frontend moderno gira en torno a bloquear ese cascade. La componentización de UI es un ejemplo. El layout es otro problema aparte, y se vuelve más complejo por compatibilidad. Si todo el layout funcionara por defecto solo con flexbox o grid, y no se mezclaran elementos inline y no-inline dentro de un mismo contenedor, sería muchísimo mejor. React Native funciona justo así. En React Native los estilos no hacen cascade, así que es mucho más fácil administrarlos.
    • Todo eso es cierto. Pero esto es lo que tenemos hoy. He pensado si no podríamos crear un modelo más consistente a nivel conceptual y transpilarlo a CSS. Tal vez con container queries, calc y cosas así se podría implementar matemáticamente un sistema de layout más ordenado. Los lenguajes preprocesadores actuales más bien terminan pegando funciones incompletas sobre conceptos que ya estaban incompletos en CSS, y eso vuelve todo todavía más confuso.
  • Creo que lo peor de CSS es que mucha gente ni siquiera lo aprende bien, lo usa a la fuerza durante un día o algo así, y luego forma opiniones muy fuertes.

    • Yo también tuve uno de esos “días”. Estaba haciendo una app de podcasts y quería crear un footer flotante que (1) siempre estuviera abajo, (2) siempre se viera, (3) no tapara el contenido, y (4) se pudiera implementar sin hacks aparte. Y entonces descubrí que eso es imposible en CSS. Qué gran sistema.
    • Aprendí CSS hace 20 años. Mi conclusión es que, por culpa del cascading, a CSS deberían cambiarle el nombre a Crappy Style Sheets. Cuando varias personas colaboran, el fenómeno de “si cambias esto aquí, se rompe algo rarísimo allá” viene de fábrica. Su característica es un conjunto complicado de reglas para sobreescribir otras reglas, y si esa es la base, ya empezamos mal. Las formas de apuntar con selectores complejos se van volviendo cada vez más enredadas hasta terminar en código como .foo > .bar:nth-child(2n) ~ .baz. Y al hacer eso, también rompes el código de tus compañeros. Hasta para un layout sencillo te termina doliendo la cabeza. Últimamente ha mejorado bastante, eso sí, pero desde el principio el problema fue esta estructura centrada en el cascade. Otras críticas, como la sintaxis, son menores. Si fuera práctico y fácil de usar, la sintaxis sería tolerable, pero CSS no lo era. No creo que hacer layouts web debería ser una profesión.
    • Respecto a eso de que “mucha gente usa CSS sin aprenderlo”, me parece excesivo plantear que alguien solo tiene derecho a usarlo si aprende sus más de 20 especificaciones. Si la gente usa una herramienta y tiene problemas, hay que ver si la herramienta está mal, no culpar a las personas. En vez de obligarte a usar la sierra con más cuidado, lo correcto sería ponerle protecciones de seguridad.
  • En este artículo no me convence mucho el argumento de que “algunos usuarios no quieren JavaScript”. Yo también uso Arch y soy entusiasta del scripting y el crawling, pero enfocarse en entornos “NoScript” no me parece especialmente importante. Me da la impresión de que es un gusto de una minoría muy pequeña, así que en general se puede ignorar. Me recuerda un poco a la época en que decían que “10% usa IE6”. Aun así, creo que hay muchas otras razones por las que CSS es mejor. De todos modos, no es el punto central, pero esa es la sensación que me deja el enfoque.

    • Algo que en CSS declarativo puedes hacer en unas pocas líneas, en JS imperativo se vuelve decenas de líneas, con más comportamientos raros, problemas de compatibilidad con frameworks y retrasos en el tiempo hasta interactivo. El entorno NoScript es solo un extra. En el fondo, la verdad, extraño DSSSL.
    • En el texto, a los usuarios que evitan JavaScript se les menciona de pasada, pero la mayor parte del artículo se enfoca en mostrar las capacidades de CSS en sí. Una de las motivaciones es el rendimiento, pero me parece mucho más productivo presentar las técnicas de CSS.
    • Yo uso internet normalmente en un entorno NoScript. Solo permito excepciones en sitios que realmente necesitan JS. También ayuda bastante en rendimiento, batería y seguridad. ¿Has vivido siquiera una semana con NoScript? Yo pensaba igual antes de probarlo. Por cierto, soy el autor de esta entrada del blog.
    • No creo que el público NoScript sea tan significativo ni que haga falta apuntarle específicamente. Pero aunque el autor no lo dijo así en esa breve mención, creo que escribir menos código y apoyarse más en la plataforma del navegador tiene un valor enorme. Dejar que el navegador haga lo más posible da una eficiencia tremenda.
    • Sobre la afirmación de que “algunos usuarios no quieren JavaScript”, yo diría que en realidad la gran mayoría de los usuarios no lo quiere.
  • No sabía que la anidación ya se había convertido en un estándar oficial. Hasta hace poco pensaba que seguía en fase de propuesta. CSS tiene muchas rarezas, pero también se siente que va evolucionando hacia un lenguaje cada vez mejor, un poco como JavaScript. Gracias a Flexbox, el selector :has y la anidación, ya se resolvieron muchos de los puntos dolorosos que venían de hace años.

  • Dos funciones de CSS que estaban en mi wishlist ya existen en la especificación.

  • Creo que la sintaxis de CSS es pésima. Trabajo con entre 10 y 15 lenguajes, pero CSS es el más difícil de leer y entender. Es incluso más enrevesado que ensamblador x86. CSS es una entrada pretokenizada para el renderer, pero ni siquiera son tokens y para una persona resulta rarísimo de escribir. Siento que debería usarse como ejemplo negativo de “así no se hace”, como ASN.1 en los RFC.

    • Me pregunto cuántos de esos lenguajes son declarativos o específicos de dominio. Comparar CSS con ensamblador no es adecuado. CSS es declarativo y ensamblador es lo opuesto. A la mayoría de los desarrolladores frontend también les cuesta al principio pasar de lenguajes imperativos a CSS, pero mejora con la práctica. La terminología y los conceptos de CSS vienen en gran medida del mundo del diseño y la publicación, no de la informática. Muchos desarrolladores abordan CSS como si fuera un conjunto de instrucciones explícitas, pero CSS funciona de una manera peculiar donde las cosas se afectan entre sí. Una sola propiedad incluso puede cambiar todo el algoritmo de layout (introducción a los algoritmos de layout en CSS)
    • Aunque “uses 15 lenguajes”, creo que CSS es realmente difícil de conocer bien. Incluso si has usado muchos lenguajes de programación, llegar al punto de poder decir que realmente conoces uno requiere muchísima experiencia práctica (wiki sobre la ilusión de profundidad explicativa). La mejor manera de entender CSS es ver directamente el resultado del renderizado y evaluarlo. Yo lo he usado así durante décadas.
    • Yo también siento que CSS es lo peor del trío HTML/CSS/JS.
    • Me gustaría escuchar con más detalle qué significa eso de que “CSS es una entrada pretokenizada”.
    • Código como font-size: 12px no me parece en absoluto difícil de leer para una persona, así que no entiendo por qué te resulta tan complicado. A mí me parece realmente simple.
  • Me pregunto si el ejemplo de tabs con radio buttons está bien en términos de accesibilidad. Según el criterio de WAI-ARIA, tenía entendido que atributos como aria-selected, tabindex y aria-controls deben actualizarse con JS cuando cambia la pestaña, aunque no estoy completamente seguro. La accesibilidad a menudo queda en segundo plano, y a veces la gente cae en la ilusión de que usar solo HTML/CSS garantiza accesibilidad automáticamente. Es un punto que vale la pena pensar una vez más al elegir este enfoque.

    • Hasta donde sé, esos tabs con radio buttons funcionan bien con navegación por teclado y lectores de pantalla, y siguen el flujo de movimiento entre tabs y contenido del ejemplo de WAI-ARIA (ejemplo de WAI-ARIA). No tengo formación profunda en accesibilidad, pero trato de verificarlo lo más posible. También los probé personalmente con varias herramientas de accesibilidad.
    • En el texto original el autor menciona varias veces el tema de accesibilidad e incluso intentó manejar workarounds para bugs del navegador (nota relacionada).
    • La accesibilidad de esta misma entrada del blog (sobre todo el contraste) es tan mala que, desde mi experiencia trabajando como desarrollador web en una organización para personas con discapacidad, me cuesta tomarla como referencia.
  • También se pueden implementar efectos interactivos como este sin JS (página de ejemplo)

      • animación de confeti cayendo
      • notificación con botón de cierre
      • al cerrar la notificación, el confeti también desaparece
      • también hay comportamiento de tabs (aunque en ese ejemplo requiere recargar desde el servidor)
      • si agregas JS, la animación se vuelve más fluida y rica
  • Como desarrollador web con 10 años de experiencia, siento que textos como este deberían sacudir nuestras certezas. El título no me gustó mucho, y casi hace que no lo leyera. Por cierto, no se puede renderizar un mapa solo con CSS.

    • Con CSS+SVG sí se puede renderizar un mapa. Claro, las funciones adicionales como navegación habría que implementarlas aparte.
  • Tal vez el nombre Vega genere prejuicios, pero de verdad me encanta este sitio. El diseño general también está muy bien, y el contenido de esta página es excelente. Pienso compartir este enlace sí o sí con gente que se dedica al desarrollo web. También me gusta muchísimo arrupted; antes ya había hecho cosas muy buenas, así que me dio gusto volver a ver un dominio conocido en portada.