DEV Community

loading...

Porque utilizar css-modules no React

gmantovani97 profile image gmantovani97 ・3 min read

Motivação

Conforme o projeto vai crescendo, muitos problemas começam a surgir por decisões tomadas no início, quando aquilo não parecia ser um problema ou talvez nem fosse imaginado. Um desses problemas pode ser a falta de padrão nos estilos, e um problema que é originado a partir disso é a confusão gerada com os classNames.

Problema

O problema com os classNames ocorre da seguinte maneira. Imaginem um nome de className bastante utilizado por todos, no caso irei explicar utilizando o nome "title". Todos os lugares em que utilizamos o "title" precisamos criar um nome composto para que não haja globalidade entre os estilos, então caso formos utilizar dentro de um card, criaremos o "card-title", caso seja uma modal, será "modal-title", e cada vez ficará mais difícil para pensar num bom nome de className para cada componente.

Solucão

Desde a versão 2 do CRA (create-react-app) temos a opcão de criar estilos únicos para cada componente, utilizando os css-modules. Os css-modules são arquivos css em que os classNames e animações são definidos localmente, isso significa que os estilos ali criados, só serão declarados dentro daquele escopo, e não globalmente, evitando conflitos entre estilos.

Explicação

Abaixo temos um arquivo .jsx contendo um card simples sem a utilização de css-modules:

import React from 'react';
import './styles.scss';

function Card() {
  return (
    <div className="container">
      <h1 className="title">Card title</h1>
      <span className="description">Card description</span>
    </div>
  );
}

export default Card;

Enter fullscreen mode Exit fullscreen mode

E esses são os estilos que devem ser aplicados para esse card:

.container {
  display: flex;
  flex-direction: column;
  padding: 20px;
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
}

.title {
  font-size: 18px;
  font-weight: 700;
}

.description {
  font-size: 14px;
}

Enter fullscreen mode Exit fullscreen mode

Porém nosso card está aparecendo da seguinte forma:

Alt Text

Ao inspecionar, vemos que em outro lugar do projeto existe um mesmo className description que altera a cor e tamanho da fonte:

Alt Text

A saída agora seria renomear os classNames utilizados no card, porém com os css-modules temos uma maneira melhor de fazer isso. O primeiro passo é alterar o nome do seu arquivo de estilos para o seguinte formato: [name].module.scss.

Depois de fazer isso, deverá alterar seu import dos estilos e a utilização dos classNames para a seguinte forma:

import React from 'react';
import styles from './styles.module.scss';

function Card() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Card title</h1>
      <span className={styles.description}>Card description</span>
    </div>
  );
}

export default Card;
Enter fullscreen mode Exit fullscreen mode

E então nosso componente aparecerá da seguinte forma (correta):

Alt Text

Você deve estar se perguntando como que isso funciona por baixo dos panos. Bom, o css-modules cria um className único para cada local em que é utilizado, e isso é feito da seguinte forma: [filename]\_[classname]\_\_[hash].

Abaixo seguem dois exemplos, um de como é compilado o card sem o css-modules, e outro com:

Sem css-modules

Sem css-modules

Com css-modules

Com css-modules

Conclusão

Vimos que a utilização do css-modules possui muitos pontos positivos e que a sua implementação é muito simples, não precisando de um grande planejamento ou tempo, podendo fazer sua utilização para novas features e com o tempo ir aplicando nas antigas.

Discussion (3)

pic
Editor guide
Collapse
buriti97 profile image
buridev

Muito bom usar css com react mas sabe se isso é possivel com sass tambem ? em um os projetos da empresa a gente tem esse problema de conflito de classes, pra ter o aninhamento de classes como sass e ainda gerar de uma forma randomica no build seria a melhor opção usar css-in-js ?

Collapse
brunopapait profile image
Bruno Papait

Isso é bem bom, mas particularmente eu prefiro usar o styled-components que também da pra isolar cada componente com seus respectivos estilos.

Collapse
robsonneres2009 profile image
Robson Neres

Muito bom esse conteúdo!!