Fundamentos da Web com HTML e CSS
Combinando Seletores e Pseudo-classes
Aprenda sobre combinando seletores e pseudo-classes
Combinando Seletores e Pseudo-classes
Olá, futuros mestres do estilo! 👋 Nesta aula prática, vamos elevar suas habilidades de CSS a um novo patamar, explorando como combinar seletores e pseudo-classes para criar estilos extremamente específicos e dinâmicos. Você já sabe como selecionar elementos básicos, mas e se você precisar estilizar o primeiro parágrafo dentro de uma div específica ou um item de lista apenas quando o mouse passa sobre ele? É exatamente isso que aprenderemos hoje!
Ao final desta aula, você será capaz de:
- Utilizar combinadores para selecionar elementos com base em seu relacionamento.
- Aplicar pseudo-classes para estilizar elementos em estados específicos ou posições estruturais.
- Combinar diferentes seletores para criar regras CSS poderosas e precisas.
Vamos lá! 🚀
1. Combinadores: Relacionando Elementos 🤝
Combinadores são caracteres especiais que nos permitem selecionar elementos com base em seu relacionamento com outros elementos. Eles são fundamentais para navegar pela estrutura da sua página HTML.
1.1. Seletor Descendente (Espaço )
O seletor descendente seleciona todos os elementos que são descendentes de outro elemento. Um descendente pode ser um filho, neto, bisneto, etc.
- Sintaxe:
elemento_pai elemento_descendente - Exemplo:
div pseleciona todos os parágrafos (<p>) que estão dentro de qualquerdiv.
<!-- index.html -->
<div class="container">
<p>Este é o primeiro parágrafo.</p>
<span>
<p>Este é o segundo parágrafo, dentro de um span.</p>
</span>
</div>
<p>Este parágrafo está fora da div.</p>/* style.css */
div p {
color: blue;
font-weight: bold;
}Neste exemplo, apenas os dois primeiros parágrafos ficarão azuis e em negrito. O último parágrafo não será afetado.
1.2. Seletor de Filho Direto (>)
O seletor de filho direto seleciona apenas os elementos que são filhos diretos de outro elemento.
- Sintaxe:
elemento_pai > elemento_filho - Exemplo:
ul > liseleciona todos os itens de lista (<li>) que são filhos diretos de uma lista não ordenada (<ul>).
<!-- index.html -->
<ul class="menu">
<li>Item 1</li>
<li>Item 2
<ul>
<li>Subitem 2.1</li>
</ul>
</li>
<li>Item 3</li>
</ul>/* style.css */
ul > li {
background-color: lightblue;
border: 1px solid blue;
}Aqui, apenas "Item 1", "Item 2" e "Item 3" terão o fundo azul. "Subitem 2.1" não será estilizado porque é filho de outro ul, não do ul.menu diretamente.
1.3. Seletor de Irmão Adjacente (+)
O seletor de irmão adjacente seleciona um elemento que é imediatamente precedido por outro elemento, e ambos devem ter o mesmo pai.
- Sintaxe:
elemento_anterior + elemento_seguinte - Exemplo:
h2 + pseleciona o primeiro parágrafo (<p>) que vem imediatamente após um cabeçalho<h2>.
<!-- index.html -->
<article>
<h2>Título do Artigo</h2>
<p>Este é o primeiro parágrafo após o h2.</p>
<p>Este é o segundo parágrafo.</p>
<h2>Outro Título</h2>
<p>Este é o parágrafo após o segundo h2.</p>
</article>/* style.css */
h2 + p {
font-style: italic;
color: gray;
}Apenas o primeiro parágrafo após cada h2 ficará em itálico e cinza.
1.4. Seletor de Irmão Geral (~)
O seletor de irmão geral seleciona todos os elementos que são irmãos de um elemento especificado e o seguem no DOM.
- Sintaxe:
elemento_referencia ~ elemento_irmao - Exemplo:
h2 ~ pseleciona todos os parágrafos (<p>) que seguem um cabeçalho<h2>e têm o mesmo pai.
<!-- index.html -->
<article>
<h2>Título do Artigo</h2>
<p>Parágrafo 1.</p>
<div>Outro elemento</div>
<p>Parágrafo 2.</p>
<p>Parágrafo 3.</p>
</article>/* style.css */
h2 ~ p {
text-decoration: underline;
}Neste caso, "Parágrafo 1", "Parágrafo 2" e "Parágrafo 3" serão sublinhados, pois todos eles seguem o h2 e são seus irmãos.
2. Pseudo-classes: Estilizando Estados e Posições 🧐
Pseudo-classes permitem que você selecione elementos com base em um estado, como quando o mouse está sobre eles, ou sua posição dentro da estrutura do documento.
2.1. Pseudo-classes Interativas (UI)
:hover: Seleciona um elemento quando o ponteiro do mouse está sobre ele.:active: Seleciona um elemento enquanto ele está sendo ativado (clicado, pressionado).:focus: Seleciona um elemento que recebeu o foco (ex: um campo de formulário selecionado).
<!-- index.html -->
<button class="btn">Passe o mouse!</button>
<input type="text" placeholder="Digite algo aqui">/* style.css */
.btn:hover {
background-color: #4CAF50; /* Verde */
color: white;
}
.btn:active {
background-color: #3e8e41; /* Verde mais escuro */
transform: translateY(2px);
}
input:focus {
border-color: dodgerblue;
box-shadow: 0 0 5px dodgerblue;
outline: none; /* Remove o outline padrão do navegador */
}2.2. Pseudo-classes Estruturais
:first-child: Seleciona o primeiro elemento de um grupo de irmãos.:last-child: Seleciona o último elemento de um grupo de irmãos.:nth-child(n): Seleciona o enésimo elemento de um grupo de irmãos.npode ser um número,odd(ímpares),even(pares), ou uma fórmula (An+B).:only-child: Seleciona um elemento que é o único filho de seu pai.
<!-- index.html -->
<ul class="lista-frutas">
<li>Maçã</li>
<li>Banana</li>
<li>Laranja</li>
<li>Uva</li>
</ul>
<div class="bloco-unico">
<p>Este é o único parágrafo aqui.</p>
</div>
<div class="bloco-multi">
<p>Parágrafo 1</p>
<p>Parágrafo 2</p>
</div>/* style.css */
.lista-frutas li:first-child {
color: red; /* Maçã */
}
.lista-frutas li:last-child {
color: purple; /* Uva */
}
.lista-frutas li:nth-child(even) { /* Banana, Uva */
background-color: #f0f0f0;
}
.lista-frutas li:nth-child(2n+1) { /* Maçã, Laranja */
font-weight: bold;
}
.bloco-unico p:only-child {
border: 2px solid green;
}
.bloco-multi p:only-child { /* Não será aplicado */
border: 2px solid red;
}2.3. Pseudo-classes de Estado de UI
:checked: Seleciona elementos de formulário (checkbox, radio) que estão marcados.:disabled: Seleciona elementos de formulário que estão desabilitados.:enabled: Seleciona elementos de formulário que estão habilitados.
<!-- index.html -->
<label>
<input type="checkbox" checked> Aceito os termos
</label>
<br>
<label>
<input type="checkbox"> Receber novidades
</label>
<br>
<input type="text" value="Campo desabilitado" disabled>
<br>
<input type="text" value="Campo habilitado">/* style.css */
input[type="checkbox"]:checked + label { /* Note a combinação com o seletor de atributo e irmão adjacente */
font-weight: bold;
color: green;
}
input[type="checkbox"]:checked {
accent-color: green; /* Muda a cor do checkbox */
}
input:disabled {
background-color: #eee;
cursor: not-allowed;
}
input:enabled {
border: 1px solid dodgerblue;
}2.4. Pseudo-classe de Negação (:not())
A pseudo-classe :not() seleciona elementos que não correspondem ao seletor passado como argumento.
- Sintaxe:
:not(seletor) - Exemplo:
p:not(.destaque)seleciona todos os parágrafos que não possuem a classedestaque.
<!-- index.html -->
<p>Parágrafo normal.</p>
<p class="destaque">Parágrafo destacado.</p>
<p>Outro parágrafo normal.</p>/* style.css */
p:not(.destaque) {
color: gray;
}3. O Poder da Combinação! 💥
Agora que revisamos os combinadores e pseudo-classes, vamos ver como eles trabalham juntos para criar seletores super específicos.
3.1. Combinando Combinadores e Pseudo-classes
Você pode encadear quantos combinadores e pseudo-classes forem necessários para atingir seu alvo.
-
Exemplo 1: Estilizando o primeiro parágrafo de uma
divespecífica.div.conteudo p:first-child { font-size: 1.2em; margin-bottom: 1em; }Isso seleciona o primeiro filho que é um parágrafo (
p) dentro de umadivcom a classeconteudo. -
Exemplo 2: Alterando o estilo de um elemento quando o mouse passa sobre seu irmão anterior.
h3:hover + p { background-color: yellow; }Quando você passa o mouse sobre um
h3, o parágrafo imediatamente adjacente a ele terá o fundo amarelo. -
Exemplo 3: Estilizando itens de lista ímpares quando o mouse está sobre eles.
ul li:nth-child(odd):hover { background-color: lightgreen; cursor: pointer; }Apenas os itens de lista ímpares (
li:nth-child(odd)) mudarão de cor quando o mouse passar sobre eles (:hover). -
Exemplo 4: Estilizando labels de checkboxes não marcados.
input[type="checkbox"]:not(:checked) + label { color: #999; font-style: italic; }Seleciona a
labelque é irmã adjacente de uminputdo tipocheckboxque não está marcado.
4. Hora da Prática! 🚀
É hora de colocar a mão na massa! Crie um arquivo index.html e style.css e tente resolver os desafios abaixo.
Setup Inicial
Crie a estrutura básica dos seus arquivos:
<!-- index.html -->
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Combinando Seletores - Prática</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Prática de Seletores e Pseudo-classes</h1>
<nav class="main-nav">
<ul>
<li><a href="#">Início</a></li>
<li><a href="#">Sobre Nós</a></li>
<li><a href="#">Serviços</a></li>
<li><a href="#">Contato</a></li>
<li><a href="#">Blog</a></li>
</ul>
</nav>
<section class="content">
<h2>Seção Principal</h2>
<p>Este é o primeiro parágrafo da seção principal.</p>
<p>Este é o segundo parágrafo. Ele deve ter um estilo diferente se for o último.</p>
<div>
<p>Este parágrafo está dentro de uma div.</p>
<span>Outro texto.</span>
<p>Este é o segundo parágrafo dentro da div.</p>
</div>
<h3>Subseção</h3>
<p>Parágrafo que segue um h3.</p>
<p>Outro parágrafo.</p>
</section>
<form class="my-form">
<h2>Formulário de Contato</h2>
<label for="nome">Nome:</label>
<input type="text" id="nome" name="nome" placeholder="Seu nome">
<br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="Seu email" disabled>
<br>
<label>
<input type="checkbox" id="newsletter"> Quero receber a newsletter
</label>
<br>
<label>
<input type="checkbox" id="termos" checked> Aceito os termos e condições
</label>
<br>
<button type="submit">Enviar</button>
</form>
</body>
</html>/* style.css */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 20px;
background-color: #f4f4f4;
color: #333;
}
h1, h2, h3 {
color: #0056b3;
}
nav.main-nav ul {
list-style: none;
padding: 0;
background-color: #333;
overflow: hidden;
}
nav.main-nav li {
float: left;
}
nav.main-nav a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.my-form label {
display: inline-block;
margin-bottom: 5px;
margin-top: 10px;
}
.my-form input[type="text"],
.my-form input[type="email"] {
width: 250px;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.my-form button {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
.my-form button:hover {
background-color: #0056b3;
}Desafio 1: Navegação Dinâmica 🖱️
Estilize a navegação (.main-nav) para ter os seguintes comportamentos:
- O último item da navegação (
Blog) deve ter um fundo diferente (#007bff). - Quando o mouse passar sobre qualquer link da navegação, o fundo do link deve mudar para um azul mais claro (
#555) e a cor do texto para branco. - O link "Contato" deve ter uma borda inferior de 2px sólida e vermelha (
red) quando o mouse passar sobre ele.
/* Seu código CSS aqui para o Desafio 1 */
/* Dica: Use combinadores e pseudo-classes */💡 Dica para o Desafio 1
- Para o último item, você precisará combinar um seletor de classe com uma pseudo-classe estrutural e um seletor descendente.
- Para o hover, um seletor descendente e a pseudo-classe
:hoversão suficientes. - Para o "Contato", você pode usar um seletor de atributo ou uma pseudo-classe estrutural (se souber que é sempre o 4º item) e combiná-lo com
:hover.
✅ Solução do Desafio 1
/* Desafio 1: Navegação Dinâmica */
nav.main-nav ul li:last-child a {
background-color: #007bff;
}
nav.main-nav a:hover {
background-color: #555;
color: white;
}
/* Assumindo que "Contato" é o 4º item */
nav.main-nav ul li:nth-child(4) a:hover {
border-bottom: 2px solid red;
}
/* Ou, se o href fosse único:
nav.main-nav a[href="#"][title="Contato"]:hover {
border-bottom: 2px solid red;
}
*/Desafio 2: Estilizando o Conteúdo 📝
Vamos aplicar estilos mais específicos à seção .content:
- O primeiro parágrafo (
p) dentro da seção.contentdeve ter a cor do texto#0056b3e ser em negrito. - Qualquer parágrafo (
p) que venha imediatamente após umh2na seção.contentdeve ter um recuo de 20px (padding-left) e uma borda esquerda de 3px sólida e cinza (#ccc). - Qualquer parágrafo (
p) que venha imediatamente após umh3na seção.contentdeve ter a fonte itálica. - O segundo parágrafo dentro da
div(que está dentro da seção.content) deve ter um fundo claro (#e9ecef).
/* Seu código CSS aqui para o Desafio 2 */
/* Dica: Use combinadores e pseudo-classes estruturais */💡 Dica para o Desafio 2
- Para o primeiro parágrafo, combine o seletor de classe da seção com o seletor descendente e a pseudo-classe
:first-child. - Para os parágrafos após
h2eh3, use o seletor de irmão adjacente. - Para o segundo parágrafo dentro da
div, você precisará de um seletor descendente e:nth-child().
✅ Solução do Desafio 2
/* Desafio 2: Estilizando o Conteúdo */
.content p:first-child {
color: #0056b3;
font-weight: bold;
}
.content h2 + p {
padding-left: 20px;
border-left: 3px solid #ccc;
}
.content h3 + p {
font-style: italic;
}
.content div p:nth-child(2) { /* O segundo parágrafo dentro da div */
background-color: #e9ecef;
}Desafio 3: Formulário Inteligente 💡
Torne o formulário (.my-form) mais interativo:
- O
inputde email deve permanecer desabilitado, mas seu fundo deve ser um cinza mais escuro (#ddd) e o texto da label associada a ele (label[for="email"]) deve ser cinza (#6c757d). - Quando o checkbox "Quero receber a newsletter" estiver marcado, a
labelassociada a ele deve ficar com a cor do texto verde (#28a745) e em negrito. - Quando o checkbox "Aceito os termos e condições" estiver desmarcado, a
labelassociada a ele deve ficar com a cor do texto vermelha (#dc3545) e em itálico.
/* Seu código CSS aqui para o Desafio 3 */
/* Dica: Use pseudo-classes de UI e o seletor de irmão adjacente */💡 Dica para o Desafio 3
- Para o input desabilitado, use a pseudo-classe
:disabled. Para a label, você pode usar um seletor de atributo ou o seletor de irmão geral se a label vier depois do input. - Para os checkboxes, combine o seletor de input com as pseudo-classes
:checkede:not(:checked), e então use o seletor de irmão adjacente+para estilizar alabel.
✅ Solução do Desafio 3
/* Desafio 3: Formulário Inteligente */
.my-form input[type="email"]:disabled {
background-color: #ddd;
}
.my-form label[for="email"] {
color: #6c757d;
}
#newsletter:checked + label {
color: #28a745;
font-weight: bold;
}
#termos:not(:checked) + label {
color: #dc3545;
font-style: italic;
}5. Resumo e Próximos Passos 🚀
Parabéns! Você dominou a arte de combinar seletores e pseudo-classes, uma habilidade essencial para qualquer desenvolvedor web.
O que aprendemos hoje:
- Combinadores: Espaço (descendente),
>(filho direto),+(irmão adjacente),~(irmão geral) nos permitem selecionar elementos com base em sua relação no DOM. - Pseudo-classes: Como
:hover,:focus,:first-child,:nth-child(),:checked,:disablede:not()nos permitem estilizar elementos com base em seu estado ou posição. - Combinação: A união dessas ferramentas cria seletores poderosos e precisos, permitindo um controle granular sobre o estilo dos seus elementos HTML.
Com essa base, você pode criar interfaces mais dinâmicas, responsivas e visualmente atraentes.
Próximos Passos:
- Pseudo-elementos: Explore pseudo-elementos como
::before,::after,::first-linee::first-letterpara estilizar partes específicas de um elemento. - Seletores de Atributo: Aprofunde-se nos seletores de atributo (
[attr],[attr="value"],[attr^="value"], etc.) para estilizar elementos com base em seus atributos HTML. - Especificidade CSS: Entenda como o navegador decide qual regra CSS aplicar quando há conflitos, o que é crucial ao trabalhar com seletores complexos.
Continue praticando e experimentando! A melhor forma de aprender CSS é construindo e testando. Até a próxima aula! 👋