Trabalhando com pseudo-classes no CSS

No design de páginas web, o CSS é uma ferramenta essencial para criar uma apresentação visual atraente e funcional. As pseudo-classes, por sua vez, oferecem recursos avançados para aplicar estilos de forma inteligente, com base em ações do usuário ou características específicas dos elementos na página. Elas permitem que o desenvolvedor altere a aparência de um site em tempo real, sem a necessidade de interações externas, como JavaScript, garantindo uma navegação mais fluida e interativa.

Neste artigo vamos entender o que são as pseudo-classes, como elas funcionam e explorar diversas formas de usá-las para melhorar a experiência do usuário e otimizar o design de suas páginas.

O que são pseudo-classes?

Antes de aprendermos a usar as pseudo-classes, é importante entender o que elas são. Elas são palavras-chave no CSS que aplicam estilos a elementos com base em condições específicas, como quando um campo recebe foco, um usuário interage com um botão ou um elemento ocupa determinada posição na página. Diferente dos seletores comuns, que trabalham com elementos fixos no HTML, as pseudo-classes permitem criar estilos dinâmicos que respondem ao comportamento do usuário ou à estrutura do DOM.

Abaixo conseguimos ver a sintaxe básica de uma pseudo-classes. Após o seletor vamos adicionar “:” e informar qual seletor queremos utilizar:

Aqui conseguimos ver um exemplo básico utilizando o “hover”:

:hover

Vamos iniciar falando sobre a pseudo-classe “:hover”, que é uma das mais populares no CSS, especialmente para adicionar interatividade aos elementos. Quando o cursor do mouse passa sobre um elemento, ela é ativada. Imagine que você deseja criar um menu no qual os links mudem de cor ao serem destacados, oferecendo um feedback visual claro.

				
					  <style>
    a {
      color: blue;            
      text-decoration: none;  
    }

    a:hover {
      color: red;             
      text-decoration: underline; 
    }
  </style>
</head>
<body>
  <a href="#">Passe o mouse sobre o link</a>
<script type="text/javascript" id="perfmatters-delayed-styles-js">!function(){const e=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];function t(){document.querySelectorAll("link[data-pmdelayedstyle]").forEach(function(e){e.setAttribute("href",e.getAttribute("data-pmdelayedstyle"))}),e.forEach(function(e){window.removeEventListener(e,t,{passive:!0})})}e.forEach(function(e){window.addEventListener(e,t,{passive:!0})})}();</script><script type="text/javascript" id="perfmatters-delayed-scripts-js">const perfmattersUserInteractions=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];perfmattersUserInteractions.forEach(function(event){window.addEventListener(event,pmTriggerDelayedScripts,{passive:!0})});function pmTriggerDelayedScripts(){pmLoadDelayedScripts();perfmattersUserInteractions.forEach(function(event){window.removeEventListener(event, pmTriggerDelayedScripts,{passive:!0});});}function pmLoadDelayedScripts(){document.querySelectorAll("script[data-pmdelayedscript]").forEach(function(elem){elem.setAttribute("src",elem.getAttribute("data-pmdelayedscript"));});}</script></body>
				
			
Quando o usuário passa o mouse sobre o link, ele muda de azul para vermelho e aparece sublinhado, indicando que é clicável. Esse comportamento melhora a usabilidade e cria uma experiência mais interativa.

:focus

Digamos que você esteja criando um formulário e queira destacar os campos que estão em foco. A pseudo-classe “:focus” ajuda a identificar visualmente qual campo está ativo, tornando o formulário mais acessível e intuitivo.

				
					<style>
    input {
      border: 1px solid gray;
      padding: 5px;
      font-size: 16px;
    }

    input:focus {
      border: 2px solid #4caf50;
      outline: none;
    }
</style>
<body>
  <label for="name">Nome:</label>
  <input type="text" id="name" placeholder="Digite seu nome">
<script type="text/javascript" id="perfmatters-delayed-styles-js">!function(){const e=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];function t(){document.querySelectorAll("link[data-pmdelayedstyle]").forEach(function(e){e.setAttribute("href",e.getAttribute("data-pmdelayedstyle"))}),e.forEach(function(e){window.removeEventListener(e,t,{passive:!0})})}e.forEach(function(e){window.addEventListener(e,t,{passive:!0})})}();</script><script type="text/javascript" id="perfmatters-delayed-scripts-js">const perfmattersUserInteractions=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];perfmattersUserInteractions.forEach(function(event){window.addEventListener(event,pmTriggerDelayedScripts,{passive:!0})});function pmTriggerDelayedScripts(){pmLoadDelayedScripts();perfmattersUserInteractions.forEach(function(event){window.removeEventListener(event, pmTriggerDelayedScripts,{passive:!0});});}function pmLoadDelayedScripts(){document.querySelectorAll("script[data-pmdelayedscript]").forEach(function(elem){elem.setAttribute("src",elem.getAttribute("data-pmdelayedscript"));});}</script></body>

				
			

Quando o usuário clica no campo de texto, a borda muda para verde, destacando o campo ativo.

:nth-child

Dentro da pseudo-classe “:nth-child”, você pode usar os valores odd (ímpar) e even (par) para selecionar respectivamente os elementos de posição ímpar ou par dentro de um container. Essas opções são úteis para aplicar estilos alternados a elementos de listas, tabelas ou qualquer outro grupo de elementos, sem a necessidade de selecionar manualmente cada um.

odd: seleciona os elementos que estão em posições ímpares (1, 3, 5, 7, etc.).

even: seleciona os elementos que estão em posições pares (2, 4, 6, 8, etc.).

Esses valores são frequentemente usados para alternar as cores de fundo de itens de uma lista, criando um efeito visual de “zebra”, onde os itens alternam entre cores claras e escuras.

				
					<style>
    li:nth-child(odd) {
      background-color: #f9f9f9;
    }

    li:nth-child(even) {
      background-color: #e0e0e0;
    }
  </style>
<body>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
<script type="text/javascript" id="perfmatters-delayed-styles-js">!function(){const e=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];function t(){document.querySelectorAll("link[data-pmdelayedstyle]").forEach(function(e){e.setAttribute("href",e.getAttribute("data-pmdelayedstyle"))}),e.forEach(function(e){window.removeEventListener(e,t,{passive:!0})})}e.forEach(function(e){window.addEventListener(e,t,{passive:!0})})}();</script><script type="text/javascript" id="perfmatters-delayed-scripts-js">const perfmattersUserInteractions=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];perfmattersUserInteractions.forEach(function(event){window.addEventListener(event,pmTriggerDelayedScripts,{passive:!0})});function pmTriggerDelayedScripts(){pmLoadDelayedScripts();perfmattersUserInteractions.forEach(function(event){window.removeEventListener(event, pmTriggerDelayedScripts,{passive:!0});});}function pmLoadDelayedScripts(){document.querySelectorAll("script[data-pmdelayedscript]").forEach(function(elem){elem.setAttribute("src",elem.getAttribute("data-pmdelayedscript"));});}</script></body>

				
			
No código acima conseguimos ver que o “li:nth-child(odd):” aplica o estilo ao primeiro, terceiro, quinto, e outros itens em posições ímpares. Já o “li:nth-child(even):” aplica o estilo ao segundo, quarto, sexto, e outros itens em posições pares.

:not

A pseudo-classe “:not” é bastante útil quando você precisa estilizar quase todos os elementos de um determinado tipo, mas deseja excluir um subconjunto específico.

Imagine que você está desenvolvendo um sistema em que botões secundários devem ter um estilo padronizado, enquanto o botão principal precisa de um destaque visual diferente. Você pode usar “:not” para aplicar um estilo aos botões secundários sem interferir no botão principal.

				
					<style>
    button {
      padding: 10px 20px;
      font-size: 16px;
      margin: 5px;
    }

    button:not(.primary) {
      background-color: gray;
      color: white;
    }
</style>
<body>
  <button class="primary">Botão Principal</button>
  <button>Botão Secundário 1</button>
  <button>Botão Secundário 2</button>
<script type="text/javascript" id="perfmatters-delayed-styles-js">!function(){const e=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];function t(){document.querySelectorAll("link[data-pmdelayedstyle]").forEach(function(e){e.setAttribute("href",e.getAttribute("data-pmdelayedstyle"))}),e.forEach(function(e){window.removeEventListener(e,t,{passive:!0})})}e.forEach(function(e){window.addEventListener(e,t,{passive:!0})})}();</script><script type="text/javascript" id="perfmatters-delayed-scripts-js">const perfmattersUserInteractions=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];perfmattersUserInteractions.forEach(function(event){window.addEventListener(event,pmTriggerDelayedScripts,{passive:!0})});function pmTriggerDelayedScripts(){pmLoadDelayedScripts();perfmattersUserInteractions.forEach(function(event){window.removeEventListener(event, pmTriggerDelayedScripts,{passive:!0});});}function pmLoadDelayedScripts(){document.querySelectorAll("script[data-pmdelayedscript]").forEach(function(elem){elem.setAttribute("src",elem.getAttribute("data-pmdelayedscript"));});}</script></body>

				
			
O “‘button:not(.primary)” aplica estilos a todos os botões que não possuem a classe “.primary”.

:checked

A pseudo-classe “‘:checked” é indicada quando você quer destacar visualmente elementos de formulário que foram selecionados. Isso é muito útil em cenários de listas de tarefas, filtros, ou qualquer interface que dependa da interação do usuário com caixas de seleção ou botões de rádio.

Imagine que você está criando uma lista de tarefas onde itens concluídos devem ser riscados para indicar que estão finalizados.

				
					<style>
    input[type="checkbox"] {
      display: none; 
    }

    input[type="checkbox"]:checked + label {
      text-decoration: line-through;
      color: gray;
    }

    label {
      cursor: pointer;
      font-size: 18px;
    }
 </style>
<body>
  <input type="checkbox" id="task1">
  <label for="task1">Tarefa 1</label><br>
  <input type="checkbox" id="task2">
  <label for="task2">Tarefa 2</label><br>
  <input type="checkbox" id="task3">
  <label for="task3">Tarefa 3</label>
<script type="text/javascript" id="perfmatters-delayed-styles-js">!function(){const e=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];function t(){document.querySelectorAll("link[data-pmdelayedstyle]").forEach(function(e){e.setAttribute("href",e.getAttribute("data-pmdelayedstyle"))}),e.forEach(function(e){window.removeEventListener(e,t,{passive:!0})})}e.forEach(function(e){window.addEventListener(e,t,{passive:!0})})}();</script><script type="text/javascript" id="perfmatters-delayed-scripts-js">const perfmattersUserInteractions=["keydown","mousemove","wheel","touchmove","touchstart","touchend"];perfmattersUserInteractions.forEach(function(event){window.addEventListener(event,pmTriggerDelayedScripts,{passive:!0})});function pmTriggerDelayedScripts(){pmLoadDelayedScripts();perfmattersUserInteractions.forEach(function(event){window.removeEventListener(event, pmTriggerDelayedScripts,{passive:!0});});}function pmLoadDelayedScripts(){document.querySelectorAll("script[data-pmdelayedscript]").forEach(function(elem){elem.setAttribute("src",elem.getAttribute("data-pmdelayedscript"));});}</script></body>

				
			

Quando o checkbox é marcado, o rótulo associado ao elemento recebe um estilo de texto riscado e cor cinza.

Conclusão

Agora que você compreendeu como as pseudo-classes funcionam e viu exemplos práticos, experimente aplicá-las em seus projetos. Teste diferentes combinações e explore sua criatividade para criar interfaces mais dinâmicas e interativas. O uso inteligente dessas ferramentas pode transformar a experiência do usuário e elevar a qualidade do seu design. O próximo passo é colocar esse conhecimento em prática e descobrir como ele pode fazer a diferença nos seus trabalhos.