Comparando métodos de estilo no Next.js
Publicados: 2022-03-10Como você deve estar ciente, existem muitas perspectivas diferentes sobre CSS-in-JS, e todos nós temos uma opinião sobre o tópico de uma forma ou de outra que pode ser bem diferente das opiniões dos autores de frameworks.
Next.js é uma das cadeias de ferramentas recomendadas ao criar um novo aplicativo React. Ferramentas como Next têm um objetivo simples de abstrair tarefas comumente redundantes ao escrever um aplicativo React. Isso ajuda os desenvolvedores a se concentrarem mais em escrever código do que em reinventar a roda. Embora isso geralmente seja uma coisa boa, também pode ser um pouco tedioso para começar. Por um lado, há um obstáculo a ser superado aprendendo sobre as abstrações e, embora haja um bando disso em Next (Routing, Data Fetching…), um muitas vezes esquecido é Styling.
Para atender a um público mais amplo, o Next.js oferece suporte a várias maneiras de estilizar seus componentes. Se você pertence ao grupo Utility first ou CSS-in-JS não é muito da preocupação do Next, sua preocupação é como você injeta sua escolha em sua API.
O objetivo deste artigo é ajudá-lo a entender como configurar o estilo em seu aplicativo Next. Usaremos métodos diferentes para lidar com a comparação. Implementaremos os diferentes tipos de estilo em um aplicativo de livro que configurei. Os métodos de estilo que veremos incluem:
- CSS mundial,
- SASS/SCSS,
- SASS/SCSS em nível de componente,
- CSS em nível de componente (módulos CSS),
- Componentes estilizados,
- Com estilo JSX,
- Emoção.
Pré-requisito
Antes de começarmos nosso tour de estilo, existem algumas nuances do Next que você precisa conhecer.
-
_app.js
Este é um componente personalizado que reside na pasta de páginas. Next.js usa esse componente para inicializar páginas. -
_document.js
Assim como_app.js
,_document.js
é um componente personalizado que o Next.js usa para aumentar as tags<html>
e<body>
de seus aplicativos. Isso é necessário porque as páginas Next.js ignoram a definição da marcação do documento circundante. -
_.babelrc
Quando presente, o Next.js usa esse arquivo como a única fonte de verdade para algumas configurações internas e dá permissão para estendê-lo.
Lembre-se de que, se seu servidor estiver em execução antes de adicionar o arquivo _app.js
, será necessário reiniciá-lo.
Criando um próximo aplicativo com create-next-app
Criar um próximo aplicativo com create-next-app
é tão simples quanto seguir as etapas abaixo:
- Instale
create-next-app
globalmente.
yarn global add create-next-app // Installs create-next-app globally
- Crie um novo aplicativo Next chamado styling-in-next .
create-next-app styling-in-next // Creates a new Next app named styling-in-next
- Altere o diretório para o novo site.
cd styling-in-next // Switch directory into the new Next app
- Execute o site.
yarn dev -p 3000 // Instruct Next to run on port 3000
Consulte a documentação para obter mais informações sobre como criar e executar um aplicativo Next.
O aplicativo agora deve estar sendo executado em https://localhost:3000
.
Repositório de demonstração
À medida que avançamos, estaremos construindo uma estante de livros artificial aplicando diferentes métodos de estilo a cada livro . O resultado final ficará assim:
A imagem acima mostra 6 livros; cada livro terá seus próprios componentes, então aplicaremos um tipo de estilo específico para cada livro específico, ou seja, o Livro 1 fará uso de um estilo global enquanto o Livro 2 fará uso de outro. Assim veremos como funciona cada um desses estilos e como podem ser usados. Isso irá ajudá-lo a tomar uma melhor decisão sobre qual opção escolher.
Para simplificar as coisas, montei um repositório GitHub para você acompanhar. Você pode pegar aqui.
Algumas alterações também foram feitas no iniciador padrão gerado por create-next-app
. Pastas como emoção , global , módulos , componentes com estilo etc. foram adicionadas à pasta de styles
— com seus arquivos de estilo correspondentes — bem como um diretório de components
com vários componentes.
O arquivo index.js
foi modificado para import
e render
os components
necessários e cada um dos componentes tem uma estrutura semelhante à mostrada na imagem abaixo.
Se você clonou e executou o repositório de demonstração, veja como sua página deve ficar:
Com tudo isso fora do caminho, vamos ao estilo.
Estilo global
Uma das coisas comuns que você normalmente faria ao iniciar um novo projeto da web é redefinir ou normalizar seu CSS para que haja uma posição inicial uniforme entre os navegadores. Este é um exemplo perfeito de como usar o CSS Global sem se preocupar com o escopo.
- Atualize
styles/global/globals.css
com este Reset Mínimo de CSS estendido.
/* 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 o CSS reset
styles/global/globals.css
empages/_app.js
.
// pages/_app.js import "../styles/global/globals.css"; function MyApp({Component, pageProps}) { return <Component {...pageProps} />; } export default MyApp;
Estilos globais só podem ser importados em pages/_app.js
. Isso é diretamente lógico porque esses estilos serão aplicados a todas as pages
e components
em seu aplicativo - independentemente de onde você os importe - portanto, é melhor ter uma única fonte de verdade [importar] para manter as coisas simples e/ou se algo der certo errado.
Neste ponto, não temos muitas alterações visuais em nossa estante , pois fizemos apenas alterações de normalização . Uma coisa que você pode notar são as mudanças de fonte e espaçamento.
SASS/SCSS
Next.js também permite estilizar com SASS com a extensão .sass
ou .scss
. A instalação do Sass é um requisito. Assim como os estilos globais, eles só podem ser importados em pages/_app.js
.
- Instale o pacote Sass.
yarn add sass
- Atualize
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; } } } }
- Atualize também
styles/sass/bookone.sass
estyles/sass/booktwo.sass
assim:
// 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
) é baseado em recuo. Para facilitar a formatação, você pode instalar esta extensão VSCode para suporte a arquivos SASS (formatação, realce de sintaxe…)
- Importe os três arquivos de estilo —
styles/scss/bookshelf.scss
,styles/sass/bookone.sass
estyles/sass/booktwo.sass
— empages/_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;
Nossa estante está começando a tomar forma. Com os estilos aplicados, o primeiro e o segundo livro devem ser estilizados e exibidos conforme pretendido.
Módulos CSS
Módulos CSS é um CSS de nível de componente, que vem embutido com o Next e pode ser ativado nomeando os arquivos de estilo com a extensão .module.css
. Também é possível usar Módulos CSS com SASS/SCSS com a extensão .module.sass
ou .module.scss
.
Vamos estilizar o components/BookThree.js
com ele.
- Atualize
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
emcomponents/BookThree.js
e aplique a classe.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> ); }
Acessar nomes de classe em Módulos CSS é semelhante a Acessadores de propriedade em JavaScript — com a notação de ponto ou colchete. Aqui importamos BookThreeStyles
e então usamos a notação de colchetes para aplicar o estilo que temos no arquivo styles/modules/BookThree.module.css
.
Se o seletor (neste caso, o nome da classe) foi acessado corretamente, o terceiro livro deve ser estilizado agora.
Emoção
Emotion é uma biblioteca CSS-in-JS e, como qualquer outra CSS-in-JS, permite escrever estilos CSS com JavaScript.
Vamos estilizar o components/BookFour.js
com ele.
- Instale os pacotes:
@emotion/core
,@emotion/styled
,emotion
,emotion-server
.
yarn add @emotion/core @emotion/styled emotion emotion-server
- Atualize
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); `;
Depois de importar styled
de @emotion/styled
, exportamos o componente de estilo StyledBookFour
— não deve ser confundido com o outro componente de estilo CSS-in-JS — aprimorado com o método de emoção com styled
como em styled.div
. Então podemos usar <StyledBookFour/>
como na próxima etapa abaixo.
Saiba mais sobre a função estilizada da emoção.
- Usar
<StyledBookFour/>
é semelhante a como você usaria qualquer outro componente React. Importestyles/emotion/StyledBookFour.js
emcomponents/BookFour.js
e aplique o componenteStyledBookFour
.
// 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> ); }
Com uma dose suficiente de emoção , o quarto livro deve ser assim denominado.
JSX com estilo
Como Global CSS e CSS-Modules, Styled-JSX funciona com Next.js sem necessidade de qualquer configuração extra. Se ajudar, Styled-JSX também é a oferta da Vercel de um CSS baseado em componentes, os mesmos criadores do Next.js.
Vamos estilizar o components/BookFive.js
com ele.
Para manter as coisas simples, usamos o modo interno do styled-jsx aqui. Ao passar o prop jsx
para o componente <style/>
, podemos escrever tanto CSS quanto quisermos, como fizemos com .book-five
, com o benefício adicional de o estilo ser localizado no componente <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> ); }
E assim, o quinto livro toma seu estilo.
Componentes estilizados
Styled-Component, assim como Emotion, também é uma biblioteca CSS-in-JS que permite escrever estilos CSS com JavaScript. A configuração é um pouco complicada.
- Primeiro, instale
babel-plugin-styled-components
estyled-components
.
yarn add babel-plugin-styled-components styled-components
- Crie um arquivo
.babelrc
na raiz do seu aplicativo e um arquivopages/_document.js
, conforme mostrado na imagem antes (esquerda) e depois (direita) abaixo.
- Atualize o arquivo
.babelrc
para incluir a predefiniçãonext/babel
e incluir o plug-instyled-components
, com a renderização do lado do servidor (ssr) ativada.
// .babelrc { "presets": ["next/babel"], "plugins": [ [ "styled-components", { "ssr": true } ] ] }
- Atualize
pages/_document.js
injetando os estilos renderizados do lado do servidor no<head>
.
Lembre-se de que o snippet abaixo ( pages/_document.js
) é uma lógica necessária para que os styled-components funcionem com o Next.js. Você quase não precisa fazer nada além de copiar a lógica conforme indicado na documentação dos componentes com 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(); } } }
Após as atualizações para .babelrc
e pages/_document.js
, agora podemos começar a usar styled-components.
- Atualize
styles/styled-components/StyledBookSix.js
.
styled
é um método utilitário interno que transforma o estilo do JavaScript em CSS real. <StyledBookSix/>
é, e, pode ser usado como qualquer outro componente 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;
Saiba mais sobre Como usar componentes com estilo no React.
- Importe
styles/styled-components/StyledBookSix.js
emcomponents/BookSix.js
, usando os styled-components 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> ); }
Com a primeira a sexta etapa concluída, a sexta deve ser estilizada e a estante pronta:
É isso.
Se tudo correu bem, então você deve ter a estante completa com os livros esperando para serem lidos.
- Você pode pegar o código completo no GitHub →
Conclusão
Em meu próprio uso com Next.js, estilos globais e componentes com estilo têm sido suficientes. Mas não há dúvida de que todos esses métodos têm seus prós e contras. E ao decidir qual método usar, lembre-se: no final, é tudo CSS. Neste ponto, acredito que você possa descobrir qual padrão melhor atende a você em seu próximo projeto.
Recursos
Acho que para aprender a configurar métodos de estilo com Next.js, não há lugar melhor do que sua documentação oficial.
Mas também existem repositórios específicos para vários métodos de estilo. Você pode percorrer os vários repositórios para saber mais ou verificar se há atualizações, pois as coisas podem mudar de modo anônimo.
- CSS Tailwind
- Módulos CSS
- Menos
- Caneta
- Tailwind CSS com emoção
- Styletron
- Glamour
- CXS
- Afrodite
- Fela
- Styled-JSX