Sejam bem-vindos a mais este curso de React na Alura. Eu sou Vinicios Neves, e estou aqui para ajudar nesta jornada de estilização de aplicativos React. Se já possuímos conhecimento prévio de React, compreendemos o funcionamento dos componentes e temos familiaridade com JSX, vamos prosseguir nesta jornada.
A primeira etapa será entender o estado da arte e o panorama de estilização de aplicativos React. Vamos explorar a principal diferença ao pensar e organizar os estilos de um site tradicional em comparação com componentes React.
Vamos primeiro entender com o que precisamos nos preocupar e conhecer as possíveis opções. Vamos explorar as diversas maneiras de estilizar aplicativos React, mas nos aprofundaremos em duas delas: CSS Modules e Tailwind CSS. Vamos construir o Poupaapp utilizando essas duas tecnologias, o que nos permitirá compará-las. No final, poderemos decidir qual delas preferimos.
O curso está repleto de desafios, então, se desejarmos não apenas aprender, mas também praticar, nos arriscar e nos desafiar, estamos no lugar certo. Esperamos que todos estejam tão animados quanto nós para começar a criar o Poupaapp. Estaremos aguardando no próximo vídeo e prometemos que não sairemos daqui. Vamos criar o Poupaapp e aprender sobre CSS Modules e Tailwind CSS. Vamos começar?
Vamos iniciar nossa discussão sobre a estilização no React. Precisamos entender que, ao criar componentes, o paradigma de estilização é diferente. O que isso significa? Não devemos mais pensar em páginas globais ou em blocos de páginas, mas sim em componentes reutilizáveis. Para que um componente seja 100% reutilizável, devemos ter cuidado com elementos externos ou outros componentes que possam afetá-lo, como ocorre no CSS tradicional.
Quando estilizamos um site para a web, geralmente temos um arquivo global, como styles.css
. Às vezes, conseguimos dividir isso em arquivos menores, separados por contexto, mas, ainda assim, todo CSS é, por padrão, global. Isso nos obriga a ter cuidado com seletores amplos. Por exemplo, se selecionarmos uma tag, todas as tags selecionadas terão aquele estilo aplicado. Assim, a estilização e os elementos que podem afetar uma parte da aplicação, ou seja, o componente, ficam espalhados pelo código.
Se analisarmos um exemplo na tela, como o que trouxemos, temos uma classe, um seletor .card
, .card-title
e .card-description
, e o HTML correspondente do lado esquerdo. Imagine que estamos criando um card, algo genérico, mas se outra pessoa criar um seletor .card
sem cuidado, ou se a base de código for grande demais para ser lida, haverá conflitos. Teremos estilos conflitantes, o que dificultará a depuração. Portanto, o paradigma de CSS global não funciona bem com aplicações React.
Aqui está um exemplo de como isso pode ser implementado em HTML e CSS:
<div class="card">
<h2 class="card-title">Título</h2>
<p class="card-description">Descrição...</p>
</div>
<div class="card">
<h2 class="card-title">Título</h2>
<p class="card-description">Descrição...</p>
</div>
<div class="card">
<h2 class="card-title">Título</h2>
<p class="card-description">Descrição...</p>
</div>
.card {
background: white;
padding: 20px;
}
.card-title {
font-size: 18px;
}
.card-description {
font-size: 14px;
}
Podemos ter estilos globais, como definir uma fonte padrão ou aplicar uma fonte específica em toda a aplicação, definir o tamanho de fonte base ou cores que serão usadas globalmente. Isso é tranquilo. No entanto, quando falamos de estilização de componentes, o caminho é diferente. E é sobre esses caminhos diferentes que vamos falar agora.
No caso de componentes React, devemos pensar em quais cuidados tomar ao estilizar componentes, e não uma página inteira. Um componente deve ser autocontido, ou seja, ele mesmo gerencia seu estilo. Ele pode reagir ao estado e ter estilos diferentes baseados em uma prop (propriedade) passada, mas, via de regra, a não ser que haja uma boa exceção, o próprio componente cuida do seu estilo.
Por exemplo, um botão pode ter um fundo colorido normal, ser um botão outline (com fundo transparente e apenas uma borda), ou ser um botão com ícone. Podemos controlar esses estilos através de props, sem reestilizá-lo a cada uso. A ideia é que ele seja autossuficiente. Se, ao planejar e codificar um componente, percebemos que as props são muitas ou complexas, talvez seja melhor dividir o componente em partes menores. Isso facilita a manutenção e a vida útil do componente, reduzindo o risco de causar um bug.
Ao analisar um componente, como o exemplo do card, podemos planejar um CSS específico para ele, aplicando o className
no estilo tradicional que já vimos em cursos anteriores. Quais cuidados devemos ter? Ao importar estilos.card.css
, mesmo que esteja separado em uma pasta relacionada a um componente específico, ele ainda é global. Esses estilos podem vazar para outras partes da aplicação se não tivermos cuidado. Devemos evitar seletores muito genéricos, como title
, header
, footer
, card
. Quanto menos genéricos formos, mais difícil será conflitar o estilo sem querer.
Aqui está um exemplo de como podemos estruturar um componente Card em React:
// Card.jsx
import './estilos.card.css';
function Card({ title, children }) {
return (
<div className="card">
<h2 className="card-title">{title}</h2>
<div className="card-body">{children}</div>
</div>
);
}
Falamos bastante sobre CSS tradicional e global, mas o React oferece várias ferramentas para escolhermos como aplicar estilo na aplicação. Vamos explorar essas técnicas. Primeiro, o CSS tradicional, que já mencionamos. O CSS é global, e fazemos um import para utilizá-lo. O cuidado necessário é que o estilo é global e pode vazar para outros componentes. Devemos usar convenções de nomenclatura e técnicas para evitar colisões e vazamentos indesejados.
Por exemplo, temos um style.css
, importamos e está feito. O próprio Vite já sabe lidar com isso. Outra opção é o estilo inline. Isso significa abrir uma propriedade style
no HTML e aplicar o estilo como se fosse JavaScript. Isso funciona bem quando queremos variar muito o estilo baseado em uma prop e outras condições.
Com isso, o que ganhamos? O estilo não vaza, mas precisamos tomar cuidado, pois isso pode crescer de forma desorganizada. Vamos evitar colisões por um lado, mas isso pode gerar outros tipos de problemas. Trouxemos um exemplo para analisarmos. Nesse cenário, temos o componente botão, que possui definido o background-color
, a cor, o padding
, entre outros. Note que, apesar de os nomes das propriedades serem muito parecidos com o que temos no CSS, eles serão ligeiramente diferentes. Por exemplo, background-color
se torna backgroundColor
, com "C" maiúsculo. O VS Code possui um autocomplete muito bom para esse tipo de situação, facilitando a alteração sem medo de errar o nome de uma propriedade.
Aqui está um exemplo de como podemos aplicar estilos inline em um componente Button:
function Button() {
return (
<button style={{
backgroundColor: 'blue',
color: 'white',
padding: '10px' }}>
Clique aqui
</button>
);
}
O que mais temos aqui? CSS Modules. Ele é muito parecido com o estilo e o paradigma do CSS tradicional, porém, resolve um dos nossos grandes problemas: o escopo local. O que significa escopo local? Significa que o CSS de um componente não vai vazar para os outros, permanecendo bem definido. Escolhemos quais classes vamos usar, mas o próprio CSS Modules faz um trabalho para evitar colisões de nome. Ele aplica alguns ajustes, e o que será compilado no final não é a classe que colocamos, mas algo gerado pelo módulo. Isso gera nomes únicos, e começamos a importar os estilos como se fossem um objeto JavaScript. No exemplo que trouxemos, do lado esquerdo, temos o CSS normal, com um ponto botão e os estilos dentro, e um ponto botão hover, um pseudo-seletor. Quando olhamos para o componente, estamos importando styles
de Botao.module.css
, como se fosse um módulo CSS. Na hora de aplicar, chamamos o className
e usamos styles.botao
. Em vez de passar uma string, estamos passando uma propriedade de um objeto JavaScript. Isso resolve problemas de conflitos de estilos, vazamento de estilos, colisão de nomes, entre outros.
Aqui está um exemplo de como podemos usar CSS Modules em um componente Botão:
.botao {
background-color: #0070f3;
color: white;
padding: 10px 16px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
}
.botao:hover {
background-color: #0059c1;
}
import styles from './Botao.module.css'
export default function Botao({ texto }) {
return <button className={styles.botao}>{texto}</button>
}
O que mais temos? CSS em JS. É muito parecido com o conceito de usar JavaScript para compilar. Qual é o paradigma, a ideia desse CSS em JS? O próprio JSX conterá o estilo, eliminando a separação do arquivo CSS. O JSX será autossuficiente, preparado para ser dinâmico e reativo ao estado. Quando o estado muda, o estilo reflete essa alteração, evitando problemas de vazamento de CSS e colisão de nomes. O exemplo que trouxemos é o styled-components. Note que ele possui uma sintaxe específica, onde fazemos styled.button
, usando um template string. O styled.button
é uma função, e passamos para essa função essa string. O próprio styled-components sabe como lidar com isso. Detalhe: o styled-components está depreciado. A pessoa que mantinha o styled-components identificou que o uso estava caindo e optou por não manter mais. Porém, isso não muda a quantidade de aplicações que já utilizam essa abordagem. Vale a pena conhecer e entender como funciona. Em regra, parece muito com CSS tradicional, mas tudo está dentro do JSX.
Aqui está um exemplo de como podemos usar styled-components:
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? 'blue' : 'gray'};
color: white;
`;
<Button primary>Clique aqui</Button>
O que mais temos aqui? Utility First. O que queremos dizer com Utility First? Em vez de escrevermos arquivos CSS, usamos classes predefinidas por uma biblioteca, aplicando qualquer estilo CSS que aplicaríamos normalmente. A ideia é que isso vai direto no componente, evitando a necessidade de criar arquivos CSS em excesso, aumentando a produtividade. No entanto, há uma curva inicial alta. Isso significa que, para pegarmos o ritmo e entendermos como funciona, leva tempo. Com tudo isso, é importante cuidar da organização do nosso código, pois quando começamos a ter estados que variam com base em props, a situação pode se complicar. No exemplo que trouxemos, estamos usando classes do Tailwind. Note que temos classes como bg-blue-500
, que define o background, text-white
, que define a cor do texto como branca, px-4
, que define o padding horizontal como 4, e py-2
, que define o padding vertical como 2. Estamos usando pequenas classes, seguindo as convenções da biblioteca escolhida, como o Tailwind. O próprio Tailwind traduz e lida com isso, preparando a aplicação para produção.
Aqui está um exemplo de como podemos usar classes do Tailwind:
<button className="bg-blue-500 text-white px-4 py-2">
Salvar
</button>
Era isso que queríamos discutir, oferecendo um panorama. Neste curso, vamos nos especializar em duas dessas alternativas. Vamos falar mais sobre CSS Modules e praticar, e depois, na sequência, abordaremos o Tailwind e, obviamente, praticaremos também. Esse era o objetivo da conversa: mostrar o estado da arte dos estilos CSS dentro de um aplicativo React. Agora, estamos prontos, com a bagagem bem definida, para continuar nossos estudos e aplicar os estilos na nossa aplicação. Vamos lá? Estamos esperando na sequência.
Vamos prosseguir com nossos estudos e falar um pouco mais sobre CSS e módulos. Agora é o momento de respirarmos profundamente para fazermos um mergulho mais aprofundado. Antes de aprendermos como implementar, é importante entender por que essa técnica existe e qual foi o contexto que levou ao seu desenvolvimento. Vamos segurar a ansiedade para colocar a mão no código, pois já já faremos isso. Primeiro, vamos falar sobre CSS Modules.
Observando nossos slides, vemos que o CSS tradicional é global por padrão. Quando temos uma classe, como .botao
, qualquer elemento em qualquer lugar da página que possua essa classe terá o estilo aplicado. Isso pode levar a conflitos de estilos ou colisões de nomes, onde aplicamos um estilo sem querer, resultando em bugs de tamanho ou cor que não desejamos. Precisamos então depurar, entender de onde vem o problema e ajustá-lo para que tudo fique correto. Esse é o problema que enfrentamos no dia a dia.
Para ilustrar, vamos ver um exemplo de como o CSS tradicional pode ser aplicado:
/* botao.estilos.css */
.botao {
background: red;
}
E como isso seria utilizado em um componente React:
import './botao.estilos.css'
const Botao = ({ children }) => {
return (
<button className="botao">
{children}
</button>
)
}
O primeiro ponto é que, sem querer, podemos afetar um elemento. Se não tomarmos cuidado, os nomes de classe podem virar uma bagunça. Isso não significa que não há solução; existem técnicas para lidar com isso, que estão disponíveis no material de apoio para quem quiser entender mais sobre essas técnicas. No entanto, se não tomarmos cuidado, a desorganização é inevitável. Precisamos seguir uma convenção para evitar esse tipo de comportamento.
A situação se complica em projetos grandes, com equipes numerosas, tornando-se cada vez mais desafiador manter essa abordagem sem perder muito tempo corrigindo problemas que deveriam ser simples. Enquanto o CSS é global por padrão, o CSS Modules é local por padrão, evitando vazamentos. Não precisamos nos preocupar com colisões de nomes, pois podemos criar uma classe .botao
várias vezes sem medo, já que o CSS Modules gerencia isso.
Vamos ver como o CSS Modules resolve esse problema. Primeiro, criamos um arquivo CSS Module:
/* Botao.module.css */
.botao {
background-color: blue;
}
E importamos esse módulo no nosso componente:
import styles from './Botao.module.css'
export function Botao({ children }) {
return <button className={styles.botao}>
{children}</button>
}
No exemplo de código, vemos que é muito simples usar CSS Modules. Importamos um arquivo CSS como se fosse um objeto JavaScript e passamos um styles.botao
, que referencia o seletor no arquivo Botao.module.css
. Nesse cenário, temos segurança, pois não alteramos a cor, tamanho ou espaçamento de um elemento sem querer. Os componentes são isolados e mais fáceis de manter, pois são autocontidos. Mesmo que cometamos um erro, afetaremos apenas o componente específico em questão.
Quando utilizamos CSS Modules, é importante dar os devidos créditos aos criadores, Glen Maddern e Mark Dalgleish. O CSS Modules surgiu em 2015 e não foi criado do nada; inicialmente, utilizava algumas funcionalidades do Webpack para alcançar o mesmo resultado. Hoje, ele é suportado por padrão por ferramentas como Webpack, Vite (que é o que vamos usar), Parcel, entre outras. Antes, era necessário realizar um trabalho adicional para fazê-lo funcionar, mas agora, ao utilizarmos o Vite, por exemplo, ele já funciona por padrão, sem a necessidade de implementações ou instalações adicionais.
O que acontece por debaixo dos panos é que, ao aplicarmos estilos em um arquivo CSS, como botao.css
, o CSS Modules cria um objeto que representa esses estilos. Ele faz um mapeamento do nome do seletor que utilizamos para a classe que o CSS Module gerou. Quando compila e transforma isso, o resultado é algo como botao___abc123
, onde abc123
é um exemplo de hash. Isso garante que cada seletor e classe seja único, evitando conflitos de nome. O CSS Modules utiliza um pseudo-seletor CSS, :local
, para isolar o CSS, garantindo que ele não vaze.
Para ilustrar, veja como o CSS é transformado durante o processo de build:
/* Antes do build */
.botao { ... }
/* Depois da build */
.Botao_botao__abc123 { ... }
E o objeto JavaScript que representa esses estilos:
// e o objeto JS:
const estilos = {
botao: 'Botao_botao__abc123'
}
O CSS Modules não foi criado apenas para React; ele também funciona com Vue, Svelte e até mesmo em aplicações vanilla, desde que utilizemos um bundler como Webpack ou Vite para lidar com essa transformação.
Agora que entendemos o contexto, a origem e o funcionamento do CSS Modules, vamos voltar ao slide onde analisamos o processo. Temos um arquivo CSS com seletores, um objeto JavaScript que o CSS Modules monta para nós, e o resultado da compilação. Essa é a mágica que acontece por debaixo dos panos, permitindo que colhamos todos os benefícios proporcionados pelo CSS Modules.
Já discutimos bastante, e agora é hora de colocar a mão no código. Vamos iniciar uma aplicação do zero, implementar uma página inteira usando essa estratégia e, enquanto implementamos, discutiremos boas práticas de estilização dentro do ecossistema do React. Nos vemos no próximo vídeo.
O curso React: utilizando CSS Modules e Tailwind para estilização de componentes possui 219 minutos de vídeos, em um total de 40 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Matricule-se no plano PLUS e garanta:
Mobile, Programação, Front-end, DevOps, UX & Design, Marketing Digital, Data Science, Inovação & Gestão, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para estudantes ultra comprometidos atingirem seu objetivo mais rápido.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Conecte-se ao mercado com mentoria personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.