Harry Nicholls recientemente escribió todo sobre la simplificación de estilos con CSS funcional y definitivamente deberías echarle un vistazo. En resumen, CSS funcional es otro nombre para CSS atómico o el uso de clases de “ayuda” o “utilidad” que solo manejarían padding
o margin
, background-color
o color
, por ejemplo.
Harry adora completamente el uso de agregar múltiples clases como esta a un elemento:
Entonces, lo que estoy tratando de defender aquí es aprovechar el trabajo que otros han hecho para construir bibliotecas CSS funcionales. Están construidas sobre bases sólidas en diseño, la gente ha pasado muchas horas pensando en cómo deberían construirse estas bibliotecas y cuáles serán las clases más útiles.
Y no son solo las clases las que son útiles, sino los principios de diseño fundamentales detrás de Tachyons.
Esto tiene mucho sentido para mí. Sin embargo, Chris señala que no ha escuchado mucho sobre las desventajas de un enfoque CSS funcional / atómico:
¿Qué pasa con los grandes rediseños? ¿Es más o menos lo mismo, en cuanto a tiempo y dificultad, o pasa más tiempo derribando todas esas clases? ¿Qué sucede cuando necesitas un estilo que no está disponible? ¿Escribe lo tuyo? ¿O eso arruina el espíritu de todo esto y te pone en un territorio peligroso? ¿Qué tan intensos pueden ser todos los nombres de las clases? Puedo pensar en áreas que he diseñado que tienen tres o más consultas de medios que cambian drásticamente el estilo de un elemento. Poner toda esa información en HTML parece que podría volverse muy complicado. ¿La consistencia es más difícil o más fácil?
Esto también tiene mucho sentido para mí, pero aquí está la cuestión: soy un gran admirador de ambos métodos e incluso los combino en los mismos proyectos.
Antes de que te enojes, escúchame
En Gusto, la empresa para la que trabajo hoy, he estado intentando diseñar un sistema que utilice ambos métodos porque, sinceramente, creo que pueden convivir en armonía entre sí. Cada uno resuelve casos de uso muy diferentes para escribir CSS.
Aquí hay un ejemplo: imaginemos que estamos trabajando en una gran aplicación web React y nuestro diseñador ha entregado un diseño de página donde un párrafo y un botón necesitan más espacio debajo de ellos. Nuestro código se ve así:
<p>Item 1 description goes here</p>
<Button>Checkout item</Button>
Este es el tipo de problema que debe abordar el CSS funcional. En Gusto haríamos algo como esto:
<div class="margin-bottom-20px">
<p>Item 1 description goes here</p>
<button>Checkout item</button>
</div>
En otras palabras, usamos clases funcionales para hacer ajustes de diseño que pueden ser específicos de una característica particular en la que estamos trabajando. ¡Sin embargo! Ese Button
El componente se compone de un archivo CSS normal. En btn.scss
, tenemos un código como este que luego se importa a nuestro btn.jsx
componente:
.btn {
padding: 10px 15px;
margin: 0 15px 10px;
// rest of the styles go here
}
Creo que crear archivos CSS nuevos para componentes personalizados es mucho más fácil que intentar hacer estos componentes a partir de un montón de clases como margin-*
, padding-*
, etc. Aunque, podríamos estar usando estilos funcionales en nuestro btn.jsx
componente en su lugar así:
const Button = ({ onClick, className, children }) => {
return (
<button
className="padding-top-10px padding-bottom-10px padding-left-15px padding-right-15px margin-bottom-none margin-right-15px margin-left-15px margin-bottom-10px ${className}")}
onClick={onClick}
>
{children}
</button>
);
};
Este no es un ejemplo realista porque solo estamos tratando con dos propiedades y probablemente querríamos diseñar el color de fondo de este botón, el color del texto, los estados de desplazamiento, etc. Y, sí, sé que estos nombres de clase son un poco complicado, pero creo que mi punto sigue siendo válido incluso si se combinan las clases verticales y horizontales.
Así que creo que resolvemos los siguientes tres problemas con CSS funcional escribiendo nuestros estilos personalizados en un archivo CSS separado para esta instancia en particular:
- Legibilidad
- Gestión de dependencias de propiedad
- Evitar el doloroso hecho de que al diseño visual no le gustan las matemáticas
Como puede ver en el ejemplo de código anterior, es bastante difícil de leer e inmediatamente ver qué clases se han aplicado al botón. Más clases significa más dificultad para escanear.
En segundo lugar, muchos pares de propiedades / valores de CSS se escriben en relación entre sí. Diga, por ejemplo, position: relative
y position: absolute
. En nuestras hojas de estilo, quiero poder ver estas dependencias y creo que es más difícil hacerlo con CSS funcional. CSS a menudo depende de otros bits de CSS y es importante ver esas conexiones con comentarios o agrupaciones de propiedades/valores.
Y, por último, el diseño visual es un problema. Gran parte del diseño visual requiere números imperfectos que no se escalan correctamente. Con un sistema CSS funcional, probablemente querrá un sistema de base 10 o base 8, donde cada valor se basa en esa escala. Pero cuando alinea elementos juntos visualmente, es posible que deba hacerlo de una manera que no se alinee con esos valores. Esto se llama ajuste óptico y es porque nuestros cerebros son, bueno, muy raros. Lo que tiene sentido matemáticamente a menudo no lo tiene visualmente. Entonces, en este caso, tendríamos que agregar más relleno en la parte inferior del botón para que el texto se sienta como si estuviera ubicado en el centro. Con un enfoque CSS funcional, es más difícil hacer cosas así de manera ordenada, al menos en mi experiencia.
En aquellos casos en los que necesita equilibrar la legibilidad, las dependencias y los ajustes ópticos, escribir CSS normal en una hoja de estilo tradicional sigue siendo mi cosa favorita en el mundo. Pero CSS funcional todavía resuelve un montón de otros problemas de manera muy elocuente.
Por ejemplo, lo que estamos tratando de evitar con las clases funcionales en Gusto es crear toneladas de hojas de estilo que hagan un montón de cosas muy específicas o personalizadas. Volviendo a ese ejemplo anterior con el margen debajo de esos dos elementos por un segundo:
<div className="margin-bottom-20px">
<p>Item 1 description goes here</p>
<Button>Checkout item</Button>
</div>
En el pasado, nuestros equipos podrían haber escrito algo como esto en su lugar:
<div className="cool-feature-description-wrapper">
<p>Item 1 description goes here</p>
<button>Checkout item</button>
</div>
Un nuevo archivo CSS llamado cool_feature_description_wrapper.scss
necesitaría ser creado en nuestra aplicación así:
.cool-feature-description-wrapper {
margin-bottom: 20px;
}
Yo diría que estilos como este hacen que nuestro código sea más difícil de entender, más difícil de leer y fomenta las desviaciones de nuestra biblioteca de componentes. Al reemplazar esto con una clase de nuestra biblioteca de clases funcionales, de repente es mucho más fácil de leer y cambiar en el futuro. También resuelve una solución personalizada para nuestras necesidades particulares sin bifurcar nuestra biblioteca de estilos.
Por lo tanto, no he leído mucho sobre cómo equilibrar ambos enfoques de esta manera, aunque supongo que alguien ya lo ha cubierto en profundidad. Realmente creo que una combinación de estos dos métodos es mucho más útil que intentar resolver todos los problemas con una sola bolsa de trucos.
¿Yo se, verdad? Las opiniones matizadas son las peores.