Uma abordagem mais razoável para CSS e Sass
- Terminologia - Regras - Seletores - Propriedades
- CSS - formatação - Comentários - OOCSS e BEM - Seletores ID - JavaScript hooks - Border
- Sass - Sintaxe - Ordenação - Variáveis - Mixins - Extend - Seletores aninhados
- Traduções
Uma “declaração de regra” é o nome dado ao seletor (ou grupo de seletores) acompanhados de um grupo de propriedades. Segue um exemplo:
.listing {
font-size: 18px;
line-height: 1.2;
}
Em uma declaração de regra, "seletores" são os trechos que determinam quais elementos na árvore de DOM serão estilizados pelas propriedades definidas. Seletores podem coincidir com elementos HTML, assim como classes, ID ou qualquer um de seus atributos. Seguem exemplos de seletores:
.my-element-class {
/* ... */
}
[aria-hidden] {
/* ... */
}
Finalmente, propriedades são os elementos selecionados de uma regra de declaração. Propriedades são pares de chave-valor, onde uma regra de declaração pode conter uma ou mais declarações de propriedades. Declarações de propriedades são mostradas a seguir:
/* some selector */ {
background: #f1f1f1;
color: #333;
}
- Use "soft tabs" (2 espaços) para indentação.
- Prefira dashes
(-)
no lugar de camelCase em nomes de classes.- Underscores
(_)
e PascalCase podem ser utilizados caso você use BEM (veja OOCSS e BEM abaixo).
- Underscores
- Não use seletores ID.
- Quando usar múltiplos seletores em uma regra de declaração, ponha cada um em uma própria linha.
- Coloque um espaço antes da abertura de chaves
{
em declaração de regras. - Em propriedades, coloque um espaço depois, mas não antes do caractere
:
(dois-pontos). - Coloque chave de fechamento
}
de uma regra de declaração em uma nova linha. - Coloque linhas em branco entre declarações de regra.
Ruim
.avatar{
border-radius:50%;
border:2px solid white; }
.no, .nope, .not_good {
// ...
}
#lol-no {
// ...
}
Bom
.avatar {
border-radius: 50%;
border: 2px solid white;
}
.one,
.selector,
.per-line {
// ...
}
- Prefira comentários de linha (
//
em Sass) a blocos de comentários. - Prefira comentários em linhas próprias. Evite comentários no final da linha.
- Escreva comentários detalhados para códigos que não são auto-documentados:
- Usos do z-index
- Compatibilidade ou hacks específicos de navegadores
Nós incentivamos algumas combinações de OOCSS e BEM por três razões:
- Ajuda a criar relações claras e estritas entre CSS e HTML
- Nos ajuda a criar componentes reutilizáveis e que podem ser usados em composição
- Permite menor aninhamento e especificidade
- Ajuda na construção de estilos escaláveis
OOCSS, ou “Object Oriented CSS”, (CSS orientado a objetos) é uma abordagem para escrita de CSS que encoraja você a pensar sobre seus estilos como uma coleção de "objetos": trechos repetíveis e reutilizáveis que podem ser usados de forma independente em toda uma página.
- OOCSS wiki de Nicole Sullivan
- Introduction to OOCSS de Smashing Magazine
BEM, ou “Block-Element-Modifier”, é uma convenção de nomes para classes em HTML e CSS. Foi originalmente desenvolvida por Yandex com grandes bases de códigos e escalabilidade em mente, e pode servir como um sólido conjunto de orientações para implementação de OOCSS.
- BEM 101 de CSS Trick
- Introduction to BEM de Harry Roberts
Nós recomendamos um variante do BEM com "blocos" em formato PascalCase, que funciona particularmente bem quando combinado com componentes (ex. React). Underscores e dashes ainda são utilizados para modificadores e filhos.
Exemplo
// ListingCard.jsx
function ListingCard() {
return (
<article class="ListingCard ListingCard--featured">
<h1 class="ListingCard__title">Adorable 2BR in the sunny Mission</h1>
<div class="ListingCard__content">
<p>Vestibulum id ligula porta felis euismod semper.</p>
</div>
</article>
);
}
/* ListingCard.css */
.ListingCard { }
.ListingCard--featured { }
.ListingCard__title { }
.ListingCard__content { }
.ListingCard
é um “bloco” e representa um componente de alto nível.ListingCard__title
é um “elemento” e representa um descendente de.ListingCard
que ajuda a compor o bloco como um todo..ListingCard--featured
é um "modificador" e representa um estado diferente ou variação do bloco.ListingCard
.
Enquanto é possível selecionar elementos por ID em CSS, isto deveria ser considerado um antipadrão. Seletores ID introduzem um nível alto de especificidade para suas declarações de regras e eles não são reutilizáveis.
Para mais detalhes, leia o seguinte artigo do CSS Wizardry sobre como lidar com especificidade.
Evite vincular a mesma classe tanto em seu CSS como no JavaScript. Combinar os dois muitas vezes resulta, no mínimo, em tempo perdido durante refatoração, quando um desenvolvedor deve fazer referência cruzada a cada classe que está alterando, e no pior dos casos, em medo de fazer alterações pelo temor de quebrar alguma funcionalidade.
Recomendamos a criação de classes específicas JavaScript para vinculação, com prefixo .js-
:
<button class="btn btn-primary js-request-to-book">Request to Book</button>
Utilizar 0
ao invés de none
para especificar que um estilo não tem borda.
Ruim
.foo {
border: none;
}
Bom
.foo {
border: 0;
}
- Use sintaxe
.scss
, nunca a original.sass
- Ordene as declarações em CSS regular e
@include
logicamente (veja abaixo)
-
Declaração de propriedades
Listar todas as declarações de propriedades padrão, tudo que não seja
@include
ou um seletor aninhado..btn-green { background: green; font-weight: bold; // ... }
-
Declarações
@include
Agrupar
@include
s no final torna mais fácil a leitura do seletor inteiro..btn-green { background: green; font-weight: bold; @include transition(background 0.5s ease); // ... }
-
Seletores aninhados
Seletores aninhados, se necessários, vão no final, e nada deve vir depois deles. Adicionar espaços em branco entre suas declarações de regras e seletores aninhados, bem como entre seletores aninhados adjacentes. Aplicar as mesmas diretrizes acima para seus seletores aninhados.
.btn { background: green; font-weight: bold; @include transition(background 0.5s ease); .icon { margin-right: 10px; } }
Prefira nomes de variáveis em dash-case (ex. $my-variable
) em vez de camelCase ou snake_case. É aceitável adicionar um "underscore" como prefixo em nomes de variáveis que se destinam a ser usadas somente dentro do arquivo atual (ex. $_my-variable
).
Mixins devem ser usados para aplicar DRY ao seu código, adicionar clareza ou abstrair complexidade -- da mesma forma que usar funções bem nomeadas. Mixins que não aceitam nenhum argumento podem ser úteis para isto, mas note que se você não compactar seu payload (ex. gzip), isto pode contribuir para duplicação de código desnecessário nos estilos resultantes.
@extend
deve ser evitado porque possui comportamento não-intuitivo e potencialmente perigoso, especialmente quando usado em seletores aninhados. Mesmo estender seletores placeholder de nível superior pode causar problemas se a ordem dos seletores mudar mais tarde (ex. se eles estão em outros arquivos e a ordem dos mesmos variar). Usar gzip lida com a maior parte das economias que você teria ganho usando @extend
, e você ainda pode tornar seus estilos menos repetitivos muito bem com mixins.
Não aninhe seletores em mais de três níveis de profundidade!
.page-container {
.content {
.profile {
// STOP!
}
}
}
Quando os seletores se tornam muito longos, você provavelmente está escrevendo CSS que é:
- Fortemente acoplado ao HTML (frágil) —OU—
- Excessivamente específico (poderoso) —OU—
- Não reutilizável
Novamente: nunca aninhe seletores ID!
Se você precisar utilizar um seletor ID (e você realmente deve evitar fazer isto), eles nunca devem estar aninhados. Se você estiver fazendo isto, revise sua marcação ou reflita sobre por que tanta especificidade é necessária. Se você estiver escrevendo HTML e CSS bem formados, você nunca deve precisar usar isso.
Este guia também está disponível em outros idiomas:
- Indonésio: mazipan/css-style-guide
- Chinês (Tradicional): ArvinH/css-style-guide
- Chinês (Simplificado): Zhangjd/css-style-guide
- Francês: mat-u/css-style-guide
- Japonês: nao215/css-style-guide
- Coreano: CodeMakeBros/css-style-guide
- Português (Portugal): SandroMiguel/airbnb-css-style-guide
- Russo: rtplv/airbnb-css-ru
- Espanhol: ismamz/guia-de-estilo-css
- Vietnamita: trungk18/css-style-guide
- Italiano: antoniofull/linee-guida-css
- Alemão: tderflinger/css-styleguide