CSS en JavaScript: el futuro del estilo basado en componentes

Imagen de @jonathanzwhite

Al adoptar estilos en línea, podemos obtener todas las posibilidades programáticas de JavaScript. Esto nos brinda los beneficios de algo como un preprocesador CSS (variables, mixins y funciones). También resuelve muchos de los problemas que tiene CSS, como el espacio de nombres global y los conflictos de estilo.

Para una inmersión profunda en los problemas que resuelve CSS en JavaScript, consulte la famosa presentación: React CSS en JS. Para un estudio de caso sobre las mejoras de rendimiento que obtiene de Afrodita, puede leer CSS en línea en Khan Academy: Afrodita. Si desea obtener más información sobre las mejores prácticas de CSS en JavaScript, consulte la guía de estilo de Airbnb.

Además, utilizaremos estilos JavaScript en línea para crear componentes que aborden algunos de los fundamentos del diseño que cubrí en uno de mis artículos anteriores: antes de que pueda dominar el diseño, primero debe dominar los fundamentos.

Un ejemplo motivador

Comencemos con un ejemplo simple: crear y diseñar un botón.

Normalmente, el componente y sus estilos asociados irían en el mismo archivo: Button y ButtonStyles. Esto se debe a que caen bajo la misma preocupación: la vista. Sin embargo, para este ejemplo, dividí el código en varias claves para hacerlo más digerible.

Aquí está el componente del botón:

Esto no es nada inesperado, solo un componente React sin estado. Donde entra en juego Afrodita es en la propiedad className. La función css toma un objeto de estilos y lo convierte en css. El objeto de estilos se crea con la función StyleSheet.create ({...}) de Afrodita. Puede ver el resultado de StyleSheet.create ({...}) con este parque infantil de Afrodita.

Aquí está la hoja de estilo del botón:

Uno de los beneficios de Afrodita es que la migración es sencilla y la curva de aprendizaje es baja. Las propiedades como border-radius se convierten en borderRadius y los valores se convierten en cadenas. Los pseudo-selectores, las consultas de medios y las definiciones de fuentes funcionan. Además, los prefijos de proveedor se agregan automáticamente.

Aquí está el resultado:

Uno de los beneficios de Afrodita es que la migración es sencilla y la curva de aprendizaje es baja.

Con este ejemplo en mente, echemos un vistazo a cómo podemos usar Afrodita para construir un sistema de diseño visual básico, centrándonos en los siguientes fundamentos del diseño: tipografía y espaciado.

Fundamental №1: tipografía

Comencemos con la tipografía, una base fundamental para el diseño. El primer paso es definir constantes de tipografía. Y a diferencia de Sass o Less, las constantes para Afrodita pueden ir en un archivo JavaScript o JSON.

Definir constantes de tipografía

Al crear constantes, use nombres semánticos para sus variables. Por ejemplo, en lugar de nombrar uno de sus tamaños de fuente h2, use un nombre como displayLarge que describa su función. Del mismo modo, para los pesos de fuente, en lugar de nombrar uno de sus pesos 600, dele un nombre como semibold para describir su efecto.

Es importante obtener los valores correctos para variables como tamaños de fuente y alturas de línea. Esto se debe a que afectan directamente el ritmo vertical dentro de un diseño. El ritmo vertical es un concepto que lo ayuda a lograr un espaciado constante entre los elementos.

Para obtener más información sobre el ritmo vertical, puede leer este artículo: ¿Por qué el ritmo vertical es una práctica de tipografía importante?

Use una calculadora para determinar las alturas de línea

Hay una ciencia detrás de elegir los valores para sus alturas de línea y tamaños de fuente. Podemos usar proporciones matemáticas para generar un conjunto de candidatos de tamaños potenciales. Hace unas semanas, escribí un artículo que detalla la metodología: la tipografía puede hacer o deshacer su diseño: un proceso para elegir el tipo. Para determinar los tamaños de fuente, utiliza Escala modular. Para determinar las alturas de línea, puede usar esta calculadora de ritmo vertical.

Definir un componente de encabezado

Después de definir nuestras constantes de tipografía, el siguiente paso es crear un componente para consumir los valores. El objetivo del componente es garantizar la coherencia en el diseño y la implementación de los encabezados en la base de código.

El componente Encabezado es una función sin estado que toma una etiqueta como una propiedad y devuelve la etiqueta con su estilo asociado. Esto es posible porque definimos las asignaciones de etiquetas anteriormente en el archivo de constantes.

En la parte inferior del archivo componente, definimos nuestro objeto de estilos. Aquí es donde usamos las constantes de tipografía.

Y así es como se usaría el componente Encabezado:

Con este enfoque, reducimos la variabilidad inesperada en nuestro sistema de tipos. Evitamos la trampa de cientos de tamaños de fuente diferentes al eliminar la necesidad de estilos globales y estandarizar encabezados en la base de código. Además, este enfoque que tomamos para construir el componente Encabezado se puede aplicar a la construcción de un componente de Texto para la copia del cuerpo.

Fundamental №2 - Espaciado

El espaciado controla el ritmo vertical y horizontal en el diseño. Eso hace que el espacio sea fundamental para establecer un sistema de diseño visual. Al igual que en la sección de tipografía, el primer paso para abordar el espaciado es definir constantes de espaciado.

Definir constantes de espaciado

Al definir constantes de espacio para los márgenes entre elementos, podemos adoptar un enfoque matemático. Usando una constante spacingFactor, podemos generar un conjunto de distancias basadas en un factor común. Este enfoque garantiza que tengamos un espacio lógico y consistente entre elementos.

El ejemplo anterior usa una escala lineal, de uno a trece. Sin embargo, experimente con diferentes escalas y proporciones. Los diseños requieren diferentes escalas en función de su propósito, su audiencia y los dispositivos a los que se dirigen. Como ejemplo, aquí están las primeras seis distancias calculadas usando la proporción áurea con un factor de espacio de ocho.

Proporción de oro (1: 1.618)
8.0 x (1.618 ^ 0) = 8.000
8.0 x (1.618 ^ 1) = 12.94
8.0 x (1.618 ^ 2) = 20.94
8.0 x (1.618 ^ 3) = 33.89
8.0 x (1.618 ^ 4) = 54.82
8.0 x (1.618 ^ 5) = 88.71

Así es como se vería la escala de espaciado en el código. Agregué una función auxiliar para manejar el cálculo y redondear la salida a su valor de píxel más cercano.

Después de definir nuestras constantes de espaciado, podemos usarlas para agregar márgenes a elementos en nuestro diseño. Un enfoque que podemos adoptar es importar las constantes de espaciado y consumirlas en componentes.

Por ejemplo, agreguemos un margenBottom al componente Button.

Esto funciona en la mayoría de los escenarios. Sin embargo, ¿qué sucede si queremos cambiar la propiedad marginBottom del botón en función de dónde se encuentra el botón?

Una forma de lograr márgenes variables es anular el estilo de margen del componente principal consumidor. Un enfoque alternativo es crear un componente de Espaciado para controlar los márgenes verticales en los elementos.

Con este enfoque, podemos eliminar la responsabilidad de establecer márgenes fuera del componente secundario y dentro del componente primario. De esta manera, el componente hijo se vuelve independiente del diseño, sin requerir ningún conocimiento de dónde ubicarse en relación con otros elementos.

Esto funciona porque componentes como botones, entradas y tarjetas pueden necesitar márgenes variables. Por ejemplo, un botón en un formulario puede necesitar márgenes más grandes que un botón en una barra de navegación. La advertencia es que si un componente siempre tiene márgenes consistentes, entonces tendría más sentido manejar los márgenes dentro del componente.

También puede haber notado que los ejemplos solo usan marginBottom. Esto se debe a que la definición de todos sus márgenes verticales en una dirección le permite evitar los márgenes de colapso y realizar un seguimiento del ritmo vertical de su diseño. Puede leer más sobre esto en el artículo de Harry Robert, Declaraciones de margen de dirección única.

En una nota final, también puede usar las constantes de espaciado que definió como relleno.

Al usar las mismas constantes de espaciado para márgenes y relleno, puede lograr una mayor consistencia visual en su diseño.

Así es como se vería el resultado:

Al usar constantes de espaciado para sus márgenes y relleno, puede lograr una mayor consistencia visual.

Ahora que conoce CSS en JavaScript, salga y experimente. Intente incorporar estilos JavaScript en línea en su próximo proyecto. Creo que apreciará poder trabajar en un solo contexto para manejar todos sus problemas de estilo y visualización.

Sobre el tema de CSS y JavaScript, ¿cuáles son algunos de los nuevos desarrollos que te entusiasman? Personalmente, estoy entusiasmado con async / wait. Déjame una nota o envíame un tweet en Twitter.

Puedes encontrarme en Medium donde publico todas las semanas. O puede seguirme en Twitter, donde publico divagaciones no sensoriales sobre diseño, desarrollo front-end y realidad virtual.

PD Si disfrutaste este artículo, significaría mucho si hicieras clic en y lo compartieras con amigos.