Capítulo 8
Seletores e cascata
6 min de leitura 1.024 palavras 2 gravuras
Este capítulo ensina a pintar este parágrafo de um jeito e aquele de outro. O palco é a Casa da Restinga, cafeteria fictícia em Natal. Este volume tem 23 capítulos. O exemplo está em exemplos/08-seletores-cascata/.
No capítulo 7, um seletor p pegava todos os parágrafos. Agora a classe escolhe um grupo. A cascata decide quem vence quando duas regras pedem a mesma propriedade.
Trabalhe na cópia inicio da etapa. Leia e digite o código; mude uma coisa. Antes de recarregar, anote sua previsão. Depois confira com a referência completa. Se nada mudar, confira o arquivo salvo e o caminho aberto. Blocos adicionais do capítulo podem ser digitados no console; o exemplo completo mostra a aplicação daquela etapa.
O que você vai aprender
- Selecionar pela classe, com o ponto só no CSS.
- Ver a última regra vencer quando a especificidade é igual.
- Comparar seletor de tipo e seletor de classe.
- Combinar duas classes no mesmo seletor.
- Evitar
ide!importantpara estilo.
Classe em vez de pintar todas as tags
Dois h1 na mesma página podem ter papéis diferentes. Um é a marca da casa. Outro é o título de um post. A tag é a mesma. A classe diferencia.
<h1 class="marca">Casa da Restinga</h1>
<h2 class="titulo-post">A torrada das seis</h2>
.marca {
color: maroon;
}
.titulo-post {
color: seagreen;
}
O ponto no CSS marca “isto é uma classe”. No HTML o atributo é class="marca", sem ponto.
Prefira classe para estilo. Seletor de tipo (h1, p, a) vale quando você quer mesmo todos. Esses casos são poucos. Errar para o lado das classes.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Casa da Restinga</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1 class="marca">Casa da Restinga</h1>
<p class="intro">Cafeteria fictícia em Natal.</p>
<p class="aviso">A mesa da janela pega vento.</p>
</body>
</html>
Pare e experimente. Acrescente class="aviso" ao parágrafo de intro. Recarregue. Os dois devem receber o estilo de .aviso. Tire a classe extra.
Quando empatam, a última vence
Duas regras com o mesmo seletor e a mesma propriedade: a que aparece por último no CSS ganha.
.marca {
color: maroon;
}
.marca {
color: seagreen;
}
O h1.marca fica seagreen. Não é mágica. É ordem no arquivo. Cada propriedade se desempata sozinha. Uma regra pode perder na cor e ainda aplicar a borda, se a outra não falar de borda.
.marca {
border: 1px solid black;
color: maroon;
}
.titulo {
color: seagreen;
}
Com class="marca titulo", a cor fica seagreen se .titulo vier depois. A borda permanece: .titulo não a contradiz.
Leia. Copie. Mude uma coisa. Preveja. Recarregue. Confira. Inverta as duas regras .marca. A cor deve trocar.

Especificidade: classe pesa mais que tag
Nem sempre a última vence. O navegador compara especificidade. Classe pesa mais que tipo. Um .titulo vence um h1 mesmo que o h1 venha depois.
.titulo {
color: orange;
}
h1 {
color: seagreen;
}
O h1 class="titulo" fica orange. A classe é mais específica.
Um jeito tosco de pensar: tipo vale 1, classe vale 10, id vale 100. O maior número ganha. O modelo não é perfeito — uma classe ainda ganha de muitos tipos — mas ajuda a ler o conflito.
Por isso este volume pede classes no visual. Se tudo é classe, os números empatam e a ordem no arquivo resolve. Menos guerra.
Erro comum: pintar com p e depois estranhar um .aviso que “não obedece”. Confira quem é mais específico antes de repetir a regra.
Duas classes no mesmo seletor
Sem espaço, .marca.titulo pede um elemento que tenha as duas classes. Com espaço, .marca .titulo pede um .titulo dentro de um .marca. O espaço muda o significado.
.marca.titulo {
color: maroon;
}
.titulo {
color: seagreen;
}
.marca.titulo é mais específico (duas classes). Vence .titulo (uma classe).
Juntar tag e classe, h1.marca, também aumenta a conta. Evite. Se você precisa da tag no seletor para “ganhar”, o HTML provavelmente quer outra classe.
Pare e experimente. Coloque um espaço em .marca.titulo e vire .marca .titulo. Recarregue. O h1 que tem as duas classes no mesmo elemento deve perder esse estilo. Tire o espaço.
id e !important: ferramentas pesadas
Seletor de id usa #. #marca vence classes. Um id ainda vence um empilhamento comprido de classes. Por isso o id neste volume serve para âncora (#conteudo), não para pintar.
!important força uma declaração a ganhar. Quebra a leitura da cascata. Não use neste volume. Se o visual não aplica, o problema é seletor, ordem ou arquivo errado — não falta de !important.
#marca {
color: maroon;
}
.nav {
color: seagreen !important;
}
Mesmo vendo isso em códigos velhos, não copie o hábito. Classe clara e pouca briga resolvem o blog da Restinga.
O CSS está no disco. O navegador calcula a cascata na hora de desenhar a página. file:// e 127.0.0.1 mostram o mesmo cálculo nesta máquina. Publicar não muda a regra da cascata.
Prática no blog da Casa
No styles.css do exemplo, pinte a intro e o aviso de jeitos diferentes. Deixe os posts com uma borda. Não use id para cor.
.intro {
font-size: 1.15rem;
}
.aviso {
color: maroon;
border-left: 4px solid maroon;
padding-left: 1rem;
}
.post {
border: 1px solid #d6cbb8;
padding: 1rem;
margin-bottom: 1rem;
}
Se um post não ganha borda, falta class="post" no article. O seletor certo não inventa a classe no HTML.

O ciclo: ler → copiar → mudar uma coisa → prever → recarregar → conferir. Troque só a cor de .aviso. Os posts devem permanecer.
Quando duas regras brigarem, pergunte: é o mesmo seletor? quem é mais específico? qual vem por último? Só então mude o CSS. Não acrescente !important para “resolver agora”.
O capítulo 9 entra em pseudoclasses. O foco do teclado e o estado do link dependem do que você viu hoje: seletor certo e cascata previsível.
Atividades
- Como o CSS distingue um seletor de tipo de um seletor de classe?
- Duas regras
.avisopedem cores diferentes. Qual vence, se não houver!important? - Por que
.titulovenceh1mesmo oh1vindo depois no arquivo? - No exemplo
08-seletores-cascata, o que acontece se você escreverclass=".aviso"no HTML?
Respostas comentadas
- Tipo usa o nome da tag (
p). Classe usa o ponto e o nome (.aviso). No HTML a classe vai no atributoclass, sem ponto. - A que aparece por último no CSS. A especificidade é igual.
- Classe é mais específica que tipo. A ordem só desempata quando a especificidade empata.
- A classe real passaria a se chamar
.aviso, com ponto no nome. O seletor.avisonão pega esse elemento. O visual do aviso some.
Referências
O arquivo completo
Referência do exemplo 08-seletores-cascata, reproduzida aqui para que você possa conferir sem sair da página.
assets/stylesheets/main.css
*,
*::before,
*::after { box-sizing: border-box; }
html, body, h1, h2, h3, p, ul { margin: 0; padding: 0; }
img { max-width: 100%; height: auto; }
body {
font-family: "Segoe UI", Tahoma, sans-serif;
line-height: 1.5;
color: #1a2a2c;
background: #f7f3ea;
}
a { color: #0d5c63; }
a:focus-visible, button:focus-visible, input:focus-visible {
outline: 3px solid #c45c26;
outline-offset: 3px;
}
.skip { position: absolute; left: -999px; }
.skip:focus { left: 0.5rem; top: 0.5rem; background: #fff; padding: 0.4rem 0.7rem; z-index: 2; }
.wrap { width: min(44rem, calc(100% - 2rem)); margin-inline: auto; }
header { background: #0d5c63; color: #fff; padding: 1rem 0; }
header a { color: #fff; }
.brand { font-weight: 700; text-decoration: none; }
nav ul { list-style: none; display: flex; gap: 1rem; margin-top: 0.5rem; }
nav a[aria-current="page"] { text-decoration: underline; text-underline-offset: 0.2em; }
main { padding: 1.5rem 0 3rem; }
footer { border-top: 1px solid #ddd4c4; padding: 1rem 0; font-size: 0.95rem; }
article { margin: 1.25rem 0; padding-bottom: 1rem; border-bottom: 1px solid #ddd4c4; }
.aviso { color: #c45c26; }
article p { color: #1a2a2c; }