💅 Vamos aprender styled-components do ZERO? Bora! - Parte I
- #React
- #JavaScript
- #CSS
Adoro usar styled-components em um projeto React. A capacidade de escrever CSS diretamente no arquivo do componente é tão simples e direta, e o aumento de performance ao carregar apenas o código necessário para os componentes renderizados é excelente.
É uma ferramenta maravilhosa. Em muitos aspectos, mudou a forma como penso sobre a arquitetura CSS e me ajudou a manter minha base de código limpa e modular, assim como o React!
Mas o que é o styled-components?
Trata-se de uma biblioteca (lib) que nos permite escrever códigos CSS dentro do JavaScript. Dessa maneira não precisamos mais ficar importando nossos arquivos .css em nossas páginas, e se um dia precisarmos utilizar esse mesmo componente em outro projeto, uma das maneiras seria basicamente copiar o arquivo .js.
Com o styled-components também ganhamos de brinde compatibilidade de browsers.
Também ganhamos a regra de CSS Modules, o Styled cria um hash nas classes CSS, assim, cada componente conhece apenas o seu CSS, uma mudança em um componente será refletida somente nele.
Além de inúmeras outras vantagens, como a possibilidade de utilizar media queries de forma similar à que utilizamos com pré-processadores, sem contar que também é possível utilizar elementos aninhados, pseudo-elements, inclusive estilizar as tags html e body.
Bora codar!
Vamos criar um projeto React do zero somente para este tutorial, de quebra você já trabalha mais um pouco com componentes React.
Vamos usar o create-react-app, pois é bem simples de instalar, não precisa saber configurar webpack, e é criado um projeto em React bem simples e enxuto, pronto para o uso.
Para instalar nosso projeto vá até o seu terminal (pode ser o terminal do VScode) e digite:
npx install create-react-app tutorial-styled-components
Dica: Se você já instalou o create-react-app globalmente via npm install -g create-react-app, recomendamos que você desinstale o pacote usando `npm uninstall -g create-react-app` ou `yarn global remove create-react-app` para garantir que o npx sempre use a versão mais recente.
Ao terminar de instalar o projeto, entre no seu projeto e:
cd tutorial-styled-components
npm run start
E o aplicativo vai abrir na porta 3000:
Agora vamos para a parte divertida: styled-components!
Para instalar vá até o terminar e digite:
npm install --save styled-components
ou
npm i -S styled-components
Que é a mesma coisa, só com menos digitação, o que sempre pode ser útil.
Estilizando com styled-components!
Vamos manter esse layout que já veio com o create-react-app, mas mudar de puro CSS para styled-components?
Bora lá!
A primeira coisa que devemos fazer é eliminar o arquivo src/index.css.
Para isso, vamos criar um arquivo chamado GlobalStyles.js na pasta src para colocar os estilos globais do nosso projeto, então vamos copiar o conteúdo do index.css para lá, dessa forma:
// GlobalStyles.js
import { createGlobalStyle } from 'styled-components';
const GlobalStyles = createGlobalStyle`
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
`;
export default GlobalStyles;
Agora vamos abrir o arquivo src/index.js e fazer as seguintes alterações:
Vamos substituir a linha:
import './index.css';
Pela linha:
import GlobalStyle from './GlobalStyles';
E adicionar <GlobalStyles /> no topo da árvore do React.
Vai ficar assim seu arquivo:
import React from 'react';
import ReactDOM from 'react-dom';
import GlobalStyle from './GlobalStyles';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<GlobalStyle />
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
Pronto, agora podemos deletar o arquivo index.css da pasta src e ver que o layout no browser continua o mesmo :)
Agora nosso objetivo é remover o arquivo src/App.css que é chamado no arquivo src/App.js.
Vamos aos poucos, um pedacinho por fez.
Primeiro chamamos o styled-components no arquivo e mudamos a <div className=”App”></div>.
Como o nome da nossa função já é App, não podemos colocar o mesmo nome nessa variável, pois vai dar conflito, então podemos colocar um AppContainer, ou AppWrapper, já que engloba todo o nosso código.
Fica assim:
// App.js
import logo from './logo.svg';
import styled from 'styled-components';
const AppContainer = styled.div`
text-align: center;
`;
function App() {
return (
<AppContainer>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</AppContainer>
);
}
export default App;
Sempre colocamos depois do styled o que vamos estilizar, neste caso foi uma div, mas pode ser um header, um footer, uma section, um p, um a, ou o que a semântica exigir no momento.
Nesse caso a tag, que era assim:
<div className="App"></div>
Foi substituída por:
<AppContainer></AppContainer>
Agora podemos fazer o mesmo com os outros elementos do nosso src/App.css. Nem precisamos quebrar a cabeça para criar nomes para as nossas variáveis, é só tirar o hífen e utilizar o estilo CamelCase em cada uma: AppHeader, AppLogo e AppLink.
Fica assim:
// App.js
import logo from './logo.svg';
import styled from 'styled-components';
const AppContainer = styled.div`
text-align: center;
`;
const AppHeader = styled.header`
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
`;
const AppLogo = styled.img`
height: 40vmin;
pointer-events: none;
@media (prefers-reduced-motion: no-preference) {
animation: App-logo-spin infinite 20s linear;
}
`;
const AppLink = styled.a`
color: #61dafb;
`;
function App() {
return (
<AppContainer>
<AppHeader>
<AppLogo src={logo} alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<AppLink
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</AppLink>
</header>
</AppContainer>
);
}
export default App;
Perfeito!
Mas, pera aí, está faltando o @keyframe da animação! Como usamos a animação com styled-components?
Da documentação do styled-components:
As animações CSS com @keyframes não têm como escopo um único componente, mas você ainda não quer que elas sejam globais para evitar colisões de nomes. É por isso que exportamos um keyframes helper, que irá gerar uma instância única que você pode usar em todo o seu aplicativo.
Parece complicado tudo isso, mas vamos simplificar, basta fazer um simples import junto com o styled:
import styled, { keyframes } from 'styled-components';
O resultado fica assim:
// App.js
import logo from './logo.svg';
import styled from 'styled-components';
const AppContainer = styled.div`
text-align: center;
`;
const AppHeader = styled.header`
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
`;
const AppLogoSpin = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
const AppLogo = styled.img`
height: 40vmin;
pointer-events: none;
@media (prefers-reduced-motion: no-preference) {
animation: ${AppLogoSpin} infinite 20s linear;
}
`;
const AppLink = styled.a`
color: #61dafb;
`;
function App() {
return (
<AppContainer>
<AppHeader>
<AppLogo src={logo} alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<AppLink
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</AppLink>
</header>
</AppContainer>
);
}
export default App;
Adicionamos o AppLogoSpin antes do AppLogo no arquivo, para o AppLogoSpin já existir quando a animação for chamada, e no media queries mudamos para ${AppLogoSpin}:
animation: ${AppLogoSpin} infinite 20s linear;
Agora é só conferir lá no browser para ver que está tudo funcionando como antes, mas agora trocamos todos os arquivos .css por styled-components.
Pronto, podemos deletar o arquivo src/App.css \o/
Conclusão:
Até aqui aprendemos a trocar o css puro por styled-components em um projeto sem mudar o layout nem mexer nos estilos. Isso é de grande ajuda quando você precisa fazer esse tipo de mudança em um projeto já existente, e você viu que não é um bicho de sete cabeças, né? É só fazer aos poucos :)
No próximo artigo vamos aprofundar um pouco mais o nosso conhecimento sobre styled-components, não percam!