Funciones poco conocidas del HTML/CSS moderno
(lyra.horse)- 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_modulesocupa 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: flexyjustify-content: centeres sencillo centrar un div - Las herramientas de desarrollador del navegador ofrecen widgets para ajustar visualmente propiedades de flexbox
- Ejemplo: con
- 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
- Ejemplo: había que manejar cadenas largas de selectores como
- Ú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
- Ejemplo:
- La anidación de CSS (nesting) reúne los estilos relacionados en un solo lugar y mejora la legibilidad
- 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
- Con
- 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
@keyframesni JavaScript adicional
- Se configura con
- 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: 0manteniendo la accesibilidad para lectores de pantalla
- Ejemplo:
- El elemento details es ideal para implementar menús acordeón como los de FAQ
- El atributo
namepermite controlar que solo uno quede abierto a la vez - Se pueden agregar animaciones según el estado
[open]
- El atributo
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
- Ejemplo:
- :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
@mediacon 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
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.
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.
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.
gapfunciona 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.margin, elpadding, 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.container queries,calcy 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.
.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.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.
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
:hasy 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.
sibling-index()ysibling-count()(explicación en MDN)@functiony@mixin(borrador de la especificación, explicación de CSS Tricks)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.
font-size: 12pxno 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,tabindexyaria-controlsdeben 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.También se pueden implementar efectos interactivos como este sin JS (página de ejemplo)
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.
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.