Um dos grandes problemas da utilização de frameworks de desenvolvimento como o React, é a organização das folhas de estilo que serão usadas na aplicação. A abordagem em componentes deste tipo de framework costuma exigir uma atenção especial para as folhas de estilo da aplicação e como elas serão construídas.

Existem muitas alternativas para aplicar CSS aos componentes e neste artigo, iremos falar sobre uma abordagem que permite a criação de componentes HTML com formatações personalizadas: os styled components.

Preparando o projeto

Para este exemplo, eu criei um projeto React e adicionei os styled components no projeto com o comando npm i styled-components. Em seguida, renomeei o arquivo App.js para App.jsx e deletei todo o conteúdo dele.

Na imagem abaixo, você consegue ver o código que ficou no arquivo, bem como um erro relativo a forma como o return está escrito.

Esse erro vai desaparecer conforme iniciarmos nosso código.


styled components

Código inicial

Após criar o projeto, criei também o código básico abaixo para que possamos testar os styled components.

function App() {
  return (<div>
    <h1>Título da aplicação</h1>
    <h3>Subtítulo da aplicação</h3>
    <ol>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
    </ol>
  </div>);
}

Uma vez que o código básico esteja no arquivo index, podemos iniciar a aplicação com o comando npm start.

Uma vez que a aplicação esteja rodando, vamos nos deparar com a seguinte formatação da página:

styled components

Usando styled components

A abordagem de formatação usada pelos styled components é a criação de um novo componente que representa uma nova versão de uma tag HTML com uma formatação específica.

Para criarmos nossos próprios componentes, precisamos importar a biblioteca colocando import styled from “styled-components” no topo do arquivo.

Em seguida, podemos utilizar a variável styled para a criação dos nossos componentes. Os styled components basicamente irão criar uma nova versão de uma tag HTML, com a formatação que especificarmos, portanto para aplicar as formatações teremos que substituir as tags normais do HTML pelas tags criadas com a biblioteca.

A criação dos componentes se dá de uma forma diferente da forma que estamos acostumamos a definir componentes do React.

Com os styled components utilizamos a sintaxe de tagged template literals, que pode ser vista no exemplo abaixo.

Esta sintaxe nada mais é do que uma forma alternativa para a invocação de funções:

const MeuLI = styled.li`
background-color: red;
padding: 5px;
color: white;
margin: 5px;
width: 120px;
`

O código acima cria uma nova tag li com a formatação que definimos dentro da template string. Portanto, podemos substituir as tags li da aplicação pela tag formatada:

function App() {
  return (<div>
    <h1>Título da aplicação</h1>
    <h3>Subtítulo da aplicação</h3>
    <ol>
      <MeuLI>Item 1</MeuLI>
      <MeuLI>Item 2</MeuLI>
      <MeuLI>Item 3</MeuLI>
      <MeuLI>Item 4</MeuLI>
    </ol>
  </div>);
}
styled components

E assim temos o nosso componente estilizado.

Usando styled components com propriedades

Também podemos utilizar os styled components para implementar lógicas de formatação baseadas nas propriedades passadas para o componente personalizado.

Para isso, dentro da definição do componente, criamos uma função que receberá como parâmetro as propriedades passadas para o componente estilizado e então podemos criar as formatações a partir deles.

Essas formatações também serão feitas utilizando a sintaxe de tagged template literals, mas, ao invés da função styled, utilizaremos a função css que pode ser importada com o comando import {css} from “styled-components”

Um exemplo de definição de um componente pode ser visto abaixo:

const MinhaDiv = styled.div`
    display: flex;
		justify-content: center;
		align-items: center;

    ${(props) => {
        return props.col
            ? css`flex-direction: column;`
            : css`flex-direction: row;`;
    }}
`;

Aqui é importante definir que esta função aplicará estilos de acordo com as propriedades do componente deve retornar os estilos desejados.

A função do exemplo irá aplicar a direção do display flex de acordo com a propriedade col passada para o componente.

Sendo assim, o código abaixo

import styled, { css } from "styled-components";

const MeuLI = styled.li`
    background-color: red;
    padding: 5px;
    color: white;
    margin: 5px;
    width: 120px;
`;

const MinhaDiv = styled.div`
    display: flex;
		justify-content: center;
		align-items: center;

    ${(props) => {
        console.log(props);
        return props.col
            ? css`flex-direction: column;`
            : css`flex-direction: row;`;
    }}
`;

function App() {
    return (
        <MinhaDiv>
            <h1>Título da aplicação</h1>
            <h3>Subtítulo da aplicação</h3>
            <ol>
                <MeuLI>Item 1</MeuLI>
                <MeuLI>Item 2</MeuLI>
                <MeuLI>Item 3</MeuLI>
                <MeuLI>Item 4</MeuLI>
            </ol>
        </MinhaDiv>
    );
}

export default App;

irá gerar a seguinte formatação:

styled components

e adicionando a propriedade col em MinhaDIv, como mostrado abaixo

function App() {
    return (
        <MinhaDiv col>
            <h1>Título da aplicação</h1>
            <h3>Subtítulo da aplicação</h3>
            <ol>
                <MeuLI>Item 1</MeuLI>
                <MeuLI>Item 2</MeuLI>
                <MeuLI>Item 3</MeuLI>
                <MeuLI>Item 4</MeuLI>
            </ol>
        </MinhaDiv>
    );
}

temos como resultado:

styled components

Veja também

Sass: uma introdução ao pré-processador CSS

Template Strings