Las muchas formas de incluir CSS en aplicaciones JavaScript | Programar Plus

¡Bienvenido a un tema increíblemente controvertido en la tierra del desarrollo front-end! Estoy seguro de que la mayoría de los que leen esto se han encontrado con su parte justa de #hotdrama sobre cómo se debe manejar CSS dentro de una aplicación JavaScript.

Quiero comenzar esta publicación con un descargo de responsabilidad: No existe una regla estricta y rápida que establezca un método de manejo de CSS en una aplicación React, Vue o Angular como superior. ¡Cada proyecto es diferente y cada método tiene sus méritos! Eso puede parecer ambiguo, pero lo que sí sé es que la comunidad de desarrollo en la que existimos está llena de personas que buscan continuamente nueva información y buscan impulsar la web de manera significativa.

Dejando de lado las nociones preconcebidas sobre este tema, ¡echemos un vistazo al fascinante mundo de la arquitectura CSS!

Vamos a contar las maneras

Simplemente buscando en Google “Cómo agregar CSS a [insert framework here]”Produce una oleada de creencias y opiniones firmemente arraigadas sobre cómo se deben aplicar los estilos a un proyecto. Para tratar de ayudar a eliminar parte del ruido, examinemos algunos de los métodos más comúnmente utilizados en un nivel alto, junto con su propósito.

Opción 1: una maldita hoja de estilo

Comenzaremos con lo que es un enfoque familiar: una maldita hoja de estilo. Somos absolutamente capaces de <link> a una hoja de estilo externa dentro de nuestra aplicación y llámalo un día.

<link rel="stylesheet" href="https://css-tricks.com/the-many-ways-to-include-css-in-javascript-applications/styles.css">

Podemos escribir CSS normal al que estamos acostumbrados y seguir adelante con nuestras vidas. No hay nada de malo en eso, pero a medida que una aplicación se hace más grande y más compleja, se vuelve cada vez más difícil mantener una sola hoja de estilo. Analizar miles de líneas de CSS que son responsables de diseñar toda la aplicación se convierte en una molestia para cualquier desarrollador que trabaje en el proyecto. La cascada también es algo hermoso, pero también se vuelve difícil de administrar en el sentido de que algunos estilos que usted, u otros desarrolladores del proyecto, escriben, introducirán regresiones en otras partes de la aplicación. Hemos experimentado estos problemas antes, y se han introducido cosas como Sass (y PostCSS más recientemente) para ayudarnos a manejar estos problemas.

Podríamos continuar por este camino y utilizar el increíble poder de PostCSS para escribir parciales CSS muy modulares que se unen a través de @import reglas. Esto requiere un poco de trabajo dentro de la configuración de un paquete web para configurarse correctamente, ¡pero algo que puede manejar con seguridad!

No importa qué compilador decida usar (o no usar) al final del día, estará sirviendo un archivo CSS que contiene todos los estilos para su aplicación a través de un <link> etiqueta en el encabezado. Dependiendo de la complejidad de esa aplicación, este archivo tiene el potencial de volverse bastante hinchado, difícil de cargar de forma asincrónica y bloqueando el procesamiento para el resto de su aplicación. (Claro, el bloqueo de renderizado no siempre es algo malo, pero para todos los efectos, generalizaremos un poco aquí y evitaremos el bloqueo de renderizado de scripts y estilos siempre que podamos).

Eso no quiere decir que este método no tenga sus méritos. Para una aplicación pequeña o una aplicación creada por un equipo con menos enfoque en la interfaz, una sola hoja de estilo puede ser una buena opción. Proporciona una clara separación entre la lógica empresarial y los estilos de aplicación y, dado que nuestra aplicación no lo genera, está totalmente bajo nuestro control para garantizar que exactamente lo que escribimos sea exactamente lo que se genera. Además, un solo archivo CSS es bastante fácil de almacenar en caché para el navegador, por lo que los usuarios que regresan no tienen que volver a descargar el archivo completo en su próxima visita.

Pero digamos que estamos buscando un poco más de una arquitectura CSS robusta que nos permita aprovechar el poder de las herramientas. Algo que nos ayude a administrar una aplicación que requiere un enfoque un poco más matizado. Ingrese Módulos CSS.

Opción 2: Módulos CSS

Un problema bastante grande dentro de una sola hoja de estilo es el riesgo de regresión. Escribir CSS que utiliza un selector bastante no específico podría terminar alterando otro componente en un área completamente diferente de su aplicación. Aquí es donde un enfoque llamado “estilos con alcance” resulta útil.

Los estilos con ámbito nos permiten generar mediante programación nombres de clases específicos para un componente. De este modo, esos estilos se ajustan a ese componente específico, asegurando que los nombres de sus clases sean únicos. Esto conduce a nombres de clases generados automáticamente como header__2lexd. El bit al final es un selector hash que es único, por lo que incluso si tuviera otro componente llamado encabezado, podría aplicarle una clase de encabezado, y nuestros estilos con alcance generarían un nuevo sufijo hash así: header__15qy_.

Los módulos CSS ofrecen formas, según la implementación, de controlar el nombre de la clase generada, pero eso lo dejaré en manos de la documentación de los módulos CSS.

Una vez que todo está dicho y hecho, todavía estamos generando un único archivo CSS que se envía al navegador a través de un <link> etiqueta en el encabezado. Esto viene con los mismos inconvenientes potenciales (bloqueo de procesamiento, aumento de tamaño de archivo, etc.) y algunos de los beneficios (almacenamiento en caché, principalmente) que cubrimos anteriormente. Pero este método, debido a su propósito de estilos de alcance, viene con otra advertencia: la eliminación del alcance global, al menos inicialmente.

Imagina que quieres emplear el uso de un .screen-reader-text clase global que se puede aplicar a cualquier componente dentro de su aplicación. Si usa módulos CSS, tendrá que buscar el :global pseudo selector que define explícitamente el CSS dentro de él como algo a lo que otros componentes de la aplicación pueden acceder globalmente. Siempre que importe la hoja de estilo que incluye su :global bloque de declaración en la hoja de estilo de su componente, tendrá el uso de ese selector global. No es un gran inconveniente, sino algo a lo que hay que acostumbrarse.

He aquí un ejemplo de :global pseudo selector en acción:

// typography.css
:global {
  .aligncenter {
    text-align: center;
  }
  .alignright {
    text-align: right;
  }
  .alignleft {
    text-align: left;
  }
}

Puede correr el riesgo de dejar caer un montón de selectores globales para tipografía, formas y solo elementos generales que la mayoría de los sitios tienen en un solo :global selector. Afortunadamente, gracias a la magia de cosas como PostCSS Nested o Sass, puedes importar parciales directamente en el selector para hacer las cosas un poco más limpias:

// main.scss
:global {
  @import "typography";
  @import "forms";
}

De esta forma, puede escribir sus parciales sin el :global selector, y simplemente impórtelos directamente en su hoja de estilo principal.

Otro bit al que cuesta acostumbrarse es cómo se hace referencia a los nombres de clases dentro de los nodos DOM. Dejaré que los documentos individuales de Vue, React y Angular hablen por sí mismos allí. También te dejo con un pequeño ejemplo de cómo se ven esas referencias de clase utilizadas dentro de un componente de React:

// ./css/Button.css

.btn {
  background-color: blanchedalmond;
  font-size: 1.4rem;
  padding: 1rem 2rem;
  text-transform: uppercase;
  transition: background-color ease 300ms, border-color ease 300ms;

  &:hover {
    background-color: #000;
    color: #fff;
  }
}

// ./Button.js

import styles from "./css/Button.css";

const Button = () => (
  <button className={styles.btn}>
    Click me!
  </button>
);

export default Button;

El método de módulos CSS, nuevamente, tiene algunos casos de uso excelentes. Para las aplicaciones que buscan aprovechar los estilos con alcance y al mismo tiempo mantener los beneficios de rendimiento de una hoja de estilo estática pero compilada, los módulos CSS pueden ser la opción adecuada para usted.

También vale la pena señalar aquí que los módulos CSS se pueden combinar con su versión favorita de preprocesamiento CSS. Sass, Less, PostCSS, etc. pueden integrarse en el proceso de compilación utilizando módulos CSS.

Pero digamos que su aplicación podría beneficiarse de estar incluida en su JavaScript. Quizás también sería beneficioso obtener acceso a los diversos estados de sus componentes y reaccionar en función del estado cambiante. ¡Digamos que también desea incorporar fácilmente CSS crítico en su aplicación! Ingrese CSS-in-JS.

Opción 3: CSS-en-JS

CSS-in-JS es un tema bastante amplio. Hay varios paquetes que funcionan para hacer que la escritura de CSS-in-JS sea lo más sencilla posible. Los marcos como JSS, Emotion y Styled Components son solo algunos de los muchos paquetes que comprenden este tema.

Como explicación general para la mayoría de estos marcos, CSS-in-JS funciona en gran medida de la misma manera. Escribe CSS asociado con su componente individual y su proceso de construcción compila la aplicación. Cuando esto sucede, la mayoría de los marcos CSS-in-JS generarán el CSS asociado solo de los componentes que se representan en la página en un momento dado. Los marcos CSS-in-JS hacen esto al generar ese CSS dentro de un <style> etiqueta en el <head> de su aplicación. ¡Esto le brinda una estrategia crítica de carga de CSS lista para usar! Además, al igual que los módulos CSS, los estilos tienen un alcance y los nombres de las clases tienen hash.

A medida que navega por su aplicación, los componentes que están desmontados tendrán sus estilos eliminados de la <head> y sus componentes entrantes que están montados tendrán sus estilos adjuntos en su lugar. Esto brinda la oportunidad de obtener beneficios de rendimiento en su aplicación. Elimina una solicitud HTTP, no bloquea el procesamiento y garantiza que los usuarios solo descarguen lo que necesitan para ver la página en un momento dado.

Otra oportunidad interesante que brinda CSS-in-JS es la capacidad de hacer referencia a varios estados y funciones de los componentes para representar diferentes CSS. Esto podría ser tan simple como replicar un cambio de clase basado en algún cambio de estado, o ser tan complejo como algo así como un tema.

Debido a que CSS-in-JS es un tema bastante #hotdrama, me di cuenta de que hay muchas formas diferentes en que la gente está tratando de abordar esto. Ahora, comparto los sentimientos de muchas otras personas que tienen en alta estima a CSS, especialmente cuando se trata de aprovechar JavaScript para escribir CSS. Mis reacciones iniciales a este enfoque fueron bastante negativas. No me gustó la idea de contaminar los dos. Pero quería mantener la mente abierta. Veamos algunas de las características que nosotros, como desarrolladores enfocados en el front-end, necesitaríamos para siquiera considerar este enfoque.

  • Si estamos escribiendo CSS-in-JS, tenemos que escribir verdadero CSS. Varios paquetes ofrecen formas de escribir CSS literal de plantilla, pero requieren que coloque sus propiedades en mayúsculas y minúsculas, es decir, padding-left se convierte en paddingLeft. Eso no es algo que personalmente esté dispuesto a sacrificar.
  • Algunas soluciones CSS-in-JS requieren que escriba sus estilos en línea en el elemento que está intentando diseñar. La sintaxis para eso, especialmente dentro de componentes complejos, comienza a ponerse muy agitada y, nuevamente, no es algo que esté dispuesto a sacrificar.
  • El uso de CSS-in-JS tiene que proporcionarme herramientas poderosas que de otra manera serían muy difíciles de lograr con módulos CSS o una hoja de estilo.
  • Tenemos que ser capaces de aprovechar CSS con visión de futuro, como el anidamiento y las variables. También tenemos que poder incorporar cosas como Autoprefixer y otros complementos para mejorar la experiencia del desarrollador.

Es mucho pedirle a un marco, pero para aquellos de nosotros que hemos pasado la mayor parte de nuestra vida estudiando e implementando soluciones en torno a un idioma que amamos, tenemos que asegurarnos de poder seguir escribiendo ese mismo idioma de la mejor manera. podemos.

Aquí hay un vistazo rápido a cómo podría verse un componente de React que usa componentes con estilo:

// ./Button.js
import styled from 'styled-components';

const StyledButton= styled.button`
  background-color: blanchedalmond;
  font-size: 1.4rem;
  padding: 1rem 2rem;
  text-transform: uppercase;
  transition: background-color ease 300ms, border-color ease 300ms;

  &:hover {
    background-color: #000;
    color: #fff;
  }
`;

const Button = () => (
  <StyledButton>
    Click Me!
  </StyledButton>
);

export default Button;

También debemos abordar las posibles desventajas de una solución CSS-in-JS, y definitivamente no como un intento de generar más dramatismo. Con un método como este, es increíblemente fácil para nosotros caer en una trampa que nos lleva a un archivo de JavaScript inflado con potencialmente cientos de líneas de CSS, y todo eso viene antes de que el desarrollador incluso vea cualquiera de los métodos del componente o su HTML. estructura. Sin embargo, podemos ver esto como una oportunidad para examinar muy de cerca cómo y por qué estamos construyendo componentes de la forma en que son. Al pensar un poco más profundamente en esto, podemos potencialmente usarlo en nuestro beneficio y escribir código más sencillo, con componentes más reutilizables.

Además, este método desdibuja absolutamente la línea entre la lógica empresarial y los estilos de aplicación. Sin embargo, con una arquitectura bien documentada y pensada, otros desarrolladores del proyecto pueden aceptar esta idea sin sentirse abrumados.

TL; DR

Hay varias formas de manejar la bestia que es la arquitectura CSS en cualquier proyecto y hacerlo mientras se usa cualquier marco. El hecho de que nosotros, como desarrolladores, tengamos tantas opciones es súper emocionante e increíblemente abrumador. Sin embargo, el tema principal que creo que sigue perdiéndose en las conversaciones supercortas de las redes sociales que acabamos teniendo, es que cada solución tiene sus propios méritos y sus propias ineficiencias. Se trata de cómo implementamos de manera cuidadosa y reflexiva un sistema que nos hace a nosotros mismos en el futuro, y / u otros desarrolladores que pueden tocar el código, gracias por tomarnos el tiempo para establecer esa estructura.

(Visited 9 times, 1 visits today)