CSS Modules em aplicações React
Quem desenvolve aplicações utilizando Angular normalmente está acostumado com o uso do CSS Modules. Essa feature é responsável por manter, em somente um componente, o escopo de um arquivo de estilo (.css, sass etc.). Isso traz algumas vantagens, como evitar colisões com classes e seletores usados em outros lugares da aplicação, além de facilitar a localização dos estilos que efetivamente estão sendo aplicados àquele componente.
Como aqui no blog da Iteris estamos sempre trazendo dicas e novidades, confira um passo a passo que produzimos para demonstrar a criação de uma nova aplicação com esse comportamento, tanto em Angular como em React.
The Angular Way
Primeiramente, abra um shell e instale o Angular com o seguinte comando:
npm install -g @angular/cli
Após a instalação, execute os comandos a seguir para criar uma nova aplicação e executá-la:
ng new angular-app
cd angular-app
ng-serve
Criaremos algo bem simples para demonstrar o funcionamento do CSS Modules. Nossa aplicação de exemplo terá um componente com uma div colorida e um “componente filho” com uma div exatamente igual, mas com uma cor diferente.
Comece criando o componente filho executando o comando no shell:
ng generate component child
Após a criação do componente, altere o conteúdo do arquivo src/style.css conforme o trecho abaixo:
html, body {
height: 100%;
}
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.box {
display: flex;
align-items: center;
justify-content: center;
width: 80%;
height: 80%;
}
.red {
background-color: red;
}
Agora, altere o conteúdo do arquivo src/app/app.component.html:
<div class="container">
<div class="box red">
<app-child></app-child>
</div>
</div>
Por fim, altere o conteúdo do arquivo src/app/child/child.component.html:
<div class="box red"></div>
Para conseguir visualizar o CSS Modules em funcionamento, adicione o conteúdo a seguir no arquivo src/app/child/child.component.css:
:host {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.red {
background-color: blue;
}
Analisando o source do HTML gerado pela aplicação, podemos ver que na div do componente filho foi adicionado dinamicamente o atributo “_ng-content-wpi-c1”. Esse mesmo atributo é utilizado no seletor do CSS do componente filho, sendo esse mais específico que a classe do arquivo styles.css.
Como só a div do componente filho teve o atributo adicionado, somente ela teve a cor alterada. Essa é a maneira do Angular forçar o escopo de estilos em seus componentes.
Mas… e se quisermos obter esse mesmo funcionamento em React?
The React Way
Para a criação de projetos, o React possui diferentes toolchains que variam de acordo com a necessidade (renderizados no servidor, conteúdo estático etc.). Nosso exemplo utilizará o Create React App, que é a toolchain recomendada para a criação de single-page apps.
Para criar e executar um projeto utilizando o Create React App, execute os seguintes comandos no shell:
npx create-react-app react-app
cd react-app
npm start
Após a criação do projeto, crie uma pasta chamada Child dentro de src e crie os arquivos Child.js e Child.css. Agora, iremos replicar o mesmo layout que foi utilizado no projeto Angular.
Altere o conteúdo do arquivo src/App.js:
import React from 'react';
import './App.css';
import Child from './Child/Child';
function App() {
return (
<div className="container">
<div className="box red">
<Child></Child>
</div>
</div>
);
}
export default App;
Agora, altere o conteúdo do arquivo src/App.css:
/* You can add global styles to this file, and also import other style files */
html, body, #root {
height: 100%;
}
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.box {
display: flex;
align-items: center;
justify-content: center;
width: 80%;
height: 80%;
}
.red {
background-color: red;
}
Altere o conteúdo do arquivo src/Child/Child.js:
import React from 'react';
import './Child.css'
function Child() {
return (
<div className="red"></div>
);
}
export default Child;
Por fim, altere o conteúdo do arquivo src/Child/Child.css:
.red {
background-color: blue;
}
Podemos observar que o React simplesmente adicionou o CSS de nosso componente Child aos styles sem nenhuma alteração, fazendo com que as duas divs, pai e filho, tenham suas cores alteradas.
Então como implementamos o CSS Modules nesse caso?
Essa feature não é algo embutido no próprio React, e sim uma configuração habilitada no Webpack pelo Create React App. Para o Webpack identificar que um arquivo de estilo deve ser utilizado em um escopo de componente, o arquivo de css de nosso componente Child deve seguir o formato [nome].module.css. Em nosso caso, devemos alterar o nome do nosso arquivo de Child.css para Child.module.css. Não se esqueça de alterar a referência no Child.js.
Por que será que não funcionou? Na verdade, o funcionamento do CSS Modules em React é um pouco diferente da versão em Angular.
Como pudemos ver em nossa aplicação em Angular, ao gerar o HTML e o CSS que será provido do navegador, o compilador do Angular adicionou atributos aos elementos do nosso componente filho, além de adicionar o mesmo atributo aos seletores do arquivo de estilo do componente.
Para a aplicação React, o Webpack cria para os arquivos seletores únicos, que seguem a nomenclatura de [nome].module.css. Então precisamos, de alguma maneira, informar esse seletor gerado em nosso componente. Felizmente, isso é muito simples de ser feito. Altere o arquivo src/Child/Child.js conforme o código abaixo:
import React from 'react';
import styles from './Child.module.css'
function Child() {
return (
<div className={`box ${styles.red}`}></div>
);
}
export default Child;
Agora sim! O seletor gerado pelo Webpack foi utilizado corretamente em nosso componente filho, fazendo com que ficasse com a cor diferente.
Existem outras funcionalidades bem úteis disponibilizadas pelo Create React App, portanto busque sempre consultar sua documentação, além da documentação oficial do React, para acompanhar as novidades.
O projeto pode ser baixado pelo link: https://github.com/sandrocaseiro/react-css-module.
A Iteris tem especialistas aptos a avaliar sua ideia de negócio digital de ponta a ponta e recomendar o melhor caminho para chegar no software que você imagina para sua empresa. Entre em contato e saiba mais sobre como podemos te ajudar nos desafios da sua TI.