Comparación de métodos de estilo en Next.js

Publicado: 2022-03-10
Resumen rápido ↬ Entre otros, Next.js se ha denominado a sí mismo: The React Framework for Static Websites . Pero al igual que cualquier otro marco cuyo objetivo es ayudarlo a construir lo que importa al abstraer tareas comunes y redundantes, a menudo se le pide que aprenda algo nuevo y obstinado. Con Next.js, una de las cosas que debe saber es cómo integrar diferentes métodos CSS con su API, y ese es el enfoque de este tutorial.

Como sabrá, hay muchas perspectivas diferentes sobre CSS-in-JS, y todos tenemos una opinión sobre el tema de una forma u otra que puede ser bastante diferente de las opiniones de los autores del marco.

Next.js es una de las cadenas de herramientas recomendadas al crear una nueva aplicación React. Herramientas como Next tienen el objetivo simple de abstraer tareas comúnmente redundantes al escribir una aplicación React. Esto ayuda a los desarrolladores a concentrarse más en escribir código que en reinventar la rueda. Si bien esto suele ser algo bueno, también puede ser un poco tedioso para comenzar. Por un lado, hay un obstáculo que cruzar al aprender sobre las abstracciones, y aunque hay un montón de eso en Siguiente (Enrutamiento, Obtención de datos...), uno que a menudo se pasa por alto es el Estilo.

Para servir a una audiencia más amplia, Next.js admite una gran variedad de formas de diseñar sus componentes. Ya sea que pertenezca a la parte Utility first o CSS-in-JS no es una gran preocupación de Next, su preocupación es cómo inyecta su elección en su API.

El objetivo de este artículo es ayudarlo a comprender cómo configurar el estilo en su aplicación Next. Usaremos diferentes métodos para manejar la comparación. Implementaremos los diferentes tipos de estilo en una aplicación de libro que he configurado. Los métodos de estilo que veremos incluyen:

  1. CSS globales,
  2. SASS/SCSS,
  3. Nivel de componente SASS/SCSS,
  4. CSS de nivel de componente (módulos CSS),
  5. Componentes con estilo,
  6. Estilo JSX,
  7. Emoción.

Requisito previo

Antes de comenzar nuestro recorrido de estilo, hay algunos matices de Next con los que debe familiarizarse.

  1. _app.js
    Este es un componente personalizado que reside en la carpeta de páginas. Next.js usa este componente para inicializar páginas.
  2. _document.js
    Al igual que _app.js , _document.js es un componente personalizado que utiliza Next.js para aumentar las etiquetas <html> y <body> de sus aplicaciones. Esto es necesario porque las páginas de Next.js omiten la definición del marcado del documento circundante.
  3. _.babelrc
    Cuando está presente, Next.js usa este archivo como la única fuente de verdad para alguna configuración interna y le da permiso para extenderlo.

Tenga en cuenta que si tiene su servidor ejecutándose antes de agregar el archivo _app.js , debe reiniciarlo.

¡Más después del salto! Continúe leyendo a continuación ↓

Creando una próxima aplicación con create-next-app

Crear una aplicación Next con create-next-app es tan simple como seguir los pasos a continuación:

  • Instale create-next-app globalmente.
 yarn global add create-next-app // Installs create-next-app globally
  • Cree una nueva aplicación Next llamada styling-in-next .
 create-next-app styling-in-next // Creates a new Next app named styling-in-next
  • Cambie el directorio al nuevo sitio.
 cd styling-in-next // Switch directory into the new Next app
  • Ejecute el sitio.
 yarn dev -p 3000 // Instruct Next to run on port 3000

Consulte la documentación para obtener más información sobre cómo crear y ejecutar una aplicación Next.

La aplicación ahora debería estar ejecutándose en https://localhost:3000 .

Una captura de pantalla de la página de índice de inicio predeterminada de Next.js
Página de índice de inicio predeterminada de Next.js. (Vista previa grande)

Repositorio de demostración

A medida que avancemos, construiremos una estantería artificial aplicando diferentes métodos de estilo a cada libro . El resultado final se verá así:

Una captura de pantalla de la demostración final con estilo Bookshelf
Estantería de estilo final. (Vista previa grande)

La imagen de arriba muestra 6 libros; cada libro tendrá sus propios componentes, luego aplicaremos un tipo de estilo específico a cada libro específico, es decir, el Libro 1 utilizará un estilo global mientras que el Libro 2 utilizará otro. De esta forma veremos cómo funcionan cada uno de estos estilos y cómo se pueden utilizar. Esto le ayudará a tomar una mejor decisión sobre qué opción elegir.

Para simplificar las cosas, he creado un repositorio de GitHub para que lo siga. Puedes agarrarlo aqui.

También se han realizado algunos cambios en el iniciador predeterminado generado por create-next-app . Se agregaron carpetas como emoción , global , módulos , componentes con estilo, etc. a la carpeta de styles , con sus archivos de estilo correspondientes, así como un directorio de components con múltiples componentes.

Una captura de pantalla de los cambios iniciales realizados en el directorio de estilos y componentes del repositorio de demostración
Cambios en las carpetas de estilos y componentes. (Vista previa grande)

El archivo index.js se ha modificado para import y render los components necesarios, y cada uno de los componentes tiene una estructura similar a la que se muestra en la imagen a continuación.

Una captura de pantalla de los cambios iniciales realizados en BookTwo.js, BookOne.js e index.js
Cambios en los componentes individuales y archivos de índice. (Vista previa grande)

Si clonó y ejecutó el repositorio de demostración, su página debería verse así:

Una captura de pantalla de la página de índice predeterminada del repositorio de demostración
Página de índice predeterminada del repositorio de demostración. (Vista previa grande)

Con todo eso fuera del camino, comencemos con el estilo.

Estilo mundial

Una de las cosas comunes que normalmente haría cuando inicia un nuevo proyecto web es restablecer o normalizar su CSS para que haya una posición de inicio uniforme entre los navegadores. Este es un ejemplo perfecto del uso de Global CSS sin preocuparse por el alcance.

  • Actualice styles/global/globals.css con este restablecimiento mínimo de CSS extendido.
 /* styles/global/globals.css */ html { box-sizing: border-box; font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; } *, *:before, *:after { box-sizing: inherit; } body, h1, h2, h3, h4, h5, h6, p, ol, ul { margin: 0; padding: 0; font-weight: normal; } h1, h2, h3, h4, h5, h6 { font-weight: bold; } ol, ul { list-style: none; } img { max-width: 100%; height: auto; } a { color: inherit; text-decoration: none; }
  • Importe los styles/global/globals.css en pages/_app.js .
 // pages/_app.js import "../styles/global/globals.css"; function MyApp({Component, pageProps}) { return <Component {...pageProps} />; } export default MyApp;

Los estilos globales solo se pueden importar en pages/_app.js . Esto es directamente lógico porque estos estilos se aplicarán a todas las pages y components de su aplicación, independientemente de dónde los importe, por lo que es mejor tener una única fuente de verdad [importada] para mantener las cosas claras y/o si algo sale mal. incorrecto.

En este punto, no tenemos muchos cambios visuales en nuestra estantería , ya que solo hemos realizado cambios de normalización . Una cosa que puede notar es la fuente y los cambios de espaciado.

Una captura de pantalla del cambio en la estantería de demostración después de agregar un reinicio de CSS
Cambios en la página de índice después de agregar un reinicio de CSS. (Vista previa grande)

SASS/SCSS

Next.js también permite diseñar con SASS con la extensión .sass o .scss . Instalar Sass es un requisito. Al igual que los estilos globales, solo se pueden importar en pages/_app.js .

  • Instale el paquete Sass.
 yarn add sass
  • Actualice styles/scss/bookshelf.scss .
 // styles/scss/bookshelf.scss .the-bookshelf { width: 100vw; height: 100vh; background-color: #e3e3e3; display: flex; justify-content: center; align-items: center; .bookshelf-wrap { > .bookshelf { box-shadow: inset 0 -20px #7b5019; padding-bottom: 20px; display: flex; align-items: flex-end; } [class*="book"] { font-size: 32px; letter-spacing: -0.045em; display: flex; transition: 0.2s; &:hover { transform: none; } } .book-info { text-transform: uppercase; writing-mode: sideways-rl; display: flex; justify-content: space-around; flex: 1; align-items: center; font-weight: bold; padding: 16px 0; .title { font-weight: inherit; font-size: 20px; } .author { font-weight: inherit; font-size: 15px; } } } }
  • También actualice styles/sass/bookone.sass y styles/sass/booktwo.sass así:
 // styles/sass/bookone.sass .book-one color: #f00 width: 78px height: 350px transform: rotate(-4deg) margin-left: 16px margin-right: 23px background-color: black
 // styles/sass/booktwo.sass .book-two color: #781e0b width: 38px height: 448px margin-right: 23px background-color: #ffab44

SASS ( .sass ) se basa en la sangría. Para facilitar el formateo, puede instalar esta extensión VSCode para compatibilidad con archivos SASS (formato, resaltado de sintaxis...)

  • Importe los tres archivos de estilo: styles/scss/bookshelf.scss , styles/sass/bookone.sass y styles/sass/booktwo.sass , en pages/_app.js .
 // pages/_app.js import "../styles/globals.css"; import "../styles/scss/bookshelf.scss"; import "../styles/sass/bookone.sass"; import "../styles/sass/booktwo.sass"; function MyApp({Component, pageProps}) { return ; } export default MyApp; // pages/_app.js import "../styles/globals.css"; import "../styles/scss/bookshelf.scss"; import "../styles/sass/bookone.sass"; import "../styles/sass/booktwo.sass"; function MyApp({Component, pageProps}) { return ; } export default MyApp;

Nuestra Librería empieza a tomar forma. Con los estilos aplicados, el primer y el segundo libro deben diseñarse y mostrarse según lo previsto.

Una captura de pantalla del cambio en la estantería de demostración después de diseñar el primer y segundo libro con SASS
BookOne y BookTwo diseñados con SASS. (Vista previa grande)

Módulos CSS

CSS Modules es un CSS a nivel de componente, que viene integrado con Next y se puede activar nombrando los archivos de estilo con la extensión .module.css . También es posible utilizar Módulos CSS con SASS/SCSS con la extensión .module.sass o .module.scss .

Vamos a diseñar el componente components/BookThree.js con él.

  • Actualice styles/modules/BookThree.module.css .
 /* styles/modules/BookThree.module.css */ .book-three { color: #df66c3; width: 106px; height: 448px; margin-right: 23px; background-color: #153086; transform: rotate(-4deg); }
  • Importe styles/modules/BookThree.module.css en components/BookThree.js y aplique la clase .book-three .
 // components/BookThree.js import BookThreeStyles from "../styles/modules/BookThree.module.css"; export default function BookThree() { return ( <div className={BookThreeStyles["book-three"]}> <div className="book-info"> <p className="title">the revolt of the public</p> <p className="author">Martin Gurri</p> </div> </div> ); }

Acceder a los nombres de las clases en los módulos CSS es similar a los elementos de acceso a las propiedades en JavaScript, con la notación de puntos o corchetes. Aquí importamos BookThreeStyles y luego usamos la notación de paréntesis para aplicar el estilo que tenemos en el archivo styles/modules/BookThree.module.css .

Si se accedió correctamente al selector (en este caso, el nombre de la clase), el tercer libro debería tener el estilo ahora.

Una captura de pantalla del cambio en la estantería de demostración después de diseñar el tercer libro con módulos CSS
BookThree diseñado con módulos CSS. (Vista previa grande)

Emoción

Emotion es una biblioteca CSS-in-JS y, como cualquier otro CSS-in-JS, te permite escribir estilos CSS con JavaScript.

Vamos a diseñar el componente components/BookFour.js con él.

  • Instale los paquetes: @emotion/core , @emotion/styled , emotion , emotion-server .
 yarn add @emotion/core @emotion/styled emotion emotion-server
  • Actualice styles/emotion/StyledBookFour.js .
 // styles/emotion/StyledBookFour.js import styled from "@emotion/styled"; export const StyledBookFour = styled.div` color: white; width: 38px; height: 400px; margin-left: 20px; margin-right: 10px; background-color: #2faad2; transform: rotate(4deg); `;

Después de importar styled desde @emotion/styled , exportamos el componente con estilo StyledBookFour , que no debe confundirse con el otro componente con estilo CSS-in-JS, mejorado con el método de emoción con styled como en styled.div . Entonces podemos usar <StyledBookFour/> como en el siguiente paso a continuación.

Obtenga más información sobre la función de estilo de la emoción.

  • Usar <StyledBookFour/> es similar a cómo usaría cualquier otro componente de React. Importe styles/emotion/StyledBookFour.js en components/BookFour.js y aplique el componente StyledBookFour .
 // components/BookFour.js import {StyledBookFour} from "../styles/emotion/StyledBookFour"; export default function BookFour() { return ( <StyledBookFour className="book-four"> <div className="book-info"> <p className="title">the man died</p> <p className="author">wole soyinka</p> </div> </StyledBookFour> ); }

Con una suficiente dosis de emoción , el cuarto libro debería ser así estilizado.

Una captura de pantalla del cambio a la estantería de demostración después de diseñar el cuarto libro con Emoción
BookFour diseñado con Emoción. (Vista previa grande)

JSX con estilo

Al igual que Global CSS y CSS-Modules, Styled-JSX funciona con Next.js sin necesidad de configuración adicional. Si ayuda, Styled-JSX también es la oferta de Vercel de un CSS basado en componentes, los mismos creadores de Next.js.

Vamos a diseñar el componente components/BookFive.js con él.

Para simplificar las cosas, aquí usamos el modo interno de styled-jsx. Al pasar el jsx prop al componente <style/> , podemos escribir todo el CSS que queramos como lo hicimos con .book-five , con el beneficio adicional de que el estilo se localiza en el <BookFive/> .

 // components/BookFive.js export default function BookFive() { return ( <div className="book-five"> <div className="book-info"> <p className="title">there was a country</p> <p className="author">Chinua Achebe</p> </div> <style jsx>{` .book-five { color: #fff; width: 106px; height: 448px; margin-right: 23px; background-color: #000; transform: rotate(4deg); } `}</style> </div> ); }

Y así, el quinto libro toma su estilismo.

Una captura de pantalla del cambio en la estantería de demostración después de diseñar el quinto libro con Styled JSX
BookFive diseñado con Styled JSX. (Vista previa grande)

Componentes con estilo

Styled-Component, al igual que Emotion, también es una biblioteca CSS-in-JS que le permite escribir estilos CSS con JavaScript. Conseguirlo configurar es un poco complicado.

  • Primero, instale babel-plugin-styled-components y styled-components .
 yarn add babel-plugin-styled-components styled-components
  • Cree un archivo .babelrc en la raíz de su aplicación y un archivo pages/_document.js , como se muestra en la imagen anterior (izquierda) y posterior (derecha) a continuación.
Una captura de pantalla del cambio en la estantería de demostración después de agregar dos archivos nuevos: <code>_.document.js</code> y <code>.babelrc</code>
Se agregaron nuevos archivos: _document.js y .babelrc . (Vista previa grande)
  • Actualice el archivo .babelrc para incluir el ajuste preestablecido next/babel e incluya el complemento styled-components , con la representación del lado del servidor (ssr) habilitada.
 // .babelrc { "presets": ["next/babel"], "plugins": [ [ "styled-components", { "ssr": true } ] ] }
  • Actualice pages/_document.js inyectando los estilos representados del lado del servidor en <head> .

Tenga en cuenta que el fragmento a continuación ( pages/_document.js ) es una lógica necesaria para que los componentes con estilo funcionen con Next.js. Casi no tiene que hacer nada más que copiar la lógica como se indica en la documentación de componentes con estilo.

 // pages/_document.js import Document from "next/document"; import {ServerStyleSheet} from "styled-components"; export default class MyDocument extends Document { static async getInitialProps(ctx) { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => originalRenderPage({ enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} {sheet.getStyleElement()} </> ), }; } finally { sheet.seal(); } } }

Después de las actualizaciones de .babelrc y pages/_document.js , ahora podemos comenzar a usar componentes con estilo.

  • Actualice styles/styled-components/StyledBookSix.js .

styled es un método de utilidad interno que transforma el estilo de JavaScript en CSS real. <StyledBookSix/> es y puede usarse como cualquier otro componente de React.

 // styles/StyledBookSix.js import styled from "styled-components"; const StyledBookSix = styled.div` color: #fff; width: 106px; height: 448px; margin-right: 23px; background-color: rebeccapurple; `; export default StyledBookSix;

Obtenga más información sobre cómo usar componentes con estilo en React.

  • Importe styles/styled-components/StyledBookSix.js en components/BookSix.js , utilizando los componentes con estilo importados <StyledBookSix/> .
 // components/BookSix.js import StyledBookSix from "../styles/styled-components/StyledBookSix"; export default function BookSix() { return ( <StyledBookSix className="book-six"> <div className="book-info"> <p className="title">purple hibiscus</p> <p className="author">chimamanda ngozi adichie</p> </div> </StyledBookSix> ); }

Una vez completados los pasos del primero al sexto, se debe diseñar el sexto y terminar la estantería:

Una captura de pantalla del cambio en la estantería de demostración después de diseñar el sexto libro con componentes con estilo
BookSix diseñado con componentes con estilo. (Vista previa grande)

Eso es todo.

Si todo salió bien, deberías tener la estantería completa con los libros esperando a ser leídos.

  • Puedes obtener el código completo en GitHub →

Conclusión

En mi propio uso con Next.js, los estilos globales y los componentes con estilo a menudo han sido suficientes. Pero no hay duda de que todos estos métodos tienen sus pros y sus contras. Y mientras decide qué método usar, solo tenga en cuenta: al final, todo es CSS. En este punto, creo que puede descubrir qué patrón le sirve mejor en su próximo proyecto.

Recursos

Encuentro que para aprender a configurar métodos de diseño con Next.js, no hay mejor lugar que su documentación oficial.

Pero también hay repositorios específicos para varios métodos de estilo. Puede revisar los distintos repositorios para obtener más información o buscar actualizaciones, ya que las cosas pueden cambiar de incógnito.

  1. CSS viento de cola
  2. Módulos CSS
  3. Menos
  4. Aguja
  5. Tailwind CSS con emoción
  6. Styletron
  7. Glamour
  8. CXS
  9. Afrodita
  10. Fela
  11. Estilo-JSX