<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arquivos curso css3 completo - Web-Zoneware</title>
	<atom:link href="https://webzoneware.com/tag/curso-css3-completo/feed/" rel="self" type="application/rss+xml" />
	<link>https://webzoneware.com/tag/curso-css3-completo/</link>
	<description>Mais do que apenas uma academia web.</description>
	<lastBuildDate>Thu, 22 Oct 2026 03:55:12 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://webzoneware.com/wp-content/uploads/icon-webzoneware-150x150.png</url>
	<title>Arquivos curso css3 completo - Web-Zoneware</title>
	<link>https://webzoneware.com/tag/curso-css3-completo/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Filtros e Glassmorphism Modernos no CSS &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/filtros-css-backdrop-filter-glassmorphism/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/filtros-css-backdrop-filter-glassmorphism/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:55:12 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[backdrop-filter]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[design system moderno]]></category>
		<category><![CDATA[filter css]]></category>
		<category><![CDATA[filtros css]]></category>
		<category><![CDATA[glassmorphism]]></category>
		<category><![CDATA[vidro fosco]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29471</guid>

					<description><![CDATA[<p>A estética visual dos sistemas operacionais contemporâneos — como o macOS da Apple e o Windows 11 — é fortemente inspirada no mundo físico: materiais translúcidos, placas de acrílico e vidros foscos que revelam suavemente o que está por trás da interface. No passado, para criar um desfoque realista ou transformar uma imagem em preto [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/filtros-css-backdrop-filter-glassmorphism/">Filtros e Glassmorphism Modernos no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  A estética visual dos sistemas operacionais contemporâneos — como o macOS da Apple e o Windows 11 — é fortemente inspirada no mundo físico: materiais translúcidos, placas de acrílico e vidros foscos que revelam suavemente o que está por trás da interface. No passado, para criar um desfoque realista ou transformar uma imagem em preto e branco, os designers precisavam recorrer a softwares como Photoshop ou Figma e exportar arquivos pesados. Hoje, o CSS possui um motor gráfico de pós-processamento completo com as propriedades <strong><code>filter</code></strong> e <strong><code>backdrop-filter</code></strong>, permitindo criar o famoso efeito <strong>Glassmorphism</strong> nativamente no navegador.
</p>
<h2>1. O Motor de Filtros Gráficos: A Propriedade <code>filter</code></h2>
<p>
  A propriedade <code>filter</code> processa a renderização de pixels do <strong>próprio elemento e de todos os seus filhos</strong>. Ela aceita uma série de funções visuais prontas:
</p>
<div class="wzw-table-responsive">
<table class="wzw-table">
<thead>
<tr>
<th>Função</th>
<th>Valores de Exemplo</th>
<th>Efeito Visual na Interface</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>blur()</code></strong></td>
<td><code>blur(8px)</code></td>
<td>Aplica um desfoque gaussiano suave sobre o elemento.</td>
</tr>
<tr>
<td><strong><code>brightness()</code></strong></td>
<td><code>brightness(1.3)</code> (30% mais claro)</td>
<td>Ajusta o ganho de luz (excelente para acender cards no <code>:hover</code>).</td>
</tr>
<tr>
<td><strong><code>contrast()</code></strong></td>
<td><code>contrast(150%)</code></td>
<td>Aumenta ou reduz a separação entre tons claros e escuros.</td>
</tr>
<tr>
<td><strong><code>grayscale()</code></strong></td>
<td><code>grayscale(100%)</code></td>
<td>Converte a imagem inteiramente para tons de cinza (preto e branco).</td>
</tr>
<tr>
<td><strong><code>drop-shadow()</code></strong></td>
<td><code>drop-shadow(0 4px 12px rgba(0,0,0,0.5))</code></td>
<td><strong>A Sombra com Canal Alfa:</strong> Projeta sombra ao longo do contorno real de PNGs e SVGs!</td>
</tr>
</tbody>
</table>
</div>
<h3>A Diferença Crucial: <code>box-shadow</code> vs. <code>filter: drop-shadow()</code></h3>
<div class="wzw-callout wzw-callout-info">
<p><strong>Dica Sênior de SVG e PNG:</strong> A propriedade <code>box-shadow</code> projeta uma sombra quadrada em torno da caixa física do elemento, mesmo que a imagem seja um círculo ou logotipo transparente. Já o <strong><code>filter: drop-shadow()</code></strong> analisa o canal de transparência (Alpha Channel) da imagem e contorna os traços reais do ícone ou foto recortada!</p>
</div>
<h2>2. <code>filter</code> vs. <code>backdrop-filter</code>: A Fronteira do Vidro</h2>
<p>
  A diferença entre essas duas propriedades é o ponto onde muitos desenvolvedores se perdem:
</p>
<ul>
<li><strong><code>filter</code>:</strong> Borra o próprio elemento e seu texto. Se você aplicar <code>filter: blur(10px)</code> em um card, todo o texto e botões dentro dele ficarão embaçados e impossíveis de ler!</li>
<li><strong><code>backdrop-filter</code>:</strong> Borra <strong>exclusivamente a área gráfica localizada ATRÁS do elemento</strong>! O texto, os botões e a borda da caixa permanecem com 100% de nitidez cristalina.</li>
</ul>
<h2>3. A Receita dos 4 Ingredientes do Glassmorphism Perfeito</h2>
<p>
  Para criar aquele visual futurista de placa de vidro translúcida sobreposta a elementos da página, você precisa combinar exatamente estes 4 passos:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-60061" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">17 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-60061', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-60061', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.card-glassmorphism {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* 1. Fundo Semitransparente (Nunca use cor 100% sólida!) */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background</span>: rgba(255, 255, 255, 0.08);</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* 2. O Desfoque Gaussiano de Fundo (A magia do vidro fosco) */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">backdrop-filter</span>: blur(<span class="wzw-tk-num">16px</span>);</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">-webkit-backdrop-filter</span>: blur(<span class="wzw-tk-num">16px</span>); /* Fallback para Safari antigo */</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* 3. Borda Translúcida (Simula o corte e bisel da quina do vidro) */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border</span>: <span class="wzw-tk-num">1px</span> solid rgba(255, 255, 255, 0.18);</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* 4. Sombra de Difusão Atmosférica Profunda */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">box-shadow</span>: 0 <span class="wzw-tk-num">8px</span> <span class="wzw-tk-num">32px</span> 0 rgba(0, 0, 0, 0.37);</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-radius</span>: <span class="wzw-tk-num">16px</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">padding</span>: <span class="wzw-tk-num">24px</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.card-glassmorphism {
  /* 1. Fundo Semitransparente (Nunca use cor 100% sólida!) */
  background: rgba(255, 255, 255, 0.08);

  /* 2. O Desfoque Gaussiano de Fundo (A magia do vidro fosco) */
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px); /* Fallback para Safari antigo */

  /* 3. Borda Translúcida (Simula o corte e bisel da quina do vidro) */
  border: 1px solid rgba(255, 255, 255, 0.18);

  /* 4. Sombra de Difusão Atmosférica Profunda */
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);

  border-radius: 16px;
  padding: 24px;
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. Acessibilidade e Contraste Legível (WCAG 2.2)</h2>
<div class="wzw-callout wzw-callout-warning">
<p><strong>O Perigo do Vidro Ilegível:</strong> O maior pecado do Glassmorphism é colocar um fundo translúcido quase invisível sobre um fundo cheio de detalhes coloridos, tornando o texto branco impossível de ser lido por pessoas com baixa acuidade visual. Para estar em conformidade com o Critério 1.4.3 da WCAG (Contraste Mínimo de 4.5:1):</p>
<ul>
<li>Mantenha a opacidade da cor de fundo (RGBA) entre <strong>15% e 25%</strong>.</li>
<li>Use sombras sutis no texto: <code>text-shadow: 0 2px 4px rgba(0,0,0,0.5);</code> para garantir contraste mesmo se o fundo de trás mudar de cor.</li>
</ul>
</div>
<h2>5. Suporte Defensivo com <code>@supports</code></h2>
<p>
  Dispositivos antigos ou navegadores operando em modo de economia de energia podem desativar o <code>backdrop-filter</code>. Garantimos a legibilidade com a regra-arroba <code>@supports</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-73023" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">13 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-73023', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-73023', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Fallback padrão para navegadores sem suporte a blur */</span></span>
<span class="wzw-code-line">.card-glass {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background</span>: <span class="wzw-tk-num">#1e293b</span>; /* Fundo sólido seguro */</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* Se o navegador suportar backdrop-filter, ativa o vidro fosco */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">@supports</span> (backdrop-filter: blur(<span class="wzw-tk-num">10px</span>)) or (-webkit-backdrop-filter: blur(<span class="wzw-tk-num">10px</span>)) {</span>
<span class="wzw-code-line">  .card-glass {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">background</span>: rgba(30, 41, 59, 0.7);</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">backdrop-filter</span>: blur(<span class="wzw-tk-num">14px</span>);</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">-webkit-backdrop-filter</span>: blur(<span class="wzw-tk-num">14px</span>);</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Fallback padrão para navegadores sem suporte a blur */
.card-glass {
  background: #1e293b; /* Fundo sólido seguro */
}

/* Se o navegador suportar backdrop-filter, ativa o vidro fosco */
@supports (backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px)) {
  .card-glass {
    background: rgba(30, 41, 59, 0.7);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Laboratório Prático: Cartão Glassmorphic sobre Esferas Animadas</h2>
<p>
  No código interativo abaixo, criamos um cartão translúcido com <code>backdrop-filter: blur(16px)</code> flutuando sobre esferas coloridas de gradiente, acompanhado de logotipos tratados com <code>filter: grayscale</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-63154" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">117 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-63154', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-63154', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Glassmorphism e Filtros CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #030712;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      min-height: 100vh;</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      flex-direction: column;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      justify-content: center;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">      position: relative;</span>
<span class="wzw-code-line">      overflow: hidden;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* ESFERAS COLORIDAS NO FUNDO PARA TESTAR O DESFOQUE */</span></span>
<span class="wzw-code-line">    .esfera-fundo-1 {</span>
<span class="wzw-code-line">      position: absolute;</span>
<span class="wzw-code-line">      top: 15%;</span>
<span class="wzw-code-line">      left: 20%;</span>
<span class="wzw-code-line">      width: 260px;</span>
<span class="wzw-code-line">      height: 260px;</span>
<span class="wzw-code-line">      border-radius: 50%;</span>
<span class="wzw-code-line">      background: linear-gradient(135deg, #3b82f6, #8b5cf6);</span>
<span class="wzw-code-line">      filter: blur(40px);</span>
<span class="wzw-code-line">      z-index: 1;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .esfera-fundo-2 {</span>
<span class="wzw-code-line">      position: absolute;</span>
<span class="wzw-code-line">      bottom: 20%;</span>
<span class="wzw-code-line">      right: 25%;</span>
<span class="wzw-code-line">      width: 220px;</span>
<span class="wzw-code-line">      height: 220px;</span>
<span class="wzw-code-line">      border-radius: 50%;</span>
<span class="wzw-code-line">      background: linear-gradient(135deg, #10b981, #06b6d4);</span>
<span class="wzw-code-line">      filter: blur(35px);</span>
<span class="wzw-code-line">      z-index: 1;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* O CARTÃO GLASSMORPHISM AUTÊNTICO */</span></span>
<span class="wzw-code-line">    .card-vidro {</span>
<span class="wzw-code-line">      position: relative;</span>
<span class="wzw-code-line">      z-index: 2; /* Fica acima das esferas */</span>
<span class="wzw-code-line">      max-width: 440px;</span>
<span class="wzw-code-line">      background: rgba(255, 255, 255, 0.05); /* 1. Fundo semitransparente */</span>
<span class="wzw-code-line">      backdrop-filter: blur(16px);            /* 2. Desfoque atrás do vidro */</span>
<span class="wzw-code-line">      -webkit-backdrop-filter: blur(16px);</span>
<span class="wzw-code-line">      border: 1px solid rgba(255, 255, 255, 0.15); /* 3. Borda translúcida */</span>
<span class="wzw-code-line">      box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);   /* 4. Sombra profunda */</span>
<span class="wzw-code-line">      border-radius: 20px;</span>
<span class="wzw-code-line">      padding: 32px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .card-vidro h3 {</span>
<span class="wzw-code-line">      margin: 0 0 12px 0;</span>
<span class="wzw-code-line">      color: #fff;</span>
<span class="wzw-code-line">      font-size: 1.4rem;</span>
<span class="wzw-code-line">      text-shadow: 0 2px 8px rgba(0,0,0,0.5);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .card-vidro p {</span>
<span class="wzw-code-line">      color: #cbd5e1;</span>
<span class="wzw-code-line">      font-size: 0.95rem;</span>
<span class="wzw-code-line">      line-height: 1.6;</span>
<span class="wzw-code-line">      margin: 0 0 24px 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* BARRA DE PARCEIROS COM FILTER: GRAYSCALE */</span></span>
<span class="wzw-code-line">    .parceiros-box {</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      gap: 16px;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      border-top: 1px solid rgba(255,255,255,0.1);</span>
<span class="wzw-code-line">      padding-top: 16px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .logo-parceiro {</span>
<span class="wzw-code-line">      font-size: 0.85rem;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">      color: #38bdf8;</span>
<span class="wzw-code-line">      filter: grayscale(100%) opacity(0.6);</span>
<span class="wzw-code-line">      transition: filter 0.3s ease;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .logo-parceiro:hover {</span>
<span class="wzw-code-line">      filter: grayscale(0%) opacity(1); /* Ganha cor total no hover! */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">&lt;!-- Elementos gráficos luminosos que serão desfocados pelo vidro --&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;esfera-fundo-1&quot;</span><span class="wzw-tk-tag">&gt;</span><span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;esfera-fundo-2&quot;</span><span class="wzw-tk-tag">&gt;</span><span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">&lt;!-- O Cartão com Backdrop Filter --&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-vidro&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;h3&gt;</span>⚡ Economaster Glass UI<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;p&gt;</span></span>
<span class="wzw-code-line">      Observe a textura translúcida de vidro fosco: as esferas coloridas de fundo são desfocadas pelo <span class="wzw-tk-tag">&lt;code&gt;</span>backdrop-filter: blur(16px)<span class="wzw-tk-tag">&lt;/code&gt;</span>, enquanto esta tipografia permanece perfeitamente legível e nítida.</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;parceiros-box&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;font-size:0.75rem; color:#64748b;&quot;</span><span class="wzw-tk-tag">&gt;</span>Parceiros (Passe o mouse):<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;logo-parceiro&quot;</span><span class="wzw-tk-tag">&gt;</span>Chrome<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;logo-parceiro&quot;</span><span class="wzw-tk-tag">&gt;</span>Firefox<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;logo-parceiro&quot;</span><span class="wzw-tk-tag">&gt;</span>WebKit<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Glassmorphism e Filtros CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #030712;
      color: #f8fafc;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin: 0;
      position: relative;
      overflow: hidden;
    }

    /* ESFERAS COLORIDAS NO FUNDO PARA TESTAR O DESFOQUE */
    .esfera-fundo-1 {
      position: absolute;
      top: 15%;
      left: 20%;
      width: 260px;
      height: 260px;
      border-radius: 50%;
      background: linear-gradient(135deg, #3b82f6, #8b5cf6);
      filter: blur(40px);
      z-index: 1;
    }

    .esfera-fundo-2 {
      position: absolute;
      bottom: 20%;
      right: 25%;
      width: 220px;
      height: 220px;
      border-radius: 50%;
      background: linear-gradient(135deg, #10b981, #06b6d4);
      filter: blur(35px);
      z-index: 1;
    }

    /* O CARTÃO GLASSMORPHISM AUTÊNTICO */
    .card-vidro {
      position: relative;
      z-index: 2; /* Fica acima das esferas */
      max-width: 440px;
      background: rgba(255, 255, 255, 0.05); /* 1. Fundo semitransparente */
      backdrop-filter: blur(16px);            /* 2. Desfoque atrás do vidro */
      -webkit-backdrop-filter: blur(16px);
      border: 1px solid rgba(255, 255, 255, 0.15); /* 3. Borda translúcida */
      box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);   /* 4. Sombra profunda */
      border-radius: 20px;
      padding: 32px;
    }

    .card-vidro h3 {
      margin: 0 0 12px 0;
      color: #fff;
      font-size: 1.4rem;
      text-shadow: 0 2px 8px rgba(0,0,0,0.5);
    }

    .card-vidro p {
      color: #cbd5e1;
      font-size: 0.95rem;
      line-height: 1.6;
      margin: 0 0 24px 0;
    }

    /* BARRA DE PARCEIROS COM FILTER: GRAYSCALE */
    .parceiros-box {
      display: flex;
      gap: 16px;
      align-items: center;
      border-top: 1px solid rgba(255,255,255,0.1);
      padding-top: 16px;
    }

    .logo-parceiro {
      font-size: 0.85rem;
      font-weight: 700;
      color: #38bdf8;
      filter: grayscale(100%) opacity(0.6);
      transition: filter 0.3s ease;
      cursor: pointer;
    }

    .logo-parceiro:hover {
      filter: grayscale(0%) opacity(1); /* Ganha cor total no hover! */
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;!-- Elementos gráficos luminosos que serão desfocados pelo vidro --&gt;
  &lt;div class=&quot;esfera-fundo-1&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;esfera-fundo-2&quot;&gt;&lt;/div&gt;

  &lt;!-- O Cartão com Backdrop Filter --&gt;
  &lt;div class=&quot;card-vidro&quot;&gt;
    &lt;h3&gt;⚡ Economaster Glass UI&lt;/h3&gt;
    &lt;p&gt;
      Observe a textura translúcida de vidro fosco: as esferas coloridas de fundo são desfocadas pelo &lt;code&gt;backdrop-filter: blur(16px)&lt;/code&gt;, enquanto esta tipografia permanece perfeitamente legível e nítida.
    &lt;/p&gt;

    &lt;div class=&quot;parceiros-box&quot;&gt;
      &lt;span style=&quot;font-size:0.75rem; color:#64748b;&quot;&gt;Parceiros (Passe o mouse):&lt;/span&gt;
      &lt;span class=&quot;logo-parceiro&quot;&gt;Chrome&lt;/span&gt;
      &lt;span class=&quot;logo-parceiro&quot;&gt;Firefox&lt;/span&gt;
      &lt;span class=&quot;logo-parceiro&quot;&gt;WebKit&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste passar o mouse sobre os parceiros para ver o <code>filter: grayscale</code> se transformar, e altere o valor do desfoque no <code>backdrop-filter</code> para conferir a difusão da luz em tempo real:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>7. Resumo e Próximos Passos</h2>
<ul>
<li><code>filter</code> aplica pós-processamento de imagem no elemento e em todos os seus filhos.</li>
<li><code>filter: drop-shadow()</code> projeta sombras respeitando a transparência real de ícones SVG e fotos PNG.</li>
<li><code>backdrop-filter</code> aplica desfoque exclusivamente à área que está <strong>atrás</strong> da caixa, preservando a nitidez do texto.</li>
<li>O Glassmorphism autêntico exige 4 ingredientes: fundo RGBA semitransparente, <code>backdrop-filter: blur()</code>, borda translúcida fina e sombras multicamadas.</li>
<li>Sempre certifique-se de que o contraste das cores atenda ao piso de 4.5:1 da WCAG para evitar textos ilegíveis em vidros transparentes.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> O CSS moderno evoluiu para além do que muitos imaginavam ser possível. E se você pudesse selecionar um elemento pai com base nos filhos que ele possui (o Santo Graal do seletor de pai <code>:has()</code>) ou criar componentes responsivos com base no tamanho do seu próprio contêiner em vez da janela com <code>@container</code>? Na <strong>Lição 47</strong>, desvendaremos os <strong>Seletores Modernos (:is, :where, :has &#038; @container queries)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/filtros-css-backdrop-filter-glassmorphism/">Filtros e Glassmorphism Modernos no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/filtros-css-backdrop-filter-glassmorphism/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CSS Variables e Dark Mode Dinâmico no CSS &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/css-variables-custom-properties-dark-mode/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/css-variables-custom-properties-dark-mode/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:47:07 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[css variables]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[custom properties]]></category>
		<category><![CDATA[dark mode css]]></category>
		<category><![CDATA[root css]]></category>
		<category><![CDATA[theming dinamico]]></category>
		<category><![CDATA[tokens de design]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29469</guid>

					<description><![CDATA[<p>Durante muitos anos, o gerenciamento de cores e medidas no CSS foi caótico. Se a sua empresa decidisse alterar o azul corporativo da marca, você era forçado a fazer um &#8220;localizar e substituir&#8221; em milhares de linhas de código, com o risco constante de esquecer elementos. As CSS Custom Properties, universalmente chamadas de CSS Variables, [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/css-variables-custom-properties-dark-mode/">CSS Variables e Dark Mode Dinâmico no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Durante muitos anos, o gerenciamento de cores e medidas no CSS foi caótico. Se a sua empresa decidisse alterar o azul corporativo da marca, você era forçado a fazer um &#8220;localizar e substituir&#8221; em milhares de linhas de código, com o risco constante de esquecer elementos. As <strong>CSS Custom Properties</strong>, universalmente chamadas de <strong>CSS Variables</strong>, representaram o maior salto de engenharia de software da história do CSS. Ao contrário das variáveis antigas de pré-processadores como o Sass, as variáveis CSS vivem no DOM em tempo de execução, herdam pela cascata, reagem a media queries e podem ser manipuladas instantaneamente pelo JavaScript para alternar entre <strong>Modo Claro e Modo Escuro</strong> com zero recarregamento de página.
</p>
<h2>1. A Sintaxe: Declarando e Consumindo Variáveis</h2>
<p>
  A declaração de uma variável CSS sempre inicia com dois traços (<code>--</code>), e o seu consumo é feito através da função <code>var()</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-23050" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">13 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-23050', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-23050', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* 1. DECLARAÇÃO GLOBAL NO :root */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">:root</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--cor-primaria: #38bdf8;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--espacamento-padrao: 16px;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--raio-borda: 10px;</span></span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 2. CONSUMO EM QUALQUER SELETOR */</span></span>
<span class="wzw-code-line">.cartao {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border</span>: <span class="wzw-tk-num">1px</span> solid var(--cor-primaria);</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">padding</span>: var(--espacamento-padrao);</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-radius</span>: var(--raio-borda);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* 1. DECLARAÇÃO GLOBAL NO :root */
:root {
  --cor-primaria: #38bdf8;
  --espacamento-padrao: 16px;
  --raio-borda: 10px;
}

/* 2. CONSUMO EM QUALQUER SELETOR */
.cartao {
  border: 1px solid var(--cor-primaria);
  padding: var(--espacamento-padrao);
  border-radius: var(--raio-borda);
}</textarea>
        </div>
    </div>
    
</div>
<h3>Valores de Reserva (Fallbacks)</h3>
<p>
  A função <code>var()</code> aceita um segundo parâmetro opcional como valor de segurança (fallback). Se a variável não estiver definida no escopo, o navegador adota o fallback automaticamente:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-35396" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">9 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-35396', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-35396', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Se --cor-destaque não existir, usa #2563eb */</span></span>
<span class="wzw-code-line">.btn {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: var(--cor-destaque, <span class="wzw-tk-num">#2563eb</span>);</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* Fallback encadeado em cascata */</span></span>
<span class="wzw-code-line">.titulo {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: var(--cor-customizada, var(--cor-primaria, <span class="wzw-tk-num">#0f172a</span>));</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Se --cor-destaque não existir, usa #2563eb */
.btn {
  background-color: var(--cor-destaque, #2563eb);
}

/* Fallback encadeado em cascata */
.titulo {
  color: var(--cor-customizada, var(--cor-primaria, #0f172a));
}</textarea>
        </div>
    </div>
    
</div>
<h2>2. Escopo Global vs. Escopo Local (A Cascata Viva)</h2>
<p>
  O maior diferencial das CSS Variables sobre o Sass é que elas <strong>respeitam o escopo da árvore do DOM</strong>:
</p>
<h3>1. Escopo Global (<code>:root</code>)</h3>
<p>
  O pseudo-elemento <code>:root</code> representa a raiz do documento (o elemento <code>&lt;html&gt;</code>), mas possui uma especificidade maior. Qualquer variável declarada no <code>:root</code> é herdada por absolutamente todos os elementos da página.
</p>
<h3>2. Escopo Local (Component-Level Overriding)</h3>
<p>
  Você pode redefinir o valor de uma variável dentro de um contêiner específico. Apenas aquele contêiner e seus filhos passarão a enxergar o novo valor:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-10740" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">16 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-10740', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-10740', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-kw">:root</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--btn-bg: #2563eb; /* Azul padrão global */</span></span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* Um banner de perigo reescreve a variável localmente */</span></span>
<span class="wzw-code-line">.banner-alerta {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--btn-bg: #ef4444; /* Vermelho apenas dentro do banner! */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background</span>: <span class="wzw-tk-num">#450a0a</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">padding</span>: <span class="wzw-tk-num">20px</span>;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* O botão consome --btn-bg: se estiver no site é azul, se estiver no banner é vermelho! */</span></span>
<span class="wzw-code-line">.btn-acao {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: var(--btn-bg);</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#fff</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>:root {
  --btn-bg: #2563eb; /* Azul padrão global */
}

/* Um banner de perigo reescreve a variável localmente */
.banner-alerta {
  --btn-bg: #ef4444; /* Vermelho apenas dentro do banner! */
  background: #450a0a;
  padding: 20px;
}

/* O botão consome --btn-bg: se estiver no site é azul, se estiver no banner é vermelho! */
.btn-acao {
  background-color: var(--btn-bg);
  color: #fff;
}</textarea>
        </div>
    </div>
    
</div>
<h2>3. A Regra de Ouro dos Tokens Semânticos</h2>
<div class="wzw-callout wzw-callout-warning">
<p><strong>Anti-padrão Fatal:</strong> Nunca nomeie suas variáveis com nomes de cores físicas (como <code>--azul</code>, <code>--verde</code> ou <code>--cinza-escuro</code>). Quando você criar o Modo Escuro, o seu &#8220;azul&#8221; ou &#8220;branco&#8221; precisará virar cinza escuro ou preto, tornando seu código confuso e ilegível!</p>
</div>
<p>
  Use sempre <strong>Design Tokens Semânticos</strong> baseados na <strong>função visual</strong> do elemento:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-22167" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">10 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-22167', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-22167', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* SISTEMA PROFISSIONAL DE DESIGN TOKENS */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">:root</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-pagina:          #ffffff;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-superficie:      #f8fafc;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-card:            #ffffff;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--texto-primario:     #0f172a;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--texto-secundario:   #64748b;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--borda-suave:        #e2e8f0;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--cor-marca:          #2563eb;</span></span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* SISTEMA PROFISSIONAL DE DESIGN TOKENS */
:root {
  --bg-pagina:          #ffffff;
  --bg-superficie:      #f8fafc;
  --bg-card:            #ffffff;
  --texto-primario:     #0f172a;
  --texto-secundario:   #64748b;
  --borda-suave:        #e2e8f0;
  --cor-marca:          #2563eb;
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. Arquitetura Definitiva de Dark Mode</h2>
<p>
  Para criar um sistema de tema escuro de classe mundial, combinamos a detecção automática do sistema operacional com a capacidade de o usuário forçar o tema manualmente através de um atributo <code>data-theme</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-66137" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">37 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-66137', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-66137', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* 1. TEMA CLARO PADRÃO */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">:root</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-pagina:        #f8fafc;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-card:          #ffffff;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--texto-corpo:      #0f172a;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--borda:            #cbd5e1;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--destaque:         #2563eb;</span></span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 2. MODO ESCURO AUTOMÁTICO (PREFERÊNCIA DO SISTEMA OPERACIONAL) */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">@media</span> (prefers-color-scheme: dark) {</span>
<span class="wzw-code-line">  <span class="wzw-tk-kw">:root</span> {</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">--bg-pagina:      #0b0f19;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">--bg-card:        #1e293b;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">--texto-corpo:    #f8fafc;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">--borda:          #334155;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">--destaque:       #38bdf8;</span></span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 3. MODO ESCURO FORÇADO VIA JAVASCRIPT (DATA-THEME=&quot;DARK&quot;) */</span></span>
<span class="wzw-code-line">[data-theme=<span class="wzw-tk-str">&quot;dark&quot;</span>] {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-pagina:        #0b0f19;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-card:          #1e293b;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--texto-corpo:      #f8fafc;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--borda:          #334155;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--destaque:         #38bdf8;</span></span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 4. MODO CLARO FORÇADO VIA JAVASCRIPT (DATA-THEME=&quot;LIGHT&quot;) */</span></span>
<span class="wzw-code-line">[data-theme=<span class="wzw-tk-str">&quot;light&quot;</span>] {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-pagina:        #f8fafc;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--bg-card:          #ffffff;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--texto-corpo:      #0f172a;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--borda:            #cbd5e1;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">--destaque:         #2563eb;</span></span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* 1. TEMA CLARO PADRÃO */
:root {
  --bg-pagina:        #f8fafc;
  --bg-card:          #ffffff;
  --texto-corpo:      #0f172a;
  --borda:            #cbd5e1;
  --destaque:         #2563eb;
}

/* 2. MODO ESCURO AUTOMÁTICO (PREFERÊNCIA DO SISTEMA OPERACIONAL) */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-pagina:      #0b0f19;
    --bg-card:        #1e293b;
    --texto-corpo:    #f8fafc;
    --borda:          #334155;
    --destaque:       #38bdf8;
  }
}

/* 3. MODO ESCURO FORÇADO VIA JAVASCRIPT (DATA-THEME=&quot;DARK&quot;) */
[data-theme=&quot;dark&quot;] {
  --bg-pagina:        #0b0f19;
  --bg-card:          #1e293b;
  --texto-corpo:      #f8fafc;
  --borda:          #334155;
  --destaque:         #38bdf8;
}

/* 4. MODO CLARO FORÇADO VIA JAVASCRIPT (DATA-THEME=&quot;LIGHT&quot;) */
[data-theme=&quot;light&quot;] {
  --bg-pagina:        #f8fafc;
  --bg-card:          #ffffff;
  --texto-corpo:      #0f172a;
  --borda:            #cbd5e1;
  --destaque:         #2563eb;
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. Reatividade em Tempo Real com JavaScript</h2>
<p>
  Como as CSS Variables vivem no DOM computado, você pode manipulá-las diretamente pelo JavaScript sem precisar recalcular regras de classe:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-92066" data-lang="javascript">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">JavaScript</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-92066', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-92066', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">// Altera uma variável global instantaneamente:</span></span>
<span class="wzw-code-line">document.documentElement.style.<span class="wzw-tk-fn">setProperty</span>(<span class="wzw-tk-str">&#039;--destaque&#039;</span>, <span class="wzw-tk-str">&#039;#10b981&#039;</span>);</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">// Lê o valor computado de uma variável:</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">const</span> corAtual = <span class="wzw-tk-fn">getComputedStyle</span>(document.documentElement).<span class="wzw-tk-fn">getPropertyValue</span>(<span class="wzw-tk-str">&#039;--destaque&#039;</span>);</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>// Altera uma variável global instantaneamente:
document.documentElement.style.setProperty(&#039;--destaque&#039;, &#039;#10b981&#039;);

// Lê o valor computado de uma variável:
const corAtual = getComputedStyle(document.documentElement).getPropertyValue(&#039;--destaque&#039;);</textarea>
        </div>
    </div>
    
</div>
<h2>6. Laboratório Prático: Switcher de Dark Mode Completo</h2>
<p>
  No código interativo abaixo, construímos um componente de dashboard que consome tokens semânticos e alterna dinamicamente entre Tema Claro e Tema Escuro ao clique de um botão:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-74622" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">106 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-74622', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-74622', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span> <span class="wzw-tk-attr">data-theme</span>=<span class="wzw-tk-str">&quot;dark&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de CSS Variables e Dark Mode<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* TOKENS SEMÂNTICOS NO ESCOPO RAIZ */</span></span>
<span class="wzw-code-line">    :root, [data-theme=&quot;dark&quot;] {</span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--bg: #0b0f19;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--card-bg: #1e293b;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--texto: #f8fafc;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--texto-mutado: #94a3b8;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--borda: #334155;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--primaria: #38bdf8;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--btn-texto: #0b0f19;</span></span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    [data-theme=&quot;light&quot;] {</span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--bg: #f1f5f9;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--card-bg: #ffffff;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--texto: #0f172a;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--texto-mutado: #64748b;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--borda: #cbd5e1;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--primaria: #2563eb;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">--btn-texto: #ffffff;</span></span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      background-color: var(--bg);</span>
<span class="wzw-code-line">      color: var(--texto);</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">      transition: background-color 0.3s ease, color 0.3s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .painel-container {</span>
<span class="wzw-code-line">      max-width: 480px;</span>
<span class="wzw-code-line">      background-color: var(--card-bg);</span>
<span class="wzw-code-line">      border: 1px solid var(--borda);</span>
<span class="wzw-code-line">      border-radius: 14px;</span>
<span class="wzw-code-line">      padding: 24px;</span>
<span class="wzw-code-line">      box-shadow: 0 8px 24px rgba(0,0,0,0.15);</span>
<span class="wzw-code-line">      transition: background-color 0.3s ease, border-color 0.3s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .cabecalho-card {</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      justify-content: space-between;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      margin-bottom: 16px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    h3 { margin: 0; color: var(--primaria); font-size: 1.2rem; }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    p {</span>
<span class="wzw-code-line">      color: var(--texto-mutado);</span>
<span class="wzw-code-line">      font-size: 0.9rem;</span>
<span class="wzw-code-line">      line-height: 1.6;</span>
<span class="wzw-code-line">      margin: 0 0 20px 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* Botão que troca o tema via JavaScript */</span></span>
<span class="wzw-code-line">    .btn-toggle-tema {</span>
<span class="wzw-code-line">      background-color: var(--primaria);</span>
<span class="wzw-code-line">      color: var(--btn-texto);</span>
<span class="wzw-code-line">      border: none;</span>
<span class="wzw-code-line">      padding: 10px 16px;</span>
<span class="wzw-code-line">      border-radius: 8px;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">      display: inline-flex;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      gap: 8px;</span>
<span class="wzw-code-line">      transition: transform 0.2s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-toggle-tema:active {</span>
<span class="wzw-code-line">      transform: scale(0.96);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;painel-container&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;cabecalho-card&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;h3&gt;</span>⚡ Web-ZoneWare Theme<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-toggle-tema&quot;</span> <span class="wzw-tk-attr">onclick</span>=<span class="wzw-tk-str">&quot;alternarTema()&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">        🌓 Alternar Tema</span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;p&gt;</span></span>
<span class="wzw-code-line">      Este cartão consome exclusivamente variáveis CSS semânticas (<span class="wzw-tk-tag">&lt;code&gt;</span>--bg<span class="wzw-tk-tag">&lt;/code&gt;</span>, <span class="wzw-tk-tag">&lt;code&gt;</span>--card-bg<span class="wzw-tk-tag">&lt;/code&gt;</span>, <span class="wzw-tk-tag">&lt;code&gt;</span>--primaria<span class="wzw-tk-tag">&lt;/code&gt;</span>). Clique no botão acima para alternar entre Dark e Light Mode em tempo real!</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;script&gt;</span></span>
<span class="wzw-code-line">    function alternarTema() {</span>
<span class="wzw-code-line">      const html = document.documentElement;</span>
<span class="wzw-code-line">      const temaAtual = html.getAttribute(&#039;data-theme&#039;);</span>
<span class="wzw-code-line">      const novoTema = (temaAtual === &#039;dark&#039;) ? &#039;light&#039; : &#039;dark&#039;;</span>
<span class="wzw-code-line">      html.setAttribute(&#039;data-theme&#039;, novoTema);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/script&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot; data-theme=&quot;dark&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de CSS Variables e Dark Mode&lt;/title&gt;
  &lt;style&gt;
    /* TOKENS SEMÂNTICOS NO ESCOPO RAIZ */
    :root, [data-theme=&quot;dark&quot;] {
      --bg: #0b0f19;
      --card-bg: #1e293b;
      --texto: #f8fafc;
      --texto-mutado: #94a3b8;
      --borda: #334155;
      --primaria: #38bdf8;
      --btn-texto: #0b0f19;
    }

    [data-theme=&quot;light&quot;] {
      --bg: #f1f5f9;
      --card-bg: #ffffff;
      --texto: #0f172a;
      --texto-mutado: #64748b;
      --borda: #cbd5e1;
      --primaria: #2563eb;
      --btn-texto: #ffffff;
    }

    body {
      background-color: var(--bg);
      color: var(--texto);
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      padding: 40px;
      margin: 0;
      transition: background-color 0.3s ease, color 0.3s ease;
    }

    .painel-container {
      max-width: 480px;
      background-color: var(--card-bg);
      border: 1px solid var(--borda);
      border-radius: 14px;
      padding: 24px;
      box-shadow: 0 8px 24px rgba(0,0,0,0.15);
      transition: background-color 0.3s ease, border-color 0.3s ease;
    }

    .cabecalho-card {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
    }

    h3 { margin: 0; color: var(--primaria); font-size: 1.2rem; }

    p {
      color: var(--texto-mutado);
      font-size: 0.9rem;
      line-height: 1.6;
      margin: 0 0 20px 0;
    }

    /* Botão que troca o tema via JavaScript */
    .btn-toggle-tema {
      background-color: var(--primaria);
      color: var(--btn-texto);
      border: none;
      padding: 10px 16px;
      border-radius: 8px;
      font-weight: 700;
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      gap: 8px;
      transition: transform 0.2s ease;
    }

    .btn-toggle-tema:active {
      transform: scale(0.96);
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;painel-container&quot;&gt;
    &lt;div class=&quot;cabecalho-card&quot;&gt;
      &lt;h3&gt;⚡ Web-ZoneWare Theme&lt;/h3&gt;
      &lt;button class=&quot;btn-toggle-tema&quot; onclick=&quot;alternarTema()&quot;&gt;
        🌓 Alternar Tema
      &lt;/button&gt;
    &lt;/div&gt;

    &lt;p&gt;
      Este cartão consome exclusivamente variáveis CSS semânticas (&lt;code&gt;--bg&lt;/code&gt;, &lt;code&gt;--card-bg&lt;/code&gt;, &lt;code&gt;--primaria&lt;/code&gt;). Clique no botão acima para alternar entre Dark e Light Mode em tempo real!
    &lt;/p&gt;
  &lt;/div&gt;

  &lt;script&gt;
    function alternarTema() {
      const html = document.documentElement;
      const temaAtual = html.getAttribute(&#039;data-theme&#039;);
      const novoTema = (temaAtual === &#039;dark&#039;) ? &#039;light&#039; : &#039;dark&#039;;
      html.setAttribute(&#039;data-theme&#039;, novoTema);
    }
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste clicar no botão de alternância para ver todas as cores do cartão e do fundo se transformarem suavemente sem recarregar a página:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>7. Resumo e Próximos Passos</h2>
<ul>
<li>CSS Variables (Custom Properties) são declaradas com <code>--nome</code> e consumidas com <code>var(--nome, fallback)</code>.</li>
<li>Vivem na árvore do DOM em tempo de execução, respeitam o escopo da cascata e herdam valores de pais para filhos.</li>
<li>Declare tokens globais no <code>:root</code> e use tokens semânticos funcionais (como <code>--bg-card</code>) em vez de nomes físicos de cores.</li>
<li>A fusão de <code>@media (prefers-color-scheme)</code> com <code>[data-theme]</code> cria sistemas de Dark Mode elegantes e controláveis pelo usuário.</li>
<li>O JavaScript pode ler e atualizar variáveis CSS dinamicamente através de <code>setProperty()</code>.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> Agora que você domina as variáveis e o Dark Mode, como criar aquela estética translúcida futurista de vidro fosco (Glassmorphism) com desfoque de fundo e filtros visuais? Na <strong>Lição 46</strong>, mergulharemos em <strong>Filtros &#038; Glassmorphism no CSS (filter e backdrop-filter)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/css-variables-custom-properties-dark-mode/">CSS Variables e Dark Mode Dinâmico no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/css-variables-custom-properties-dark-mode/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Animações Profissionais com @keyframes no CSS &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/animacoes-keyframes-css/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/animacoes-keyframes-css/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:42:26 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[animacoes css]]></category>
		<category><![CDATA[animation shorthand]]></category>
		<category><![CDATA[animation-fill-mode]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[keyframes css]]></category>
		<category><![CDATA[steps css]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29467</guid>

					<description><![CDATA[<p>Na lição anterior, você aprendeu que as transições são perfeitas para suavizar a passagem entre dois estados quando o usuário interage com a página. No entanto, muitas interfaces exigem experiências cinematográficas contínuas: indicadores de carregamento que giram sem parar, notificações que entram suavemente na tela assim que o documento abre, ou ilustrações que flutuam em [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/animacoes-keyframes-css/">Animações Profissionais com @keyframes no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Na lição anterior, você aprendeu que as transições são perfeitas para suavizar a passagem entre dois estados quando o usuário interage com a página. No entanto, muitas interfaces exigem experiências cinematográficas contínuas: indicadores de carregamento que giram sem parar, notificações que entram suavemente na tela assim que o documento abre, ou ilustrações que flutuam em ciclos infinitos de respiração. Para coreografar múltiplos estágios temporais sem depender de ações do mouse, o CSS nos entrega o poderoso motor de <strong><code>@keyframes</code> e a propriedade <code>animation</code></strong>.
</p>
<h2>1. A Linha do Tempo: Criando Regras com <code>@keyframes</code></h2>
<p>
  Uma animação em CSS é dividida em duas partes: a <strong>linha do tempo (Timeline)</strong>, declarada com a regra-arroba <code>@keyframes</code>, e a <strong>aplicação da animação</strong>, configurada no seletor do elemento.
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-77400" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">20 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-77400', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-77400', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* 1. DEFINIÇÃO DA LINHA DO TEMPO */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-kw">@keyframes</span> pulsarBrilho {</span>
<span class="wzw-code-line">  0% {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transform</span>: scale(1);</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">opacity</span>: 0.6;</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">  50% {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transform</span>: scale(1.12);</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">opacity</span>: 1;</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">  100% {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transform</span>: scale(1);</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">opacity</span>: 0.6;</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 2. APLICAÇÃO NO ELEMENTO */</span></span>
<span class="wzw-code-line">.badge-alerta {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">animation</span>: pulsarBrilho <span class="wzw-tk-num">2s</span> ease-in-out infinite;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* 1. DEFINIÇÃO DA LINHA DO TEMPO */
@keyframes pulsarBrilho {
  0% {
    transform: scale(1);
    opacity: 0.6;
  }
  50% {
    transform: scale(1.12);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0.6;
  }
}

/* 2. APLICAÇÃO NO ELEMENTO */
.badge-alerta {
  animation: pulsarBrilho 2s ease-in-out infinite;
}</textarea>
        </div>
    </div>
    
</div>
<p>
  Você pode usar as palavras-chave <code>from</code> (equivalente a <code>0%</code>) e <code>to</code> (equivalente a <code>100%</code>) para animações simples, ou declarar quantos marcos percentuais intermediários desejar (<code>0%</code>, <code>25%</code>, <code>60%</code>, <code>100%</code>) para coreografias ricas.
</p>
<h2>2. As 8 Subpropriedades do <code>animation</code></h2>
<p>
  A propriedade abreviada <code>animation</code> encapsula 8 controles cirúrgicos:
</p>
<div class="wzw-table-responsive">
<table class="wzw-table">
<thead>
<tr>
<th>Propriedade</th>
<th>Valores Principais</th>
<th>Função na Animação</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>animation-name</code></td>
<td>Nome da regra <code>@keyframes</code></td>
<td>Conecta o elemento à sua linha do tempo.</td>
</tr>
<tr>
<td><code>animation-duration</code></td>
<td>Tempo (ex.: <code>1.5s</code>, <code>400ms</code>)</td>
<td>Duração de exatamente 1 ciclo da animação.</td>
</tr>
<tr>
<td><code>animation-timing-function</code></td>
<td><code>ease</code>, <code>linear</code>, <code>cubic-bezier</code>, <code>steps()</code></td>
<td>Curva de aceleração do movimento.</td>
</tr>
<tr>
<td><code>animation-delay</code></td>
<td>Tempo positivo ou negativo (ex.: <code>-0.5s</code>)</td>
<td>Tempo de espera antes do início do primeiro ciclo.</td>
</tr>
<tr>
<td><code>animation-iteration-count</code></td>
<td>Número inteiro ou <strong><code>infinite</code></strong></td>
<td>Quantas vezes a animação repetirá o ciclo.</td>
</tr>
<tr>
<td><code>animation-direction</code></td>
<td><code>normal</code>, <code>reverse</code>, <code>alternate</code></td>
<td><code>alternate</code> cria o efeito de ping-pong (vai e volta suavemente).</td>
</tr>
<tr>
<td><strong><code>animation-fill-mode</code></strong></td>
<td><code>none</code>, <code>forwards</code>, <code>backwards</code>, <code>both</code></td>
<td>Controla como os estilos persistem antes e após a execução.</td>
</tr>
<tr>
<td><code>animation-play-state</code></td>
<td><code>running</code>, <code>paused</code></td>
<td>Permite pausar ou retomar a animação (ex.: no <code>:hover</code>).</td>
</tr>
</tbody>
</table>
</div>
<h2>3. <code>animation-fill-mode</code>: O Fim dos Saltos Bruscos</h2>
<p>
  O maior pesadelo dos iniciantes é animar um card surgindo de baixo para cima com fade-in: a animação roda lindamente e, no instante em que chega a 100%, <strong>o card desaparece ou salta bruscamente de volta para o estado inicial</strong>!
</p>
<p>
  Isso acontece porque, por padrão (<code>animation-fill-mode: none</code>), o navegador descarta todos os estilos do <code>@keyframes</code> assim que a animação termina.
</p>
<div class="wzw-callout wzw-callout-info">
<p><strong>A Solução Definitiva com <code>forwards</code> e <code>both</code>:</strong></p>
<ul>
<li><strong><code>forwards</code>:</strong> Ordena ao navegador que <strong>mantenha permanentemente os estilos do último frame (100%)</strong> na tela após o término. O elemento nunca mais salta de volta!</li>
<li><strong><code>backwards</code>:</strong> Aplica os estilos do primeiro frame (0%) durante o período do <code>animation-delay</code> (evita que o elemento apareça antes da hora).</li>
<li><strong><code>both</code>:</strong> O padrão ouro! Aplica tanto <code>forwards</code> quanto <code>backwards</code>, garantindo entradas de tela impecáveis.</li>
</ul>
</div>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-55169" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">15 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-55169', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-55169', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Animação de Entrada Perfeita e Sem Saltos */</span></span>
<span class="wzw-code-line">.card-entrada {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">animation</span>: deslizarParaCima <span class="wzw-tk-num">0.6s</span> cubic-bezier(0.16, 1, 0.3, 1) both;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-kw">@keyframes</span> deslizarParaCima {</span>
<span class="wzw-code-line">  from {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">opacity</span>: 0;</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transform</span>: translateY(<span class="wzw-tk-num">30px</span>);</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">  to {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">opacity</span>: 1;</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transform</span>: translateY(0);</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Animação de Entrada Perfeita e Sem Saltos */
.card-entrada {
  animation: deslizarParaCima 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes deslizarParaCima {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. Pausando Loops no Hover: <code>animation-play-state</code></h2>
<p>
  Se você tem uma fita de marcas correndo na tela (<em>marquee</em> infinito) ou um disco girando, o usuário pode querer pausar a animação para ler com calma ao passar o mouse:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-62377" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">7 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-62377', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-62377', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.disco-giratorio {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">animation</span>: girar <span class="wzw-tk-num">8s</span> linear infinite;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.disco-giratorio<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">animation-play-state</span>: paused; /* Congela o giro exatamente no frame atual! */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.disco-giratorio {
  animation: girar 8s linear infinite;
}

.disco-giratorio:hover {
  animation-play-state: paused; /* Congela o giro exatamente no frame atual! */
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. Animações em Degraus com <code>steps()</code>: O Efeito Máquina de Escrever</h2>
<p>
  Em vez de uma transição fluida e suave, a função <strong><code>steps(n)</code></strong> quebra a interpolação em um número fixo de &#8220;degraus&#8221; discretos. É a base para animar spritesheets de jogos retrô e criar o efeito de digitação mecânica (Typewriter):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-89647" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">11 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-89647', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-89647', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.texto-maquina {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">overflow</span>: hidden;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">white-space</span>: nowrap;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">width</span>: 22ch; /* Largura exata de 22 caracteres */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">animation</span>: digitar <span class="wzw-tk-num">3s</span> steps(22) infinite alternate;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-kw">@keyframes</span> digitar {</span>
<span class="wzw-code-line">  from { width: 0; }</span>
<span class="wzw-code-line">  to { width: 22ch; }</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.texto-maquina {
  overflow: hidden;
  white-space: nowrap;
  width: 22ch; /* Largura exata de 22 caracteres */
  animation: digitar 3s steps(22) infinite alternate;
}

@keyframes digitar {
  from { width: 0; }
  to { width: 22ch; }
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Acessibilidade e Performance Gráfica (WCAG 2.2)</h2>
<div class="wzw-callout wzw-callout-warning">
<p><strong>Blindagem de Performance e Saúde:</strong></p>
<ul>
<li><strong>Performance:</strong> Anime preferencialmente <strong><code>transform</code></strong> e <strong><code>opacity</code></strong>. Evite animar <code>width</code>, <code>height</code>, <code>top</code> ou <code>margin</code> em loops infinitos, sob pena de travar a CPU e descarregar baterias de celulares.</li>
<li><strong>Acessibilidade:</strong> Elementos piscantes ou que se movem continuamente podem desencadear convulsões ou tonturas severas. É obrigatório incluir:
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-60361" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">6 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-60361', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-60361', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-kw">@media</span> (prefers-reduced-motion: reduce) {</span>
<span class="wzw-code-line">  * {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">animation-duration</span>: <span class="wzw-tk-num">0.01ms</span> <span class="wzw-tk-kw">!important</span>;</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">animation-iteration-count</span>: 1 <span class="wzw-tk-kw">!important</span>;</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}</textarea>
        </div>
    </div>
    </div>
</li>
</ul>
</div>
<h2>7. Laboratório Prático: 3 Animações de Produção em Ação</h2>
<p>
  No código interativo abaixo, construímos três animações do mundo real: um <strong>Spinner de Carregamento Infinito</strong>, um <strong>Efeito Máquina de Escrever com Cursor Piscante</strong> e um <strong>Card com Entrada Suave (Fade &#038; Slide)</strong> usando <code>animation-fill-mode: both</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-80610" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">113 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-80610', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-80610', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Animações @keyframes CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .painel-grid {</span>
<span class="wzw-code-line">      display: grid;</span>
<span class="wzw-code-line">      grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));</span>
<span class="wzw-code-line">      gap: 24px;</span>
<span class="wzw-code-line">      margin-top: 24px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .card-animacao {</span>
<span class="wzw-code-line">      background: #1e293b;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">      border-radius: 14px;</span>
<span class="wzw-code-line">      padding: 24px;</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      flex-direction: column;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      justify-content: center;</span>
<span class="wzw-code-line">      min-height: 200px;</span>
<span class="wzw-code-line">      text-align: center;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. SPINNER DE CARREGAMENTO (LOOP INFINITO) */</span></span>
<span class="wzw-code-line">    .spinner-radar {</span>
<span class="wzw-code-line">      width: 48px;</span>
<span class="wzw-code-line">      height: 48px;</span>
<span class="wzw-code-line">      border: 4px solid #334155;</span>
<span class="wzw-code-line">      border-top-color: #38bdf8;</span>
<span class="wzw-code-line">      border-radius: 50%;</span>
<span class="wzw-code-line">      animation: girar 1s linear infinite;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    @keyframes girar {</span>
<span class="wzw-code-line">      to { transform: rotate(360deg); }</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. EFEITO TYPEWRITER COM STEPS() */</span></span>
<span class="wzw-code-line">    .typewriter-box {</span>
<span class="wzw-code-line">      display: inline-block;</span>
<span class="wzw-code-line">      font-family: monospace;</span>
<span class="wzw-code-line">      font-size: 1.1rem;</span>
<span class="wzw-code-line">      color: #10b981;</span>
<span class="wzw-code-line">      white-space: nowrap;</span>
<span class="wzw-code-line">      overflow: hidden;</span>
<span class="wzw-code-line">      border-right: 3px solid #10b981;</span>
<span class="wzw-code-line">      width: 17ch; /* 17 caracteres */</span>
<span class="wzw-code-line">      animation: </span>
<span class="wzw-code-line">        escrever 3.5s steps(17) infinite alternate,</span>
<span class="wzw-code-line">        piscarCursor 0.7s step-end infinite;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    @keyframes escrever {</span>
<span class="wzw-code-line">      from { width: 0; }</span>
<span class="wzw-code-line">      to { width: 17ch; }</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    @keyframes piscarCursor {</span>
<span class="wzw-code-line">      50% { border-color: transparent; }</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. CARD COM ENTRADA CINEMATOGRÁFICA (FILL-MODE: BOTH) */</span></span>
<span class="wzw-code-line">    .card-entrada-suave {</span>
<span class="wzw-code-line">      animation: surgirComFade 1s cubic-bezier(0.16, 1, 0.3, 1) both;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    @keyframes surgirComFade {</span>
<span class="wzw-code-line">      0% {</span>
<span class="wzw-code-line">        opacity: 0;</span>
<span class="wzw-code-line">        transform: translateY(24px) scale(0.95);</span>
<span class="wzw-code-line">      }</span>
<span class="wzw-code-line">      100% {</span>
<span class="wzw-code-line">        opacity: 1;</span>
<span class="wzw-code-line">        transform: translateY(0) scale(1);</span>
<span class="wzw-code-line">      }</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h2</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#f1f5f9; margin-top:0;&quot;</span><span class="wzw-tk-tag">&gt;</span>Animações Avançadas com @keyframes<span class="wzw-tk-tag">&lt;/h2&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    Observe três cenários de produção controlados exclusivamente pelo motor gráfico do CSS:</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;painel-grid&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-animacao&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;spinner-radar&quot;</span><span class="wzw-tk-tag">&gt;</span><span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin:16px 0 0 0; color:#94a3b8; font-size:0.85rem;&quot;</span><span class="wzw-tk-tag">&gt;</span>Spinner Infinito (linear infinite)<span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-animacao&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;typewriter-box&quot;</span><span class="wzw-tk-tag">&gt;</span>Web-ZoneWare 2026<span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin:16px 0 0 0; color:#94a3b8; font-size:0.85rem;&quot;</span><span class="wzw-tk-tag">&gt;</span>Typewriter com <span class="wzw-tk-tag">&lt;code&gt;</span>steps()<span class="wzw-tk-tag">&lt;/code&gt;</span><span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-animacao card-entrada-suave&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;h4</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin:0 0 8px 0; color:#38bdf8;&quot;</span><span class="wzw-tk-tag">&gt;</span>Entrada Blindada<span class="wzw-tk-tag">&lt;/h4&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin:0; font-size:0.85rem; color:#94a3b8;&quot;</span><span class="wzw-tk-tag">&gt;</span>Retém o estado com <span class="wzw-tk-tag">&lt;code&gt;</span>animation-fill-mode: both<span class="wzw-tk-tag">&lt;/code&gt;</span><span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Animações @keyframes CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 40px;
      margin: 0;
    }

    .painel-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
      gap: 24px;
      margin-top: 24px;
    }

    .card-animacao {
      background: #1e293b;
      border: 1px solid #334155;
      border-radius: 14px;
      padding: 24px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 200px;
      text-align: center;
    }

    /* 1. SPINNER DE CARREGAMENTO (LOOP INFINITO) */
    .spinner-radar {
      width: 48px;
      height: 48px;
      border: 4px solid #334155;
      border-top-color: #38bdf8;
      border-radius: 50%;
      animation: girar 1s linear infinite;
    }

    @keyframes girar {
      to { transform: rotate(360deg); }
    }

    /* 2. EFEITO TYPEWRITER COM STEPS() */
    .typewriter-box {
      display: inline-block;
      font-family: monospace;
      font-size: 1.1rem;
      color: #10b981;
      white-space: nowrap;
      overflow: hidden;
      border-right: 3px solid #10b981;
      width: 17ch; /* 17 caracteres */
      animation: 
        escrever 3.5s steps(17) infinite alternate,
        piscarCursor 0.7s step-end infinite;
    }

    @keyframes escrever {
      from { width: 0; }
      to { width: 17ch; }
    }

    @keyframes piscarCursor {
      50% { border-color: transparent; }
    }

    /* 3. CARD COM ENTRADA CINEMATOGRÁFICA (FILL-MODE: BOTH) */
    .card-entrada-suave {
      animation: surgirComFade 1s cubic-bezier(0.16, 1, 0.3, 1) both;
    }

    @keyframes surgirComFade {
      0% {
        opacity: 0;
        transform: translateY(24px) scale(0.95);
      }
      100% {
        opacity: 1;
        transform: translateY(0) scale(1);
      }
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h2 style=&quot;color:#f1f5f9; margin-top:0;&quot;&gt;Animações Avançadas com @keyframes&lt;/h2&gt;
  &lt;p style=&quot;color:#94a3b8; font-size:0.9rem;&quot;&gt;
    Observe três cenários de produção controlados exclusivamente pelo motor gráfico do CSS:
  &lt;/p&gt;

  &lt;div class=&quot;painel-grid&quot;&gt;
    &lt;div class=&quot;card-animacao&quot;&gt;
      &lt;div class=&quot;spinner-radar&quot;&gt;&lt;/div&gt;
      &lt;p style=&quot;margin:16px 0 0 0; color:#94a3b8; font-size:0.85rem;&quot;&gt;Spinner Infinito (linear infinite)&lt;/p&gt;
    &lt;/div&gt;

    &lt;div class=&quot;card-animacao&quot;&gt;
      &lt;div class=&quot;typewriter-box&quot;&gt;Web-ZoneWare 2026&lt;/div&gt;
      &lt;p style=&quot;margin:16px 0 0 0; color:#94a3b8; font-size:0.85rem;&quot;&gt;Typewriter com &lt;code&gt;steps()&lt;/code&gt;&lt;/p&gt;
    &lt;/div&gt;

    &lt;div class=&quot;card-animacao card-entrada-suave&quot;&gt;
      &lt;h4 style=&quot;margin:0 0 8px 0; color:#38bdf8;&quot;&gt;Entrada Blindada&lt;/h4&gt;
      &lt;p style=&quot;margin:0; font-size:0.85rem; color:#94a3b8;&quot;&gt;Retém o estado com &lt;code&gt;animation-fill-mode: both&lt;/code&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste alterar a curva de aceleração ou a direção da animação para <code>alternate</code> para comprovar a versatilidade do <code>@keyframes</code>:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>8. Resumo e Próximos Passos</h2>
<ul>
<li><code>@keyframes</code> define uma linha do tempo autônoma através de porcentagens (<code>0%</code> a <code>100%</code>).</li>
<li>A propriedade <code>animation</code> conecta o elemento à timeline e dita duração, repetições e velocidade.</li>
<li><code>animation-fill-mode: forwards</code> ou <code>both</code> impede que a animação sofra saltos bruscos ao terminar.</li>
<li><code>animation-direction: alternate</code> cria loops suaves de ida e volta (ping-pong).</li>
<li>A função <code>steps()</code> divide a interpolação em degraus rígidos, ideal para sprites e efeitos de digitação.</li>
<li>Priorize animar <code>transform</code> e <code>opacity</code> para manter 60fps acelerados pela placa de vídeo.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> Como organizar paletas de cores globais, alternar entre Modo Claro e Escuro dinamicamente e evitar valores mágicos repetidos no CSS? Na <strong>Lição 45</strong>, desvendaremos as <strong>CSS Variables (Custom Properties) &#038; Dark Mode Dinâmico</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/animacoes-keyframes-css/">Animações Profissionais com @keyframes no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/animacoes-keyframes-css/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Transições Suaves no CSS com transition &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/transicoes-css-suaves-animadas/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/transicoes-css-suaves-animadas/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:38:47 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[aceleracao gpu]]></category>
		<category><![CDATA[cubic-bezier]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[micro-interacoes]]></category>
		<category><![CDATA[timing function]]></category>
		<category><![CDATA[transicoes suaves]]></category>
		<category><![CDATA[transition css]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29465</guid>

					<description><![CDATA[<p>A diferença entre um website amador e uma aplicação digital de alto padrão estético reside nas micro-interações. Sem transições, quando o usuário passa o mouse sobre um botão, as cores e elevações mudam em zero milissegundos — um corte seco, robótico e visualmente agressivo. A propriedade transition ensina o motor do navegador a interpolar matematicamente [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/transicoes-css-suaves-animadas/">Transições Suaves no CSS com transition | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  A diferença entre um website amador e uma aplicação digital de alto padrão estético reside nas micro-interações. Sem transições, quando o usuário passa o mouse sobre um botão, as cores e elevações mudam em zero milissegundos — um corte seco, robótico e visualmente agressivo. A propriedade <strong><code>transition</code></strong> ensina o motor do navegador a interpolar matematicamente a passagem suave entre o estado inicial e o estado final de um elemento. Nesta lição, você dominará as 4 subpropriedades de transição, aprenderá por que deve fugir do <code>transition: all</code> e descobrirá como usar curvas <strong><code>cubic-bezier</code></strong> para criar efeitos de mola elástica cinematográficos.
</p>
<h2>1. A Anatomia da Propriedade <code>transition</code></h2>
<p>
  Uma transição suave completa é composta por quatro parâmetros fundamentais:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-23797" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-23797', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-23797', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Sintaxe Geral: transition: [propriedade] [duração] [curva-de-velocidade] [atraso]; */</span></span>
<span class="wzw-code-line">.botao {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transition</span>: transform <span class="wzw-tk-num">0.3s</span> ease <span class="wzw-tk-num">0s</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Sintaxe Geral: transition: [propriedade] [duração] [curva-de-velocidade] [atraso]; */
.botao {
  transition: transform 0.3s ease 0s;
}</textarea>
        </div>
    </div>
    
</div>
<h3>1. <code>transition-property</code> — O que Animar?</h3>
<p>
  Define exatamente quais propriedades de estilo serão interpoladas suavemente.
</p>
<div class="wzw-callout wzw-callout-warning">
<p><strong>O Perigo Mortal do <code>transition: all</code>:</strong> Declarar <code>transition: all 0.3s</code> é um dos maiores anti-padrões de CSS. Ao instruir o navegador a animar &#8220;tudo&#8221;, qualquer mudança acidental de <code>padding</code>, <code>font-size</code> ou <code>margin</code> forçará a CPU a recalcular o layout da página inteira (Reflow). <strong>Sempre liste as propriedades específicas</strong> (ex.: <code>transition: transform 0.2s, background-color 0.2s;</code>).</p>
</div>
<h3>2. <code>transition-duration</code> — O Tempo de Resposta</h3>
<p>
  O tempo total da transição, expresso em segundos (<code>0.3s</code>) ou milissegundos (<code>300ms</code>).
</p>
<ul>
<li><strong>Zona Ideal de Micro-interações (150ms a 350ms):</strong> É rápida o suficiente para parecer instantânea e suave o bastante para ser percebida pelo cérebro humano.</li>
<li><strong>Acima de 500ms:</strong> O site começa a parecer pesado, lerdo e cansativo para o usuário.</li>
</ul>
<h3>3. <code>transition-timing-function</code> — A Física da Velocidade</h3>
<p>
  Dita a curva de aceleração do movimento, simulando as leis de inércia da física real.
</p>
<h3>4. <code>transition-delay</code> — O Tempo de Espera</h3>
<p>
  Define quanto tempo o navegador deve aguardar antes de iniciar a transição. Excelente para criar cascatas de itens em listas (staggered animations).
</p>
<h2>2. A Física das Curvas de Velocidade (Timing Functions)</h2>
<p>
  A forma como um objeto acelera e desacelera comunica peso e personalidade à interface:
</p>
<div class="wzw-table-responsive">
<table class="wzw-table">
<thead>
<tr>
<th>Função</th>
<th>Comportamento Físico</th>
<th>Sensação Visual</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>linear</code></strong></td>
<td>Velocidade estritamente constante do início ao fim.</td>
<td>Robótica, mecânica, artificial.</td>
</tr>
<tr>
<td><strong><code>ease</code></strong> (Padrão)</td>
<td>Começa lento, acelera no meio e desacelera no final.</td>
<td>Suave e natural para a maioria dos casos.</td>
</tr>
<tr>
<td><strong><code>ease-out</code></strong></td>
<td>Começa rápido e desacelera suavemente no final.</td>
<td><strong>A melhor opção para interações:</strong> reage instantaneamente ao usuário!</td>
</tr>
<tr>
<td><strong><code>ease-in</code></strong></td>
<td>Começa muito lento e acelera no final.</td>
<td>Excelente para elementos saindo da tela.</td>
</tr>
<tr>
<td><strong><code>ease-in-out</code></strong></td>
<td>Aceleração e desaceleração simétricas.</td>
<td>Ótimo para modais e rotações completas.</td>
</tr>
</tbody>
</table>
</div>
<h2>3. O Superpoder do <code>cubic-bezier</code>: O Efeito Mola (Spring)</h2>
<p>
  Todas as funções acima são apenas atalhos pré-configurados de uma <strong>Curva de Bézier Cúbica</strong> composta por 4 coordenadas matemáticas: <code>cubic-bezier(P1x, P1y, P2x, P2y)</code>.
</p>
<p>
  A mágica acontece quando usamos um valor no eixo Y <strong>maior do que 1</strong>: o elemento ultrapassa seu destino final e &#8220;rebota&#8221; elasticamente de volta, simulando uma mola mecânica sem precisar de bibliotecas pesadas de animação em JavaScript:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-23547" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">8 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-23547', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-23547', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Curva de Rebote Elástico Snappy / Bouncy */</span></span>
<span class="wzw-code-line">.card-elastico {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transition</span>: transform <span class="wzw-tk-num">0.4s</span> cubic-bezier(0.34, 1.56, 0.64, 1);</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.card-elastico<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: translateY(-<span class="wzw-tk-num">10px</span>) scale(1.03); /* Dá um leve <span class="wzw-tk-str">&quot;pulo&quot;</span> elástico! */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Curva de Rebote Elástico Snappy / Bouncy */
.card-elastico {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.card-elastico:hover {
  transform: translateY(-10px) scale(1.03); /* Dá um leve &quot;pulo&quot; elástico! */
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. Onde Declarar a Transição? A Regra da Ida e da Volta</h2>
<div class="wzw-callout wzw-callout-info">
<p><strong>A Pegadinha Mais Comum do CSS:</strong> Se você declarar o <code>transition</code> dentro do bloco <code>:hover</code>, a animação funcionará suavemente quando o mouse ENTRAR no elemento, mas ao tirar o cursor, a transição é cancelada e o elemento volta em um corte seco instantâneo! <strong>Declare sempre o <code>transition</code> na classe base do elemento</strong> para garantir que a ida e a volta sejam 100% fluidas.</p>
</div>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-30057" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">12 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-30057', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-30057', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* FORMA CORRETA: No estado base */</span></span>
<span class="wzw-code-line">.botao-perfeito {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: <span class="wzw-tk-num">#2563eb</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: translateY(0);</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* A transição mora aqui, garantindo suavidade na ida E na volta: */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transition</span>: transform <span class="wzw-tk-num">0.25s</span> ease-out, background-color <span class="wzw-tk-num">0.2s</span> ease;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.botao-perfeito<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: <span class="wzw-tk-num">#1d4ed8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: translateY(-<span class="wzw-tk-num">4px</span>);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* FORMA CORRETA: No estado base */
.botao-perfeito {
  background-color: #2563eb;
  transform: translateY(0);
  /* A transição mora aqui, garantindo suavidade na ida E na volta: */
  transition: transform 0.25s ease-out, background-color 0.2s ease;
}

.botao-perfeito:hover {
  background-color: #1d4ed8;
  transform: translateY(-4px);
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. Múltiplas Transições Independentes</h2>
<p>
  Você pode atribuir tempos e acelerações diferentes para cada propriedade, separando-as por vírgula em uma única regra:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-76310" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">7 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-76310', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-76310', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.cartao-vip {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* O movimento dura 300ms com mola; a sombra muda mais rápido em 150ms */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transition</span>: </span>
<span class="wzw-code-line">    transform <span class="wzw-tk-num">0.3s</span> cubic-bezier(0.34, 1.56, 0.64, 1),</span>
<span class="wzw-code-line">    box-shadow <span class="wzw-tk-num">0.15s</span> ease-out,</span>
<span class="wzw-code-line">    border-color <span class="wzw-tk-num">0.2s</span> linear;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.cartao-vip {
  /* O movimento dura 300ms com mola; a sombra muda mais rápido em 150ms */
  transition: 
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.15s ease-out,
    border-color 0.2s linear;
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Acessibilidade Vestibular (WCAG 2.2)</h2>
<p>
  Transições com movimento de escala ou translação devem respeitar as preferências de acessibilidade de pessoas com labirintite:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-40039" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-40039', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-40039', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-kw">@media</span> (prefers-reduced-motion: reduce) {</span>
<span class="wzw-code-line">  * {</span>
<span class="wzw-code-line">    <span class="wzw-tk-attr">transition</span>: none <span class="wzw-tk-kw">!important</span>;</span>
<span class="wzw-code-line">  }</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}</textarea>
        </div>
    </div>
    
</div>
<h2>7. Laboratório Prático: Comparando Curvas e o Efeito Mola</h2>
<p>
  No código interativo abaixo, experimente passar o cursor do mouse sobre cada um dos 3 botões para sentir visualmente a diferença entre a falta de transição, a transição <code>ease</code> tradicional e o efeito mola com <code>cubic-bezier</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-18507" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">72 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-18507', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-18507', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Transições CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .painel-botoes {</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      flex-wrap: wrap;</span>
<span class="wzw-code-line">      gap: 20px;</span>
<span class="wzw-code-line">      margin-top: 24px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-teste {</span>
<span class="wzw-code-line">      background: #1e293b;</span>
<span class="wzw-code-line">      color: #fff;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">      padding: 16px 28px;</span>
<span class="wzw-code-line">      border-radius: 10px;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">      font-size: 0.95rem;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. SEM TRANSIÇÃO (CORTE SECO) */</span></span>
<span class="wzw-code-line">    .btn-sem-transicao:hover {</span>
<span class="wzw-code-line">      background: #ef4444;</span>
<span class="wzw-code-line">      transform: translateY(-8px);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. TRANSIÇÃO PADRÃO (EASE) */</span></span>
<span class="wzw-code-line">    .btn-ease {</span>
<span class="wzw-code-line">      transition: transform 0.25s ease, background 0.25s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-ease:hover {</span>
<span class="wzw-code-line">      background: #3b82f6;</span>
<span class="wzw-code-line">      transform: translateY(-8px);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. EFEITO MOLA ELÁSTICA (CUBIC-BEZIER) */</span></span>
<span class="wzw-code-line">    .btn-mola {</span>
<span class="wzw-code-line">      transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-mola:hover {</span>
<span class="wzw-code-line">      background: #10b981;</span>
<span class="wzw-code-line">      transform: translateY(-8px) scale(1.05);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h2</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#f1f5f9; margin-top:0;&quot;</span><span class="wzw-tk-tag">&gt;</span>A Física das Transições Suaves no CSS<span class="wzw-tk-tag">&lt;/h2&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    Passe o mouse sobre os 3 botões e observe a diferença física de percepção e acabamento de cada um:</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;painel-botoes&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-teste btn-sem-transicao&quot;</span><span class="wzw-tk-tag">&gt;</span>1. Sem Transição (Seco)<span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-teste btn-ease&quot;</span><span class="wzw-tk-tag">&gt;</span>2. Transição ease (Padrão)<span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-teste btn-mola&quot;</span><span class="wzw-tk-tag">&gt;</span>3. Mola cubic-bezier (Snappy)<span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Transições CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 40px;
      margin: 0;
    }

    .painel-botoes {
      display: flex;
      flex-wrap: wrap;
      gap: 20px;
      margin-top: 24px;
    }

    .btn-teste {
      background: #1e293b;
      color: #fff;
      border: 1px solid #334155;
      padding: 16px 28px;
      border-radius: 10px;
      font-weight: 700;
      font-size: 0.95rem;
      cursor: pointer;
    }

    /* 1. SEM TRANSIÇÃO (CORTE SECO) */
    .btn-sem-transicao:hover {
      background: #ef4444;
      transform: translateY(-8px);
    }

    /* 2. TRANSIÇÃO PADRÃO (EASE) */
    .btn-ease {
      transition: transform 0.25s ease, background 0.25s ease;
    }

    .btn-ease:hover {
      background: #3b82f6;
      transform: translateY(-8px);
    }

    /* 3. EFEITO MOLA ELÁSTICA (CUBIC-BEZIER) */
    .btn-mola {
      transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s ease;
    }

    .btn-mola:hover {
      background: #10b981;
      transform: translateY(-8px) scale(1.05);
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h2 style=&quot;color:#f1f5f9; margin-top:0;&quot;&gt;A Física das Transições Suaves no CSS&lt;/h2&gt;
  &lt;p style=&quot;color:#94a3b8; font-size:0.9rem;&quot;&gt;
    Passe o mouse sobre os 3 botões e observe a diferença física de percepção e acabamento de cada um:
  &lt;/p&gt;

  &lt;div class=&quot;painel-botoes&quot;&gt;
    &lt;button class=&quot;btn-teste btn-sem-transicao&quot;&gt;1. Sem Transição (Seco)&lt;/button&gt;
    &lt;button class=&quot;btn-teste btn-ease&quot;&gt;2. Transição ease (Padrão)&lt;/button&gt;
    &lt;button class=&quot;btn-teste btn-mola&quot;&gt;3. Mola cubic-bezier (Snappy)&lt;/button&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste alterar as coordenadas da curva <code>cubic-bezier</code> para criar seus próprios efeitos de aceleração física:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>8. Resumo e Próximos Passos</h2>
<ul>
<li><code>transition</code> interpola suavemente a transição numérica entre dois estados disparados por interações.</li>
<li>Evite <code>transition: all</code> para blindar sua página contra quedas de quadros de layout (Reflows); especifique sempre propriedades como <code>transform</code> e <code>opacity</code>.</li>
<li>Durações entre 150ms e 350ms são o padrão ouro da ergonomia de interfaces modernas.</li>
<li>Declare o <code>transition</code> no estado base do elemento para garantir suavidade na entrada e na saída do hover.</li>
<li>Curvas <code>cubic-bezier</code> com valores de Y maiores que 1 simulam o efeito de rebote elástico (spring) com extrema elegância e performance nativa.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> As transições conectam dois estados com base na ação do usuário. Mas e quando queremos uma animação cinematográfica contínua, com dezenas de etapas intermediárias, repetição infinita e sem depender de cliques ou hovers? Na <strong>Lição 44</strong>, dominaremos as <strong>Animações com @keyframes no CSS</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/transicoes-css-suaves-animadas/">Transições Suaves no CSS com transition | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/transicoes-css-suaves-animadas/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Transformações 2D e 3D Modernas no CSS &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/transformacoes-css-translate-rotate-scale/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/transformacoes-css-translate-rotate-scale/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:34:39 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[aceleracao gpu]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[perspective css]]></category>
		<category><![CDATA[rotate css]]></category>
		<category><![CDATA[scale css]]></category>
		<category><![CDATA[transform css]]></category>
		<category><![CDATA[transformacoes 2d 3d]]></category>
		<category><![CDATA[translate css]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29463</guid>

					<description><![CDATA[<p>Até este ponto da sua jornada, os elementos da tela viveram confinados em caixas estáticas retangulares. Mas o CSS moderno possui um verdadeiro motor de computação gráfica: o módulo de Transformações (CSS Transforms). Com ele, você pode transladar, rotacionar, redimensionar, inclinar e até projetar elementos na terceira dimensão (Eixo Z). E o aspecto mais impressionante: [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/transformacoes-css-translate-rotate-scale/">Transformações 2D e 3D Modernas no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Até este ponto da sua jornada, os elementos da tela viveram confinados em caixas estáticas retangulares. Mas o CSS moderno possui um verdadeiro motor de computação gráfica: o módulo de <strong>Transformações (CSS Transforms)</strong>. Com ele, você pode transladar, rotacionar, redimensionar, inclinar e até projetar elementos na terceira dimensão (Eixo Z). E o aspecto mais impressionante: diferente das velhas alterações de coordenadas, as transformações são processadas diretamente na placa de vídeo (GPU), garantindo experiências visuais fluidas a 60 ou 120 quadros por segundo sem engasgos.
</p>
<h2>1. A Pipeline Gráfica: Por que a GPU Transforma Tudo?</h2>
<p>
  Para compreender a supremacia das transformações, precisamos analisar o que o navegador faz internamente quando um elemento se move na tela:
</p>
<ul>
<li><strong>Movimentação Antiga (com <code>top</code>, <code>left</code> ou <code>margin</code>):</strong> Força a CPU a recalcular a geometria física de todos os elementos da página (etapa de <strong>Layout/Reflow</strong>) e redesenhar cada pixel na tela (<strong>Repaint</strong>). Em celulares ou páginas complexas, isso causa engasgos visuais graves (<em>jank</em>).</li>
<li><strong>Movimentação Moderna (com <code>transform</code>):</strong> O elemento é isolado em sua própria camada de vídeo (<strong>Composite Layer</strong>) e manipulado diretamente pela <strong>GPU (Placa Gráfica)</strong>. O navegador não recalcula o layout nem repinta os vizinhos: ele apenas move a imagem da camada com aceleração por hardware!</li>
</ul>
<div class="wzw-callout wzw-callout-info">
<p><strong>Regra de Alta Performance:</strong> Toda vez que você for mover um elemento (em um hover, modal ou animação), <strong>NUNCA anime <code>top</code> ou <code>left</code></strong>. Use sempre <strong><code>transform: translate()</code></strong>!</p>
</div>
<h2>2. As 4 Transformações 2D Fundamentais</h2>
<p>
  A propriedade <code>transform</code> aceita uma ou mais funções geométricas aplicadas no plano bidimensional (X e Y):
</p>
<h3>1. <code>translate(x, y)</code> — Deslocamento sem Perturbar Vizinhos</h3>
<p>
  Move o elemento nos eixos horizontal e vertical. O espaço original da caixa permanece 100% preservado no fluxo normal:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-92811" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">3 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-92811', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-92811', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.card<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: translateY(-<span class="wzw-tk-num">8px</span>); /* Eleva o card <span class="wzw-tk-num">8px</span> para cima com aceleração GPU */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.card:hover {
  transform: translateY(-8px); /* Eleva o card 8px para cima com aceleração GPU */
}</textarea>
        </div>
    </div>
    
</div>
<p>
  <strong>O Truque Histórico da Centralização:</strong> Valores percentuais em <code>translate()</code> calculam em relação ao <em>tamanho do próprio elemento</em> (e não do pai!). Por isso, a combinação clássica centraliza qualquer elemento com perfeição milimétrica:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-63989" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">6 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-63989', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-63989', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.modal-centralizado {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: absolute;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">top</span>: 50%;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">left</span>: 50%;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: translate(-50%, -50%); /* Recua exatamente metade da sua própria largura e altura */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.modal-centralizado {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); /* Recua exatamente metade da sua própria largura e altura */
}</textarea>
        </div>
    </div>
    
</div>
<h3>2. <code>scale(x, y)</code> — Escala e Zoom Suave</h3>
<p>
  Aumenta ou diminui o elemento visualmente. O valor <code>1</code> representa 100% (tamanho natural):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-31412" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">3 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-31412', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-31412', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.btn-cta<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: scale(1.05); /* Amplia o botão em 5% sem alterar o layout da página */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.btn-cta:hover {
  transform: scale(1.05); /* Amplia o botão em 5% sem alterar o layout da página */
}</textarea>
        </div>
    </div>
    
</div>
<h3>3. <code>rotate(ângulo)</code> — Rotação Angular</h3>
<p>
  Gira o elemento em torno de seu eixo. Aceita graus (<code>deg</code>) ou voltas (<code>turn</code>):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-15812" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-15812', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-15812', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.icone-engrenagem {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: rotate(<span class="wzw-tk-num">45deg</span>);   /* Gira 45 graus no sentido horário */</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* transform: rotate(0.5turn); Gira meia volta (180 graus) */</span></span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.icone-engrenagem {
  transform: rotate(45deg);   /* Gira 45 graus no sentido horário */
  /* transform: rotate(0.5turn); Gira meia volta (180 graus) */
}</textarea>
        </div>
    </div>
    
</div>
<h3>4. <code>skew(x, y)</code> — Inclinação Paralela</h3>
<p>
  Distorce as faces do elemento em ângulos diagonais, criando o efeito de paralelogramo:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-98658" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">3 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-98658', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-98658', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.faixa-diagonal {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: skewX(-<span class="wzw-tk-num">12deg</span>); /* Cria bordas esportivas inclinadas */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.faixa-diagonal {
  transform: skewX(-12deg); /* Cria bordas esportivas inclinadas */
}</textarea>
        </div>
    </div>
    
</div>
<h2>3. O Ponto de Ancoragem: <code>transform-origin</code></h2>
<p>
  Por padrão, toda transformação acontece a partir do centro geométrico do elemento (<code>50% 50%</code>). A propriedade <strong><code>transform-origin</code></strong> permite alterar esse pivô de ancoragem:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-83287" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-83287', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-83287', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.ponteiro-relogio {</span>
<span class="wzw-code-line">  <span class="wzw-tk-comment">/* Gira a partir da base inferior central, como o ponteiro de um relógio real */</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform-origin</span>: center bottom;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: rotate(<span class="wzw-tk-num">90deg</span>);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.ponteiro-relogio {
  /* Gira a partir da base inferior central, como o ponteiro de um relógio real */
  transform-origin: center bottom;
  transform: rotate(90deg);
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. Entrando na Terceira Dimensão (3D Transforms)</h2>
<p>
  Telas de computador e celulares são superfícies bidimensionais estritamente planas. Para que o cérebro humano perceba profundidade em 3D, precisamos aplicar a propriedade <strong><code>perspective</code></strong> no contêiner pai:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-49541" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">3 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-49541', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-49541', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.cena-3d {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">perspective</span>: <span class="wzw-tk-num">1000px</span>; /* Define a distância do olho do usuário até a tela */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.cena-3d {
  perspective: 1000px; /* Define a distância do olho do usuário até a tela */
}</textarea>
        </div>
    </div>
    
</div>
<h3>A Tríade Sagrada do Efeito Card Flip 3D</h3>
<p>
  Para criar o famoso efeito de virar um cartão em 180 graus revelando o verso, usamos três propriedades essenciais:
</p>
<ol>
<li><strong><code>perspective</code> no pai:</strong> Cria o campo de visão tridimensional realista.</li>
<li><strong><code>transform-style: preserve-3d</code> no cartão:</strong> Garante que as faces frontal e traseira coexistam no espaço 3D real, em vez de serem achatadas pelo navegador.</li>
<li><strong><code>backface-visibility: hidden</code> nas faces:</strong> Informa ao motor gráfico para ocultar o verso de uma face quando ela estiver de costas para os olhos do usuário!</li>
</ol>
<h2>5. Novidade Moderna: Propriedades Individuais de Transformação</h2>
<p>
  A especificação <em>CSS Transforms Level 2</em> introduziu propriedades independentes para que você não precise mais reescrever a longa cadeia de <code>transform</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-85394" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">6 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-85394', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-85394', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Sintaxe Moderna Independente (Navegadores Modernos) */</span></span>
<span class="wzw-code-line">.card-moderno<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">translate</span>: 0 -<span class="wzw-tk-num">8px</span>;  /* Equivalente a transform: translateY(-<span class="wzw-tk-num">8px</span>) */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">scale</span>: 1.03;        /* Equivalente a transform: scale(1.03) */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">rotate</span>: <span class="wzw-tk-num">2deg</span>;       /* Equivalente a transform: rotate(<span class="wzw-tk-num">2deg</span>) */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Sintaxe Moderna Independente (Navegadores Modernos) */
.card-moderno:hover {
  translate: 0 -8px;  /* Equivalente a transform: translateY(-8px) */
  scale: 1.03;        /* Equivalente a transform: scale(1.03) */
  rotate: 2deg;       /* Equivalente a transform: rotate(2deg) */
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Laboratório Prático: O Espetacular Card Flip 3D</h2>
<p>
  No código interativo abaixo, construímos um cartão de curso tridimensional. Ao passar o mouse sobre ele, o cartão gira 180 graus no Eixo Y, ocultando a frente e revelando a ementa de estudos no verso com aceleração por hardware perfeita:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-12651" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">111 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-12651', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-12651', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Transformações 3D CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      flex-direction: column;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. O CONTÊINER COM PERSPECTIVA 3D */</span></span>
<span class="wzw-code-line">    .cena-card {</span>
<span class="wzw-code-line">      width: 320px;</span>
<span class="wzw-code-line">      height: 400px;</span>
<span class="wzw-code-line">      perspective: 1000px; /* Profundidade de câmera */</span>
<span class="wzw-code-line">      margin-top: 20px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. O CARTÃO QUE GIRA */</span></span>
<span class="wzw-code-line">    .card-3d {</span>
<span class="wzw-code-line">      width: 100%;</span>
<span class="wzw-code-line">      height: 100%;</span>
<span class="wzw-code-line">      position: relative;</span>
<span class="wzw-code-line">      transform-style: preserve-3d; /* Preserva o espaço tridimensional dos filhos */</span>
<span class="wzw-code-line">      transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .cena-card:hover .card-3d {</span>
<span class="wzw-code-line">      transform: rotateY(180deg); /* Gira 180 graus na horizontal */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. AS FACES (FRENTE E VERSO) */</span></span>
<span class="wzw-code-line">    .card-face {</span>
<span class="wzw-code-line">      position: absolute;</span>
<span class="wzw-code-line">      inset: 0;</span>
<span class="wzw-code-line">      border-radius: 16px;</span>
<span class="wzw-code-line">      padding: 28px;</span>
<span class="wzw-code-line">      box-sizing: border-box;</span>
<span class="wzw-code-line">      display: flex;</span>
<span class="wzw-code-line">      flex-direction: column;</span>
<span class="wzw-code-line">      justify-content: center;</span>
<span class="wzw-code-line">      backface-visibility: hidden; /* OCULTA O VERSO QUANDO DE COSTAS! */</span>
<span class="wzw-code-line">      box-shadow: 0 10px 30px rgba(0,0,0,0.4);</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* FACE FRONTAL */</span></span>
<span class="wzw-code-line">    .face-frente {</span>
<span class="wzw-code-line">      background: linear-gradient(135deg, #1e293b, #0f172a);</span>
<span class="wzw-code-line">      border-color: #38bdf8;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .face-frente h3 { margin: 0 0 10px 0; color: #38bdf8; font-size: 1.4rem; }</span>
<span class="wzw-code-line">    .face-frente p { color: #94a3b8; font-size: 0.9rem; line-height: 1.5; }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* FACE TRASEIRA */</span></span>
<span class="wzw-code-line">    .face-verso {</span>
<span class="wzw-code-line">      background: linear-gradient(135deg, #2563eb, #1d4ed8);</span>
<span class="wzw-code-line">      transform: rotateY(180deg); /* Já nasce virada de costas */</span>
<span class="wzw-code-line">      text-align: center;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .face-verso h3 { margin: 0 0 12px 0; color: #fff; }</span>
<span class="wzw-code-line">    .face-verso p { color: #bfdbfe; font-size: 0.85rem; margin-bottom: 20px; }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-matricular {</span>
<span class="wzw-code-line">      background: #fff;</span>
<span class="wzw-code-line">      color: #1d4ed8;</span>
<span class="wzw-code-line">      border: none;</span>
<span class="wzw-code-line">      padding: 12px 24px;</span>
<span class="wzw-code-line">      border-radius: 8px;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h2</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#f1f5f9; margin-top:0;&quot;</span><span class="wzw-tk-tag">&gt;</span>Card Flip 3D com Aceleração por GPU<span class="wzw-tk-tag">&lt;/h2&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    Passe o cursor sobre o cartão para testemunhar o giro tridimensional em 180 graus com <span class="wzw-tk-tag">&lt;code&gt;</span>rotateY<span class="wzw-tk-tag">&lt;/code&gt;</span>:</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;cena-card&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-3d&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">&lt;!-- Frente do Cartão --&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-face face-frente&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;font-size:0.75rem; font-weight:700; color:#38bdf8; text-transform:uppercase;&quot;</span><span class="wzw-tk-tag">&gt;</span>Módulo 05<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;h3&gt;</span>CSS3 Avançado<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;p&gt;</span>Transformações espaciais 2D e 3D aceleradas pela placa gráfica. Passe o mouse para ver o verso!<span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin-top:auto; font-size:0.8rem; color:#64748b;&quot;</span><span class="wzw-tk-tag">&gt;</span>🔄 Passe o mouse para girar<span class="wzw-tk-tag">&lt;/span&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">      <span class="wzw-tk-comment">&lt;!-- Verso do Cartão --&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-face face-verso&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;h3&gt;</span>Ementa Completa<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;p&gt;</span>✓ Animações com keyframes<span class="wzw-tk-tag">&lt;br&gt;</span>✓ Transições suaves<span class="wzw-tk-tag">&lt;br&gt;</span>✓ CSS Variables e Dark Mode<span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-matricular&quot;</span><span class="wzw-tk-tag">&gt;</span>Iniciar Lição 43 →<span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Transformações 3D CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 40px;
      display: flex;
      flex-direction: column;
      align-items: center;
      margin: 0;
    }

    /* 1. O CONTÊINER COM PERSPECTIVA 3D */
    .cena-card {
      width: 320px;
      height: 400px;
      perspective: 1000px; /* Profundidade de câmera */
      margin-top: 20px;
    }

    /* 2. O CARTÃO QUE GIRA */
    .card-3d {
      width: 100%;
      height: 100%;
      position: relative;
      transform-style: preserve-3d; /* Preserva o espaço tridimensional dos filhos */
      transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
      cursor: pointer;
    }

    .cena-card:hover .card-3d {
      transform: rotateY(180deg); /* Gira 180 graus na horizontal */
    }

    /* 3. AS FACES (FRENTE E VERSO) */
    .card-face {
      position: absolute;
      inset: 0;
      border-radius: 16px;
      padding: 28px;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      justify-content: center;
      backface-visibility: hidden; /* OCULTA O VERSO QUANDO DE COSTAS! */
      box-shadow: 0 10px 30px rgba(0,0,0,0.4);
      border: 1px solid #334155;
    }

    /* FACE FRONTAL */
    .face-frente {
      background: linear-gradient(135deg, #1e293b, #0f172a);
      border-color: #38bdf8;
    }

    .face-frente h3 { margin: 0 0 10px 0; color: #38bdf8; font-size: 1.4rem; }
    .face-frente p { color: #94a3b8; font-size: 0.9rem; line-height: 1.5; }

    /* FACE TRASEIRA */
    .face-verso {
      background: linear-gradient(135deg, #2563eb, #1d4ed8);
      transform: rotateY(180deg); /* Já nasce virada de costas */
      text-align: center;
      align-items: center;
    }

    .face-verso h3 { margin: 0 0 12px 0; color: #fff; }
    .face-verso p { color: #bfdbfe; font-size: 0.85rem; margin-bottom: 20px; }

    .btn-matricular {
      background: #fff;
      color: #1d4ed8;
      border: none;
      padding: 12px 24px;
      border-radius: 8px;
      font-weight: 700;
      cursor: pointer;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h2 style=&quot;color:#f1f5f9; margin-top:0;&quot;&gt;Card Flip 3D com Aceleração por GPU&lt;/h2&gt;
  &lt;p style=&quot;color:#94a3b8; font-size:0.9rem;&quot;&gt;
    Passe o cursor sobre o cartão para testemunhar o giro tridimensional em 180 graus com &lt;code&gt;rotateY&lt;/code&gt;:
  &lt;/p&gt;

  &lt;div class=&quot;cena-card&quot;&gt;
    &lt;div class=&quot;card-3d&quot;&gt;
      &lt;!-- Frente do Cartão --&gt;
      &lt;div class=&quot;card-face face-frente&quot;&gt;
        &lt;span style=&quot;font-size:0.75rem; font-weight:700; color:#38bdf8; text-transform:uppercase;&quot;&gt;Módulo 05&lt;/span&gt;
        &lt;h3&gt;CSS3 Avançado&lt;/h3&gt;
        &lt;p&gt;Transformações espaciais 2D e 3D aceleradas pela placa gráfica. Passe o mouse para ver o verso!&lt;/p&gt;
        &lt;span style=&quot;margin-top:auto; font-size:0.8rem; color:#64748b;&quot;&gt;🔄 Passe o mouse para girar&lt;/span&gt;
      &lt;/div&gt;

      &lt;!-- Verso do Cartão --&gt;
      &lt;div class=&quot;card-face face-verso&quot;&gt;
        &lt;h3&gt;Ementa Completa&lt;/h3&gt;
        &lt;p&gt;✓ Animações com keyframes&lt;br&gt;✓ Transições suaves&lt;br&gt;✓ CSS Variables e Dark Mode&lt;/p&gt;
        &lt;button class=&quot;btn-matricular&quot;&gt;Iniciar Lição 43 →&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e experimente alterar o valor de <code>perspective: 1000px</code> para <code>200px</code> ou <code>3000px</code> para perceber como a profundidade visual da cena 3D se transforma:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>7. Resumo e Próximos Passos</h2>
<ul>
<li><code>transform</code> opera na camada <strong>Composite</strong> da GPU, mantendo 60fps sem provocar recálculos de Layout (Reflow).</li>
<li><code>translate(x, y)</code> move elementos sem perturbar a geometria dos vizinhos.</li>
<li><code>scale()</code> e <code>rotate()</code> redimensionam e giram a caixa com aceleração gráfica.</li>
<li><code>transform-origin</code> define o ponto pivô de ancoragem da transformação.</li>
<li>As propriedades individuais modernas (<code>translate</code>, <code>rotate</code>, <code>scale</code>) eliminam a necessidade de encadeamentos longos.</li>
<li>Efeitos 3D realistas dependem de <strong><code>perspective</code></strong> no contêiner pai, <strong><code>transform-style: preserve-3d</code></strong> no elemento rotativo e <strong><code>backface-visibility: hidden</code></strong> nas faces.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> Agora que você sabe mover e transformar elementos no espaço, como fazer essas mudanças acontecerem de forma suave, natural e cinematográfica, sem saltos bruscos? Na <strong>Lição 43</strong>, dominaremos as <strong>Transições Suaves no CSS (transition, timing-functions e cubic-bezier)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/transformacoes-css-translate-rotate-scale/">Transformações 2D e 3D Modernas no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/transformacoes-css-translate-rotate-scale/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pseudo-elementos no CSS: ::before e ::after &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/pseudo-elementos-before-after/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/pseudo-elementos-before-after/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:30:34 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[after css]]></category>
		<category><![CDATA[before css]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[marker css]]></category>
		<category><![CDATA[propriedade content]]></category>
		<category><![CDATA[pseudo-elementos]]></category>
		<category><![CDATA[selection css]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29461</guid>

					<description><![CDATA[<p>Uma das marcas distintivas de um desenvolvedor front-end de alto nível é a capacidade de manter o código HTML 100% semântico e enxuto. No passado, para criar uma fita de destaque em um cartão, um sublinhado elegante que se expande ao passar o mouse ou uma bolinha verde pulsante de status, desenvolvedores enchiam o documento [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-elementos-before-after/">Pseudo-elementos no CSS: ::before e ::after | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Uma das marcas distintivas de um desenvolvedor front-end de alto nível é a capacidade de manter o código HTML 100% semântico e enxuto. No passado, para criar uma fita de destaque em um cartão, um sublinhado elegante que se expande ao passar o mouse ou uma bolinha verde pulsante de status, desenvolvedores enchiam o documento de tags vazias como <code>&lt;span class="circulo"&gt;&lt;/span&gt;</code>. Os <strong>Pseudo-elementos</strong> (identificados pelo duplo dois-pontos <code>::</code>) revolucionaram esse cenário: eles criam elementos visuais virtuais diretamente na árvore de renderização do CSS, sem poluir uma única linha do seu HTML!
</p>
<h2>1. A Sintaxe Padronizada: Por que Dois Dois-Pontos (<code>::</code>)?</h2>
<p>
  Nas especificações antigas de CSS1 e CSS2, tanto pseudo-classes quanto pseudo-elementos usavam um único caractere <code>:</code>.
</p>
<p>
  A partir do CSS3, a W3C estabeleceu uma fronteira conceitual definitiva:
</p>
<ul>
<li><strong>Pseudo-classe (<code>:</code> com um dois-pontos):</strong> Mira um <em>estado dinâmico</em> do elemento real (ex.: <code>:hover</code>, <code>:focus</code>, <code>:checked</code>).</li>
<li><strong>Pseudo-elemento (<code>::</code> com dois dois-pontos):</strong> Cria um <em>elemento visual virtual</em> ou estiliza uma subparte interna (ex.: <code>::before</code>, <code>::after</code>, <code>::marker</code>, <code>::selection</code>).</li>
</ul>
<div class="wzw-callout wzw-callout-info">
<p><strong>Dica de Boas Práticas:</strong> Os navegadores modernos ainda aceitam a sintaxe antiga de um ponto (<code>:before</code>) por razões de retrocompatibilidade com a década de 1990. No entanto, em código moderno profissional e acessível, use SEMPRE o padrão moderno de dois dois-pontos (<strong><code>::before</code></strong> e <strong><code>::after</code></strong>).</p>
</div>
<h2>2. Onde Nascem <code>::before</code> e <code>::after</code>?</h2>
<p>
  Um dos equívocos mais comuns entre iniciantes é acreditar que <code>::before</code> fica localizado <em>do lado de fora, antes da tag</em>, e que <code>::after</code> fica <em>do lado de fora, depois da tag</em>. Isso é falso!
</p>
<p>
  No modelo de renderização do navegador, os pseudo-elementos são inseridos <strong>INTERNAMENTE</strong> dentro do elemento selecionado:
</p>
<ul>
<li><strong><code>::before</code>:</strong> É renderizado como o <strong>primeiríssimo filho interno</strong> da caixa, logo antes do texto ou de qualquer outro elemento filho.</li>
<li><strong><code>::after</code>:</strong> É renderizado como o <strong>último filho interno</strong> da caixa, logo após todo o conteúdo do elemento.</li>
</ul>
<div class="wzw-callout wzw-callout-warning">
<p><strong>Atenção aos Elementos Vazios (Void Elements):</strong> Como <code>::before</code> e <code>::after</code> são filhos internos, eles <strong>NÃO FUNCIONAM</strong> em tags HTML auto-fechadas que não aceitam conteúdo filho no DOM, como <code>&lt;img&gt;</code>, <code>&lt;input&gt;</code>, <code>&lt;br&gt;</code> e <code>&lt;hr&gt;</code>!</p>
</div>
<h2>3. A Regra de Ouro: A Propriedade <code>content</code></h2>
<p>
  Existe uma lei inegociável para <code>::before</code> e <code>::after</code>: <strong>sem a propriedade <code>content</code>, o pseudo-elemento simplesmente NÃO EXISTE</strong> e o navegador não desenha absolutamente nada na tela!
</p>
<p>
  Mesmo que você queira criar um quadrado geométrico ou uma linha colorida sem nenhum texto dentro, você <strong>deve</strong> declarar <code>content: "";</code> (aspas vazias):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-43058" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">10 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-43058', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-43058', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Cria um indicador visual de status verde antes do texto */</span></span>
<span class="wzw-code-line">.status-online::before {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">content</span>: <span class="wzw-tk-str">&quot;&quot;</span>;            /* OBRIGATÓRIO: Sem isso, o elemento não nasce! */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">display</span>: inline-block;  /* Por padrão, pseudo-elementos são inline */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">width</span>: <span class="wzw-tk-num">10px</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">height</span>: <span class="wzw-tk-num">10px</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: <span class="wzw-tk-num">#10b981</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-radius</span>: 50%;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">margin-right</span>: <span class="wzw-tk-num">8px</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Cria um indicador visual de status verde antes do texto */
.status-online::before {
  content: &quot;&quot;;            /* OBRIGATÓRIO: Sem isso, o elemento não nasce! */
  display: inline-block;  /* Por padrão, pseudo-elementos são inline */
  width: 10px;
  height: 10px;
  background-color: #10b981;
  border-radius: 50%;
  margin-right: 8px;
}</textarea>
        </div>
    </div>
    
</div>
<h3>O que a Propriedade <code>content</code> Pode Conter?</h3>
<ul>
<li><strong>Aspas Vazias (<code>content: "";</code>):</strong> O padrão para formas geométricas decorativas, máscaras e overlays.</li>
<li><strong>Texto Fixo ou Emojis:</strong> <code>content: "★ ";</code> ou <code>content: " • ";</code>.</li>
<li><strong>Leitura Dinâmica de Atributos:</strong> <code>content: attr(data-tooltip);</code> permite ler valores de atributos HTML para criar tooltips 100% nativos sem JavaScript!</li>
</ul>
<h2>4. Casos de Uso Clássicos na Indústria</h2>
<h3>1. Sublinhado Animado no Hover (Underline Expandível)</h3>
<p>
  Em vez de usar o velho e rígido <code>text-decoration: underline</code>, criamos uma linha fina com <code>::after</code> que se expande do centro para as pontas suavemente:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-12974" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">23 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-12974', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-12974', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.link-magico {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: relative;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">text-decoration</span>: none;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.link-magico::after {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">content</span>: <span class="wzw-tk-str">&quot;&quot;</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: absolute;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">left</span>: 0;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">bottom</span>: -<span class="wzw-tk-num">4px</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">width</span>: 100%;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">height</span>: <span class="wzw-tk-num">2px</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: scaleX(0); /* Inicialmente invisível (comprimido a zero) */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transition</span>: transform <span class="wzw-tk-num">0.3s</span> ease;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform-origin</span>: right;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.link-magico<span class="wzw-tk-kw">:hover</span>::after {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform</span>: scaleX(1); /* Expande para 100% da largura no hover */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">transform-origin</span>: left;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.link-magico {
  position: relative;
  text-decoration: none;
  color: #38bdf8;
}

.link-magico::after {
  content: &quot;&quot;;
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 2px;
  background: #38bdf8;
  transform: scaleX(0); /* Inicialmente invisível (comprimido a zero) */
  transition: transform 0.3s ease;
  transform-origin: right;
}

.link-magico:hover::after {
  transform: scaleX(1); /* Expande para 100% da largura no hover */
  transform-origin: left;
}</textarea>
        </div>
    </div>
    
</div>
<h3>2. Máscara Escura sobre Imagens (Overlay)</h3>
<p>
  Para escurecer um cartão com imagem de fundo e garantir que o texto branco seja sempre legível (contraste WCAG):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-26108" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">17 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-26108', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-26108', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line">.card-com-overlay {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: relative;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">overflow</span>: hidden;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.card-com-overlay::before {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">content</span>: <span class="wzw-tk-str">&quot;&quot;</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: absolute;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">inset</span>: 0; /* Preenche 100% da área do card */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background</span>: rgba(0, 0, 0, 0.55); /* Máscara semitransparente */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">z-index</span>: 1;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">.card-conteudo {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">position</span>: relative;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">z-index</span>: 2; /* Fica acima da máscara */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>.card-com-overlay {
  position: relative;
  overflow: hidden;
}

.card-com-overlay::before {
  content: &quot;&quot;;
  position: absolute;
  inset: 0; /* Preenche 100% da área do card */
  background: rgba(0, 0, 0, 0.55); /* Máscara semitransparente */
  z-index: 1;
}

.card-conteudo {
  position: relative;
  z-index: 2; /* Fica acima da máscara */
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. Outros Pseudo-elementos Modernos Essenciais</h2>
<h3><code>::selection</code> — A Identidade Visual do Texto Selecionado</h3>
<p>
  Quando o usuário arrasta o mouse para copiar um trecho do seu site, você pode trocar o azul genérico do sistema pela cor da marca da sua empresa:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-13830" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-13830', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-13830', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Personaliza o grifo de texto do site inteiro */</span></span>
<span class="wzw-code-line">::selection {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#0b0f19</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Personaliza o grifo de texto do site inteiro */
::selection {
  background-color: #38bdf8;
  color: #0b0f19;
}</textarea>
        </div>
    </div>
    
</div>
<h3><code>::marker</code> — Marcadores de Lista sem Gambiarras</h3>
<p>
  No passado, mudar a cor da bolinha de uma lista <code>&lt;li&gt;</code> exigia remover o estilo nativo e reconstruí-lo do zero. Hoje usamos <strong><code>::marker</code></strong>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-23802" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-23802', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-23802', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-attr">li</span>::marker {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#10b981</span>; /* A bolinha ou número fica verde sem afetar o texto! */</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">font-size</span>: <span class="wzw-tk-num">1.1rem</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>li::marker {
  color: #10b981; /* A bolinha ou número fica verde sem afetar o texto! */
  font-size: 1.1rem;
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Acessibilidade e Leitores de Tela (WCAG 2.2)</h2>
<div class="wzw-callout wzw-callout-warning">
<p><strong>Atenção com Textos em Pseudo-elementos:</strong> Leitores de tela modernos (como VoiceOver e NVDA) <strong>leem em voz alta</strong> o texto colocado dentro de <code>content: "..."</code>! Portanto, nunca insira textos críticos apenas no CSS. Se o pseudo-elemento for puramente decorativo, use <code>content: ""</code> para evitar poluir a leitura de usuários cegos.</p>
</div>
<h2>7. Laboratório Prático: Tooltip Nativo e Efeitos de Pseudo-elementos</h2>
<p>
  No código interativo abaixo, construímos um componente que combina <strong>tooltip nativo via <code>attr()</code></strong>, bolinha de status pulsante, marcador de lista customizado e grifo de texto personalizado:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-70231" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">111 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-70231', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-70231', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Pseudo-elementos CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. SELEÇÃO DE TEXTO PERSONALIZADA (::selection) */</span></span>
<span class="wzw-code-line">    ::selection {</span>
<span class="wzw-code-line">      background: #f59e0b;</span>
<span class="wzw-code-line">      color: #000;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. CARD COM STATUS ONLINE (::before) */</span></span>
<span class="wzw-code-line">    .card-usuario {</span>
<span class="wzw-code-line">      max-width: 440px;</span>
<span class="wzw-code-line">      background: #1e293b;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">      border-radius: 14px;</span>
<span class="wzw-code-line">      padding: 24px;</span>
<span class="wzw-code-line">      margin-bottom: 30px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .status-badge {</span>
<span class="wzw-code-line">      display: inline-flex;</span>
<span class="wzw-code-line">      align-items: center;</span>
<span class="wzw-code-line">      font-size: 0.85rem;</span>
<span class="wzw-code-line">      font-weight: 600;</span>
<span class="wzw-code-line">      color: #10b981;</span>
<span class="wzw-code-line">      margin-bottom: 12px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* Bolinha verde desenhada puramente no CSS */</span></span>
<span class="wzw-code-line">    .status-badge::before {</span>
<span class="wzw-code-line">      content: &quot;&quot;;</span>
<span class="wzw-code-line">      width: 8px;</span>
<span class="wzw-code-line">      height: 8px;</span>
<span class="wzw-code-line">      background: #10b981;</span>
<span class="wzw-code-line">      border-radius: 50%;</span>
<span class="wzw-code-line">      margin-right: 8px;</span>
<span class="wzw-code-line">      box-shadow: 0 0 8px #10b981;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. TOOLTIP NATIVO SEM JS (::after com attr) */</span></span>
<span class="wzw-code-line">    .tooltip-link {</span>
<span class="wzw-code-line">      position: relative;</span>
<span class="wzw-code-line">      color: #38bdf8;</span>
<span class="wzw-code-line">      text-decoration: underline;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">      display: inline-block;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .tooltip-link::after {</span>
<span class="wzw-code-line">      content: attr(data-tooltip); /* Lê o texto do atributo HTML! */</span>
<span class="wzw-code-line">      position: absolute;</span>
<span class="wzw-code-line">      bottom: 125%;</span>
<span class="wzw-code-line">      left: 50%;</span>
<span class="wzw-code-line">      transform: translateX(-50%) scale(0.9);</span>
<span class="wzw-code-line">      background: #020617;</span>
<span class="wzw-code-line">      color: #fff;</span>
<span class="wzw-code-line">      font-size: 0.75rem;</span>
<span class="wzw-code-line">      padding: 6px 12px;</span>
<span class="wzw-code-line">      border-radius: 6px;</span>
<span class="wzw-code-line">      white-space: nowrap;</span>
<span class="wzw-code-line">      pointer-events: none;</span>
<span class="wzw-code-line">      opacity: 0;</span>
<span class="wzw-code-line">      transition: opacity 0.2s ease, transform 0.2s ease;</span>
<span class="wzw-code-line">      box-shadow: 0 4px 12px rgba(0,0,0,0.5);</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .tooltip-link:hover::after {</span>
<span class="wzw-code-line">      opacity: 1;</span>
<span class="wzw-code-line">      transform: translateX(-50%) scale(1);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 4. MARCADOR DE LISTA CUSTOMIZADO (::marker) */</span></span>
<span class="wzw-code-line">    ul.lista-recursos li::marker {</span>
<span class="wzw-code-line">      color: #38bdf8;</span>
<span class="wzw-code-line">      font-size: 1.2rem;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h2</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#f1f5f9; margin-top:0;&quot;</span><span class="wzw-tk-tag">&gt;</span>Demonstração de Pseudo-elementos<span class="wzw-tk-tag">&lt;/h2&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    Selecione qualquer trecho deste texto com o mouse para ver o <span class="wzw-tk-tag">&lt;code&gt;</span>::selection<span class="wzw-tk-tag">&lt;/code&gt;</span> amarelo em ação!</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;card-usuario&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;status-badge&quot;</span><span class="wzw-tk-tag">&gt;</span>Servidor Ativo<span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;h3</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin:0 0 10px 0;&quot;</span><span class="wzw-tk-tag">&gt;</span>Plataforma WebZoneWare<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem; line-height:1.6;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      Passe o mouse sobre esta <span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;tooltip-link&quot;</span> <span class="wzw-tk-attr">data-tooltip</span>=<span class="wzw-tk-str">&quot;⚡ Dica de Engenharia: 100% puro CSS!&quot;</span><span class="wzw-tk-tag">&gt;</span>palavra com tooltip<span class="wzw-tk-tag">&lt;/span&gt;</span> para ver o texto flutuante gerado via <span class="wzw-tk-tag">&lt;code&gt;</span>content: attr()<span class="wzw-tk-tag">&lt;/code&gt;</span>.</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;ul</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;lista-recursos&quot;</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#cbd5e1; font-size:0.9rem;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;li&gt;</span>CSS Grid 2D Completo<span class="wzw-tk-tag">&lt;/li&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;li&gt;</span>Flexbox Unidimensional<span class="wzw-tk-tag">&lt;/li&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;li&gt;</span>Acessibilidade WCAG 2.2<span class="wzw-tk-tag">&lt;/li&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/ul&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Pseudo-elementos CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 40px;
      margin: 0;
    }

    /* 1. SELEÇÃO DE TEXTO PERSONALIZADA (::selection) */
    ::selection {
      background: #f59e0b;
      color: #000;
    }

    /* 2. CARD COM STATUS ONLINE (::before) */
    .card-usuario {
      max-width: 440px;
      background: #1e293b;
      border: 1px solid #334155;
      border-radius: 14px;
      padding: 24px;
      margin-bottom: 30px;
    }

    .status-badge {
      display: inline-flex;
      align-items: center;
      font-size: 0.85rem;
      font-weight: 600;
      color: #10b981;
      margin-bottom: 12px;
    }

    /* Bolinha verde desenhada puramente no CSS */
    .status-badge::before {
      content: &quot;&quot;;
      width: 8px;
      height: 8px;
      background: #10b981;
      border-radius: 50%;
      margin-right: 8px;
      box-shadow: 0 0 8px #10b981;
    }

    /* 3. TOOLTIP NATIVO SEM JS (::after com attr) */
    .tooltip-link {
      position: relative;
      color: #38bdf8;
      text-decoration: underline;
      cursor: pointer;
      display: inline-block;
    }

    .tooltip-link::after {
      content: attr(data-tooltip); /* Lê o texto do atributo HTML! */
      position: absolute;
      bottom: 125%;
      left: 50%;
      transform: translateX(-50%) scale(0.9);
      background: #020617;
      color: #fff;
      font-size: 0.75rem;
      padding: 6px 12px;
      border-radius: 6px;
      white-space: nowrap;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.2s ease, transform 0.2s ease;
      box-shadow: 0 4px 12px rgba(0,0,0,0.5);
      border: 1px solid #334155;
    }

    .tooltip-link:hover::after {
      opacity: 1;
      transform: translateX(-50%) scale(1);
    }

    /* 4. MARCADOR DE LISTA CUSTOMIZADO (::marker) */
    ul.lista-recursos li::marker {
      color: #38bdf8;
      font-size: 1.2rem;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h2 style=&quot;color:#f1f5f9; margin-top:0;&quot;&gt;Demonstração de Pseudo-elementos&lt;/h2&gt;
  &lt;p style=&quot;color:#94a3b8; font-size:0.9rem;&quot;&gt;
    Selecione qualquer trecho deste texto com o mouse para ver o &lt;code&gt;::selection&lt;/code&gt; amarelo em ação!
  &lt;/p&gt;

  &lt;div class=&quot;card-usuario&quot;&gt;
    &lt;div class=&quot;status-badge&quot;&gt;Servidor Ativo&lt;/div&gt;
    &lt;h3 style=&quot;margin:0 0 10px 0;&quot;&gt;Plataforma WebZoneWare&lt;/h3&gt;
    &lt;p style=&quot;color:#94a3b8; font-size:0.9rem; line-height:1.6;&quot;&gt;
      Passe o mouse sobre esta &lt;span class=&quot;tooltip-link&quot; data-tooltip=&quot;⚡ Dica de Engenharia: 100% puro CSS!&quot;&gt;palavra com tooltip&lt;/span&gt; para ver o texto flutuante gerado via &lt;code&gt;content: attr()&lt;/code&gt;.
    &lt;/p&gt;

    &lt;ul class=&quot;lista-recursos&quot; style=&quot;color:#cbd5e1; font-size:0.9rem;&quot;&gt;
      &lt;li&gt;CSS Grid 2D Completo&lt;/li&gt;
      &lt;li&gt;Flexbox Unidimensional&lt;/li&gt;
      &lt;li&gt;Acessibilidade WCAG 2.2&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste passar o cursor sobre a palavra com tooltip e selecionar o texto para comprovar a elegância dos pseudo-elementos:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>8. Resumo e Próximos Passos</h2>
<ul>
<li>Pseudo-elementos (usando <code>::</code>) criam nós virtuais ou estilizam subpartes sem alterar o código HTML.</li>
<li><code>::before</code> e <code>::after</code> são inseridos como o primeiro e o último filho <strong>interno</strong> da caixa selecionada.</li>
<li>A propriedade <code>content: ""</code> é estritamente obrigatória; sem ela, o pseudo-elemento não é renderizado.</li>
<li><code>content: attr(nome)</code> permite ler dados de atributos HTML dinamicamente (como data-tooltips).</li>
<li><code>::marker</code> estiliza as bolinhas e numerações de listas de forma nativa e limpa.</li>
<li><code>::selection</code> customiza as cores do texto grifado pelo cursor do usuário.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Próximo Passo:</strong> Agora que você pode criar elementos visuais no CSS, como movê-los, girá-los, esticá-los e criar sensações de profundidade em 3D? Na <strong>Lição 42</strong>, desvendaremos as <strong>Transformações 2D e 3D no CSS (translate, rotate, scale, skew e perspective)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-elementos-before-after/">Pseudo-elementos no CSS: ::before e ::after | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/pseudo-elementos-before-after/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pseudo-classes Estruturais: nth-child no CSS &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/pseudo-classes-estruturais-nth-child/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/pseudo-classes-estruturais-nth-child/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:23:53 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[nth-child]]></category>
		<category><![CDATA[nth-of-type]]></category>
		<category><![CDATA[pseudo-classes estruturais]]></category>
		<category><![CDATA[seletor empty]]></category>
		<category><![CDATA[seletor not]]></category>
		<category><![CDATA[tabelas zebradas]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29459</guid>

					<description><![CDATA[<p>Chegamos ao grande encerramento do Módulo 4! Em aplicações web corporativas, os dados exibidos na tela são quase sempre dinâmicos: listas de clientes, tabelas de vendas ou feeds de postagens gerados por bancos de dados. Colocar classes manuais em cada linha HTML (como .item-1, .item-2, .item-zebrado) seria inviável. As Pseudo-classes Estruturais capacitam o CSS a [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-classes-estruturais-nth-child/">Pseudo-classes Estruturais: nth-child no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Chegamos ao grande encerramento do Módulo 4! Em aplicações web corporativas, os dados exibidos na tela são quase sempre dinâmicos: listas de clientes, tabelas de vendas ou feeds de postagens gerados por bancos de dados. Colocar classes manuais em cada linha HTML (como <code>.item-1</code>, <code>.item-2</code>, <code>.item-zebrado</code>) seria inviável. As <strong>Pseudo-classes Estruturais</strong> capacitam o CSS a inspecionar a árvore do DOM e aplicar estilos cirúrgicos com base na posição ordinal, parentesco ou fórmulas matemáticas elegantes. Nesta lição, você dominará o poder de <code>:nth-child</code>, a fórmula <code>An + B</code>, a distinção para <code>:nth-of-type</code>, o seletor de negação <code>:not()</code> e o autolimpante <code>:empty</code>.
</p>
<h2>1. Os Guardiões das Extremidades: <code>:first-child</code>, <code>:last-child</code> e <code>:only-child</code></h2>
<p>
  Antes de mergulhar na matemática avançada, o CSS nos oferece seletores semânticos diretos para os limites de um contêiner:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-95597" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">16 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-95597', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-95597', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Seleciona o primeiro item de uma lista */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">li</span>:first-child {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">font-weight</span>: 700;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* O uso mais clássico da web: remove a borda divisória do último item */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">li</span>:last-child {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-bottom</span>: none;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* Estiliza um elemento se ele for o ÚNICO filho dentro do seu pai */</span></span>
<span class="wzw-code-line">.alerta:only-child {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">margin</span>: 0 auto;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">text-align</span>: center;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Seleciona o primeiro item de uma lista */
li:first-child {
  font-weight: 700;
  color: #38bdf8;
}

/* O uso mais clássico da web: remove a borda divisória do último item */
li:last-child {
  border-bottom: none;
}

/* Estiliza um elemento se ele for o ÚNICO filho dentro do seu pai */
.alerta:only-child {
  margin: 0 auto;
  text-align: center;
}</textarea>
        </div>
    </div>
    
</div>
<h2>2. A Matemática Sagrada da Fórmula <code>:nth-child(An + B)</code></h2>
<p>
  A pseudo-classe <strong><code>:nth-child()</code></strong> aceita palavras-chave simples ou uma expressão algébrica linear <code>An + B</code> para varrer elementos em intervalos programados:
</p>
<h3>1. Palavras-Chave Rápidas (Listas e Tabelas Zebradas)</h3>
<ul>
<li><strong><code>:nth-child(odd)</code>:</strong> Seleciona todos os filhos em posições ímpares (1, 3, 5, 7&#8230;).</li>
<li><strong><code>:nth-child(even)</code>:</strong> Seleciona todos os filhos em posições pares (2, 4, 6, 8&#8230;). É a fórmula canônica para zebrar tabelas financeiras!</li>
</ul>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-56611" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-56611', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-56611', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Linhas pares com fundo sutilmente destacado */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">tr</span>:nth-child(even) {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">background-color</span>: rgba(255, 255, 255, 0.03);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Linhas pares com fundo sutilmente destacado */
tr:nth-child(even) {
  background-color: rgba(255, 255, 255, 0.03);
}</textarea>
        </div>
    </div>
    
</div>
<h3>2. A Mecânica da Equação <code>An + B</code></h3>
<p>
  Como o navegador computa essa fórmula? Ele executa um laço onde <strong><code>n</code> começa em zero (0)</strong> e incrementa sucessivamente (0, 1, 2, 3, 4&#8230;):
</p>
<ul>
<li><strong><code>A</code></strong> representa a frequência ou intervalo de repetição (o &#8220;passo&#8221;).</li>
<li><strong><code>B</code></strong> representa o ponto de partida inicial (o &#8220;deslocamento&#8221; ou offset).</li>
</ul>
<div class="wzw-table-responsive">
<table class="wzw-table">
<thead>
<tr>
<th>Expressão CSS</th>
<th>Valores de <code>n</code> Calculados</th>
<th>Índices Selecionados no HTML</th>
<th>Aplicação Prática</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>:nth-child(3)</code></td>
<td>Sem variável</td>
<td>Apenas o <strong>3º elemento</strong></td>
<td>Destacar um card de plano específico.</td>
</tr>
<tr>
<td><code>:nth-child(3n)</code></td>
<td>3(1), 3(2), 3(3)&#8230;</td>
<td><strong>3, 6, 9, 12, 15&#8230;</strong></td>
<td>Fim de linha em grades de 3 colunas.</td>
</tr>
<tr>
<td><code>:nth-child(3n + 1)</code></td>
<td>3(0)+1, 3(1)+1, 3(2)+1&#8230;</td>
<td><strong>1, 4, 7, 10, 13&#8230;</strong></td>
<td>Início de linha em grades de 3 colunas.</td>
</tr>
<tr>
<td><code>:nth-child(n + 5)</code></td>
<td>0+5, 1+5, 2+5&#8230;</td>
<td><strong>5, 6, 7, 8&#8230; em diante</strong></td>
<td>Estilizar itens excedentes (<em>&#8220;ver mais&#8221;</em>).</td>
</tr>
<tr>
<td><strong><code>:nth-child(-n + 3)</code></strong></td>
<td>-0+3, -1+3, -2+3</td>
<td><strong>1, 2 e 3 apenas!</strong></td>
<td><strong>O Seletor de Pódio:</strong> destaca os 3 primeiros colocados de um ranking!</td>
</tr>
</tbody>
</table>
</div>
<h2>3. O Duelo Crucial: <code>:nth-child</code> vs. <code>:nth-of-type</code></h2>
<p>
  Existe uma armadilha clássica que derruba milhares de desenvolvedores no CSS. Observe este código HTML:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-95530" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-95530', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-95530', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;artigo&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h1&gt;</span>Título Principal<span class="wzw-tk-tag">&lt;/h1&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p&gt;</span>Primeiro parágrafo.<span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p&gt;</span>Segundo parágrafo.<span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/div&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;div class=&quot;artigo&quot;&gt;
  &lt;h1&gt;Título Principal&lt;/h1&gt;
  &lt;p&gt;Primeiro parágrafo.&lt;/p&gt;
  &lt;p&gt;Segundo parágrafo.&lt;/p&gt;
&lt;/div&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Se você escrever <code>p:nth-child(1)</code>, <strong>nada será estilizado</strong>! Por quê? Porque aos olhos do navegador, o filho de índice 1 dentro da div é o <code>&lt;h1&gt;</code>. Como o filho 1 não é um <code>&lt;p&gt;</code>, a regra falha.
</p>
<div class="wzw-callout wzw-callout-warning">
<p><strong>A Diferença Arquitetural:</strong></p>
<ul>
<li><strong><code>:nth-child</code>:</strong> Conta <em>todos os elementos irmãos indiscriminadamente</em>, independentemente da tag.</li>
<li><strong><code>:nth-of-type</code>:</strong> Filtra a contagem <em>exclusivamente entre irmãos da mesma tag HTML</em>! No exemplo acima, <code>p:nth-of-type(1)</code> selecionará perfeitamente o <code>Primeiro parágrafo</code>.</li>
</ul>
</div>
<h3>Bônus Moderno: A Sintaxe <code>:nth-child(An + B of .classe)</code></h3>
<p>
  O CSS Selectors Level 4 trouxe uma das adições mais pedidas da história: a capacidade de contar filhos que correspondam a uma <strong>classe específica</strong> usando a palavra-chave <code>of</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-15852" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-15852', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-15852', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Seleciona o 2º item que possui a classe .ativo, ignorando os demais! */</span></span>
<span class="wzw-code-line">.item:nth-child(2 of .ativo) {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border</span>: <span class="wzw-tk-num">2px</span> solid <span class="wzw-tk-num">#10b981</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Seleciona o 2º item que possui a classe .ativo, ignorando os demais! */
.item:nth-child(2 of .ativo) {
  border: 2px solid #10b981;
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. A Pseudo-classe de Negação: <code>:not()</code></h2>
<p>
  Em vez de aplicar um estilo a todos os elementos e depois criar uma classe especial para desfazê-lo, a pseudo-classe <strong><code>:not()</code></strong> permite excluir alvos diretamente na regra:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-47300" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">10 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-47300', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-47300', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Adiciona separador em todos os itens, EXCETO no último */</span></span>
<span class="wzw-code-line">.lista-item:not(:last-child) {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-bottom</span>: <span class="wzw-tk-num">1px</span> solid <span class="wzw-tk-num">#334155</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">margin-bottom</span>: <span class="wzw-tk-num">12px</span>;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* Todos os botões ganham opacidade reduzida quando desativados */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">button</span>:not(:disabled)<span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">filter</span>: brightness(1.1);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Adiciona separador em todos os itens, EXCETO no último */
.lista-item:not(:last-child) {
  border-bottom: 1px solid #334155;
  margin-bottom: 12px;
}

/* Todos os botões ganham opacidade reduzida quando desativados */
button:not(:disabled):hover {
  filter: brightness(1.1);
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. A Pseudo-classe Autolimpante: <code>:empty</code></h2>
<p>
  A pseudo-classe <strong><code>:empty</code></strong> seleciona elementos que não contêm absolutamente nada em seu interior (nem elementos filhos, nem nós de texto).
</p>
<p>
  É a solução definitiva para selos e badges de notificação que devem sumir automaticamente quando o contador for zero:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-16151" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">4 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-16151', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-16151', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Se o JavaScript esvaziar o badge, ele desaparece da tela sem deixar buraco! */</span></span>
<span class="wzw-code-line">.badge-contador:empty {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">display</span>: none;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Se o JavaScript esvaziar o badge, ele desaparece da tela sem deixar buraco! */
.badge-contador:empty {
  display: none;
}</textarea>
        </div>
    </div>
    
</div>
<h2>6. Laboratório Prático: Ranking Zebrado e Destaque de Pódio</h2>
<p>
  No exemplo abaixo, combinamos a fórmula matemática de pódio <code>:nth-child(-n + 3)</code> para destacar os 3 líderes de um ranking, zebramos as linhas com <code>:nth-child(even)</code> e usamos <code>:not(:last-child)</code> e <code>:empty</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-70170" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">121 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-70170', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-70170', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Pseudo-classes Estruturais<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 30px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .tabela-ranking {</span>
<span class="wzw-code-line">      width: 100%;</span>
<span class="wzw-code-line">      max-width: 580px;</span>
<span class="wzw-code-line">      border-collapse: collapse;</span>
<span class="wzw-code-line">      background: #1e293b;</span>
<span class="wzw-code-line">      border-radius: 12px;</span>
<span class="wzw-code-line">      overflow: hidden;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    th, td {</span>
<span class="wzw-code-line">      padding: 14px 20px;</span>
<span class="wzw-code-line">      text-align: left;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    th {</span>
<span class="wzw-code-line">      background: #0f172a;</span>
<span class="wzw-code-line">      color: #94a3b8;</span>
<span class="wzw-code-line">      font-size: 0.85rem;</span>
<span class="wzw-code-line">      text-transform: uppercase;</span>
<span class="wzw-code-line">      letter-spacing: 0.05em;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. SEPARADOR EM TODOS EXCETO O ÚLTIMO (:not(:last-child)) */</span></span>
<span class="wzw-code-line">    tbody tr:not(:last-child) td {</span>
<span class="wzw-code-line">      border-bottom: 1px solid #334155;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. LINHAS ZEBRADAS (:nth-child(even)) */</span></span>
<span class="wzw-code-line">    tbody tr:nth-child(even) {</span>
<span class="wzw-code-line">      background-color: rgba(255, 255, 255, 0.02);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. O SELETOR DE PÓDIO: TOP 3 MELHORES (:nth-child(-n + 3)) */</span></span>
<span class="wzw-code-line">    tbody tr:nth-child(-n + 3) td:first-child {</span>
<span class="wzw-code-line">      font-weight: 800;</span>
<span class="wzw-code-line">      color: #f59e0b; /* Dourado para o Top 3 */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    tbody tr:nth-child(1) td:first-child::after { content: &quot; 🥇&quot;; }</span>
<span class="wzw-code-line">    tbody tr:nth-child(2) td:first-child::after { content: &quot; 🥈&quot;; }</span>
<span class="wzw-code-line">    tbody tr:nth-child(3) td:first-child::after { content: &quot; 🥉&quot;; }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 4. BADGE AUTOLIMPANTE (:empty) */</span></span>
<span class="wzw-code-line">    .badge-trofeu:empty {</span>
<span class="wzw-code-line">      display: none;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .badge-trofeu {</span>
<span class="wzw-code-line">      background: #3b82f6;</span>
<span class="wzw-code-line">      color: #fff;</span>
<span class="wzw-code-line">      font-size: 0.75rem;</span>
<span class="wzw-code-line">      padding: 3px 8px;</span>
<span class="wzw-code-line">      border-radius: 9999px;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;h2</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#38bdf8; margin-top:0;&quot;</span><span class="wzw-tk-tag">&gt;</span>Quadro de Líderes da Web Academy<span class="wzw-tk-tag">&lt;/h2&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#94a3b8; font-size:0.9rem; margin-bottom:20px;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    Tabela estruturada matematicamente no CSS sem nenhuma classe individual por linha:</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;table</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;tabela-ranking&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;thead&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;th&gt;</span>Posição<span class="wzw-tk-tag">&lt;/th&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;th&gt;</span>Desenvolvedor<span class="wzw-tk-tag">&lt;/th&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;th&gt;</span>Pontos<span class="wzw-tk-tag">&lt;/th&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;th&gt;</span>Status<span class="wzw-tk-tag">&lt;/th&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/thead&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;tbody&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>1º<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>Carlos Mendes<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>9.840<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span><span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;badge-trofeu&quot;</span><span class="wzw-tk-tag">&gt;</span>Líder<span class="wzw-tk-tag">&lt;/span&gt;</span><span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>2º<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>Beatriz Lima<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>9.410<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span><span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;badge-trofeu&quot;</span><span class="wzw-tk-tag">&gt;</span>Pro<span class="wzw-tk-tag">&lt;/span&gt;</span><span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>3º<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>Rafael Souza<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>8.950<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span><span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;badge-trofeu&quot;</span><span class="wzw-tk-tag">&gt;</span>Pro<span class="wzw-tk-tag">&lt;/span&gt;</span><span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>4º<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>Juliana Ramos<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>7.620<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span><span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;badge-trofeu&quot;</span><span class="wzw-tk-tag">&gt;</span><span class="wzw-tk-tag">&lt;/span&gt;</span><span class="wzw-tk-comment">&lt;!-- Vazio: auto-oculta com :empty! --&gt;</span><span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;tr&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>5º<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>Diego Alves<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span>6.890<span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">        <span class="wzw-tk-tag">&lt;td&gt;</span><span class="wzw-tk-tag">&lt;span</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;badge-trofeu&quot;</span><span class="wzw-tk-tag">&gt;</span><span class="wzw-tk-tag">&lt;/span&gt;</span><span class="wzw-tk-comment">&lt;!-- Vazio: auto-oculta com :empty! --&gt;</span><span class="wzw-tk-tag">&lt;/td&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;/tr&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/tbody&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/table&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Pseudo-classes Estruturais&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 30px;
    }

    .tabela-ranking {
      width: 100%;
      max-width: 580px;
      border-collapse: collapse;
      background: #1e293b;
      border-radius: 12px;
      overflow: hidden;
      border: 1px solid #334155;
    }

    th, td {
      padding: 14px 20px;
      text-align: left;
    }

    th {
      background: #0f172a;
      color: #94a3b8;
      font-size: 0.85rem;
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }

    /* 1. SEPARADOR EM TODOS EXCETO O ÚLTIMO (:not(:last-child)) */
    tbody tr:not(:last-child) td {
      border-bottom: 1px solid #334155;
    }

    /* 2. LINHAS ZEBRADAS (:nth-child(even)) */
    tbody tr:nth-child(even) {
      background-color: rgba(255, 255, 255, 0.02);
    }

    /* 3. O SELETOR DE PÓDIO: TOP 3 MELHORES (:nth-child(-n + 3)) */
    tbody tr:nth-child(-n + 3) td:first-child {
      font-weight: 800;
      color: #f59e0b; /* Dourado para o Top 3 */
    }

    tbody tr:nth-child(1) td:first-child::after { content: &quot; 🥇&quot;; }
    tbody tr:nth-child(2) td:first-child::after { content: &quot; 🥈&quot;; }
    tbody tr:nth-child(3) td:first-child::after { content: &quot; 🥉&quot;; }

    /* 4. BADGE AUTOLIMPANTE (:empty) */
    .badge-trofeu:empty {
      display: none;
    }

    .badge-trofeu {
      background: #3b82f6;
      color: #fff;
      font-size: 0.75rem;
      padding: 3px 8px;
      border-radius: 9999px;
      font-weight: 700;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h2 style=&quot;color:#38bdf8; margin-top:0;&quot;&gt;Quadro de Líderes da Web Academy&lt;/h2&gt;
  &lt;p style=&quot;color:#94a3b8; font-size:0.9rem; margin-bottom:20px;&quot;&gt;
    Tabela estruturada matematicamente no CSS sem nenhuma classe individual por linha:
  &lt;/p&gt;

  &lt;table class=&quot;tabela-ranking&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Posição&lt;/th&gt;
        &lt;th&gt;Desenvolvedor&lt;/th&gt;
        &lt;th&gt;Pontos&lt;/th&gt;
        &lt;th&gt;Status&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;1º&lt;/td&gt;
        &lt;td&gt;Carlos Mendes&lt;/td&gt;
        &lt;td&gt;9.840&lt;/td&gt;
        &lt;td&gt;&lt;span class=&quot;badge-trofeu&quot;&gt;Líder&lt;/span&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2º&lt;/td&gt;
        &lt;td&gt;Beatriz Lima&lt;/td&gt;
        &lt;td&gt;9.410&lt;/td&gt;
        &lt;td&gt;&lt;span class=&quot;badge-trofeu&quot;&gt;Pro&lt;/span&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;3º&lt;/td&gt;
        &lt;td&gt;Rafael Souza&lt;/td&gt;
        &lt;td&gt;8.950&lt;/td&gt;
        &lt;td&gt;&lt;span class=&quot;badge-trofeu&quot;&gt;Pro&lt;/span&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;4º&lt;/td&gt;
        &lt;td&gt;Juliana Ramos&lt;/td&gt;
        &lt;td&gt;7.620&lt;/td&gt;
        &lt;td&gt;&lt;span class=&quot;badge-trofeu&quot;&gt;&lt;/span&gt;&lt;!-- Vazio: auto-oculta com :empty! --&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;5º&lt;/td&gt;
        &lt;td&gt;Diego Alves&lt;/td&gt;
        &lt;td&gt;6.890&lt;/td&gt;
        &lt;td&gt;&lt;span class=&quot;badge-trofeu&quot;&gt;&lt;/span&gt;&lt;!-- Vazio: auto-oculta com :empty! --&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste alterar a fórmula <code>:nth-child(-n + 3)</code> para <code>:nth-child(n + 4)</code> e comprove o controle cirúrgico sobre a árvore de elementos:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>7. Celebração do Módulo 4 e Boas-Vindas ao Módulo 5</h2>
<p>
  Parabéns por conquistar mais um marco extraordinário! Você concluiu <strong>100% do Módulo 4: CSS Grid &#038; Design Responsivo</strong>!
</p>
<p>
  Ao longo das últimas 10 lições, você adquiriu habilidades de nível sênior:
</p>
<ul>
<li>Compreendeu a arquitetura bidimensional (2D) do <strong>CSS Grid Layout</strong>.</li>
<li>Dominou a unidade fracionária <code>fr</code> e a grade implícita dinâmica.</li>
<li>Criou grades mágicas auto-responsivas sem media queries com <code>repeat()</code>, <code>minmax()</code> e <code>auto-fit</code>.</li>
<li>Unificou o espaçamento moderno com <code>gap</code> no Grid e no Flexbox.</li>
<li>Projetou layouts visuais em ASCII Art com <code>grid-template-areas</code>.</li>
<li>Adotou a mentalidade <strong>Mobile-First</strong> progressiva com a meta viewport.</li>
<li>Dominou a moderna <strong>Sintaxe de Faixa das Media Queries</strong> e preferências de acessibilidade.</li>
<li>Eliminou distorções e o temido CLS com <code>object-fit</code> e <code>aspect-ratio</code>.</li>
<li>E dominou integralmente as pseudo-classes dinâmicas e estruturais com matemática no DOM.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>Rumo à Reta Final:</strong> Entraremos agora no quinto e último módulo da trilha: <strong>Módulo 5: Animações, CSS Moderno &#038; Projeto Final</strong>! Na <strong>Lição 41</strong>, desvendaremos o poder criativo dos <strong>Pseudo-elementos (::before e ::after)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-classes-estruturais-nth-child/">Pseudo-classes Estruturais: nth-child no CSS | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/pseudo-classes-estruturais-nth-child/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pseudo-classes no CSS: hover, focus e visible &#124; Web Academy</title>
		<link>https://webzoneware.com/web-academy/curso-css/pseudo-classes-hover-focus-visible/</link>
					<comments>https://webzoneware.com/web-academy/curso-css/pseudo-classes-hover-focus-visible/#respond</comments>
		
		<dc:creator><![CDATA[Web-Zoneware]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 03:18:11 +0000</pubDate>
				<category><![CDATA[Curso de CSS e CSS3]]></category>
		<category><![CDATA[acessibilidade web]]></category>
		<category><![CDATA[curso css3 completo]]></category>
		<category><![CDATA[focus css]]></category>
		<category><![CDATA[focus-visible]]></category>
		<category><![CDATA[focus-within]]></category>
		<category><![CDATA[hover css]]></category>
		<category><![CDATA[pseudo-classes]]></category>
		<guid isPermaLink="false">https://webzoneware.com/?p=29457</guid>

					<description><![CDATA[<p>Uma página web onde os elementos não reagem às ações do usuário parece estática e desprovida de vida. No CSS, o que transforma um simples documento de marcação em uma interface digital tátil e responsiva são as Pseudo-classes (identificadas por um único caractere de dois pontos :). Elas permitem aplicar regras de estilo condicionadas ao [&#8230;]</p>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-classes-hover-focus-visible/">Pseudo-classes no CSS: hover, focus e visible | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wzw-lesson-lead">
  Uma página web onde os elementos não reagem às ações do usuário parece estática e desprovida de vida. No CSS, o que transforma um simples documento de marcação em uma interface digital tátil e responsiva são as <strong>Pseudo-classes</strong> (identificadas por um único caractere de dois pontos <code>:</code>). Elas permitem aplicar regras de estilo condicionadas ao estado dinâmico de um elemento: passar o cursor por cima, pressionar um botão, selecionar um campo com a tecla Tab ou validar um formulário. Nesta lição, você dominará o ciclo de vida dos links (regra LVHA), a revolução de acessibilidade do <code>:focus-visible</code> e os estados de formulário modernos.
</p>
<h2>1. O que é uma Pseudo-classe?</h2>
<p>
  Enquanto um seletor comum (como <code>.botao</code>) mira o elemento em seu estado estático padrão, uma <strong>pseudo-classe</strong> visa o elemento em uma circunstância temporal ou comportamental transitória.
</p>
<div class="wzw-callout wzw-callout-info">
<p><strong>Diferença Essencial de Sintaxe:</strong></p>
<ul>
<li><strong>Pseudo-classe (1 caractere <code>:</code>):</strong> Reflete um <em>estado dinâmico</em> do elemento inteiro (ex.: <code>:hover</code>, <code>:focus</code>, <code>:checked</code>).</li>
<li><strong>Pseudo-elemento (2 caracteres <code>::</code>):</strong> Cria ou estiliza uma <em>parte interna específica</em> do elemento (ex.: <code>::before</code>, <code>::after</code>, <code>::placeholder</code>).</li>
</ul>
</div>
<h2>2. O Ciclo de Vida dos Links e a Regra LVHA (LoVe HAte)</h2>
<p>
  Ao estilizar links de navegação, a ordem em que você escreve as regras no arquivo CSS não é opcional — ela é ditada pela cascata de especificidade do navegador. Se você inverter a ordem, um estado pode anular o outro silenciosamente.
</p>
<p>
  Para nunca errar, memorize o mnemônico mundial da web: <strong>LoVe HAte</strong> (Link, Visited, Hover, Active):
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-18920" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">21 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-18920', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-18920', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* 1. L (Link): Estado virgem (não visitado) */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">a</span>:link {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">text-decoration</span>: none;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 2. V (Visited): Link já clicado pelo usuário anteriormente */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">a</span>:visited {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#a855f7</span>;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 3. H (Hover): O ponteiro do mouse repousa sobre o link */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">a</span><span class="wzw-tk-kw">:hover</span> {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#60a5fa</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">text-decoration</span>: underline;</span>
<span class="wzw-code-line">}</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line"><span class="wzw-tk-comment">/* 4. A (Active): O exato instante em que o clique está pressionado */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">a</span>:active {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">color</span>: <span class="wzw-tk-num">#ef4444</span>;</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* 1. L (Link): Estado virgem (não visitado) */
a:link {
  color: #38bdf8;
  text-decoration: none;
}

/* 2. V (Visited): Link já clicado pelo usuário anteriormente */
a:visited {
  color: #a855f7;
}

/* 3. H (Hover): O ponteiro do mouse repousa sobre o link */
a:hover {
  color: #60a5fa;
  text-decoration: underline;
}

/* 4. A (Active): O exato instante em que o clique está pressionado */
a:active {
  color: #ef4444;
}</textarea>
        </div>
    </div>
    
</div>
<h2>3. O Duelo de Acessibilidade: <code>:focus</code> vs. <code>:focus-visible</code></h2>
<p>
  Durante décadas, designers gráficos e desenvolvedores cometeram o maior crime contra a acessibilidade na web: aplicar <code>outline: none;</code> ou <code>outline: 0;</code> para eliminar a borda azul nativa do navegador que aparecia quando um botão era clicado com o mouse.
</p>
<p>
  O efeito colateral foi devastador: <strong>milhões de pessoas com deficiência motora que navegam exclusivamente pela tecla <code>Tab</code> ficaram cegas</strong>, sem saber onde o cursor estava na tela!
</p>
<h3>A Salvação: A Pseudo-classe <code>:focus-visible</code></h3>
<p>
  A W3C resolveu esse conflito histórico criando a pseudo-classe <strong><code>:focus-visible</code></strong>:
</p>
<ul>
<li>Se o usuário clicar no botão com o mouse ou tocar na tela do celular: <strong>nenhum anel de foco é exibido</strong> (design limpo!).</li>
<li>Se o usuário navegar usando a tecla <strong><code>Tab</code> do teclado</strong> ou um leitor de tela: o navegador ativa <code>:focus-visible</code> e exibe um anel de foco destacado!</li>
</ul>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-22232" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">6 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-22232', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-22232', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* Padrão de Alta Acessibilidade e Design Impecável */</span></span>
<span class="wzw-code-line"><span class="wzw-tk-attr">button</span><span class="wzw-tk-kw">:focus</span>-visible,</span>
<span class="wzw-code-line"><span class="wzw-tk-attr">a</span><span class="wzw-tk-kw">:focus</span>-visible {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">outline</span>: <span class="wzw-tk-num">2px</span> solid <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">outline-offset</span>: <span class="wzw-tk-num">4px</span>; /* Afasta o anel das bordas arredondadas com elegância */</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* Padrão de Alta Acessibilidade e Design Impecável */
button:focus-visible,
a:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 4px; /* Afasta o anel das bordas arredondadas com elegância */
}</textarea>
        </div>
    </div>
    
</div>
<h2>4. O Efeito Cascata do <code>:focus-within</code></h2>
<p>
  A pseudo-classe <strong><code>:focus-within</code></strong> possui um comportamento genial: ela seleciona um elemento contêiner pai se <strong>qualquer elemento filho dentro dele receber foco</strong>!
</p>
<p>
  É a técnica perfeita para acender a borda de um cartão de formulário ou escurecer o fundo quando o usuário clica em qualquer campo de texto interno:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-66002" data-lang="css">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">CSS3</span>
                                <span class="wzw-ide-lines-count">5 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-66002', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-66002', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-comment">/* O cartão inteiro ganha uma borda azul e sombra quando o usuário foca no input */</span></span>
<span class="wzw-code-line">.cartao-login<span class="wzw-tk-kw">:focus</span>-within {</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">border-color</span>: <span class="wzw-tk-num">#38bdf8</span>;</span>
<span class="wzw-code-line">  <span class="wzw-tk-attr">box-shadow</span>: 0 0 <span class="wzw-tk-num">20px</span> rgba(56, 189, 248, 0.2);</span>
<span class="wzw-code-line">}</span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>/* O cartão inteiro ganha uma borda azul e sombra quando o usuário foca no input */
.cartao-login:focus-within {
  border-color: #38bdf8;
  box-shadow: 0 0 20px rgba(56, 189, 248, 0.2);
}</textarea>
        </div>
    </div>
    
</div>
<h2>5. Estados Interativos de Formulários</h2>
<p>
  O CSS moderno permite validar e reagir a campos de formulário sem precisar de uma única linha de JavaScript:
</p>
<div class="wzw-table-responsive">
<table class="wzw-table">
<thead>
<tr>
<th>Pseudo-classe</th>
<th>Condição de Ativação</th>
<th>Exemplo de Uso</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>:disabled</code></strong></td>
<td>O elemento possui o atributo <code>disabled</code>.</td>
<td>Botões cinzas sem clique (<code>cursor: not-allowed; opacity: 0.5</code>).</td>
</tr>
<tr>
<td><strong><code>:checked</code></strong></td>
<td>Caixa de seleção (checkbox) ou rádio marcada.</td>
<td>Criação de botões toggle e switches personalizados no CSS.</td>
</tr>
<tr>
<td><strong><code>:valid</code></strong></td>
<td>O valor digitado atende aos requisitos do campo.</td>
<td>Exibir uma borda verde suave quando o e-mail for válido.</td>
</tr>
<tr>
<td><strong><code>:invalid</code></strong></td>
<td>O valor viola regras de tipo, formato ou <code>required</code>.</td>
<td>Borda vermelha e aviso quando o campo estiver incorreto.</td>
</tr>
<tr>
<td><strong><code>:placeholder-shown</code></strong></td>
<td>O texto do placeholder ainda está visível.</td>
<td>Efeito de rótulo flutuante (<em>Floating Label</em>) ao digitar.</td>
</tr>
</tbody>
</table>
</div>
<h2>6. Laboratório Prático: Formulário Reativo e Foco Acessível</h2>
<p>
  No código interativo abaixo, experimente navegar usando a tecla <strong><code>Tab</code></strong> para ver o anel do <code>:focus-visible</code> com <code>outline-offset</code>, observe o cartão reagindo com <code>:focus-within</code> e teste digitar um e-mail para ver a validação em tempo real com <code>:valid</code>:
</p>
<div class="wzw-code-wrapper">
    <div class="wzw-ide-card" id="wzw-code-57945" data-lang="html">
        <div class="wzw-ide-header">
            <div class="wzw-ide-dots" aria-hidden="true">
                <span class="wzw-dot wzw-dot-red"></span>
                <span class="wzw-dot wzw-dot-amber"></span>
                <span class="wzw-dot wzw-dot-green"></span>
            </div>
            <div class="wzw-ide-meta">
                <span class="wzw-ide-lang-badge">HTML5</span>
                                <span class="wzw-ide-lines-count">112 linhas</span>
            </div>
            <div class="wzw-ide-actions">
                <button type="button" class="wzw-ide-btn wzw-ide-wrap-btn" onclick="wzwToggleCodeWrap('wzw-code-57945', this)" title="Alternar quebra automática de linhas">
                    ⇄ Wrap
                </button>
                <button type="button" class="wzw-ide-btn wzw-ide-copy-btn" onclick="wzwCopyCodeBlock('wzw-code-57945', this)" aria-label="Copiar código para a área de transferência">
                    📋 <span class="wzw-copy-text">Copiar Código</span>
                </button>
            </div>
        </div>
        <div class="wzw-ide-body">
            <pre class="wzw-ide-pre" tabindex="0"><code class="wzw-ide-code"><span class="wzw-code-line"><span class="wzw-tk-tag">&lt;!DOCTYPE</span><span class="wzw-tk-kw"> html</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;html</span> <span class="wzw-tk-attr">lang</span>=<span class="wzw-tk-str">&quot;pt-BR&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;head&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;meta</span> <span class="wzw-tk-attr">charset</span>=<span class="wzw-tk-str">&quot;UTF-8&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;title&gt;</span>Laboratório de Pseudo-classes CSS<span class="wzw-tk-tag">&lt;/title&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;style&gt;</span></span>
<span class="wzw-code-line">    body {</span>
<span class="wzw-code-line">      font-family: &#039;Inter&#039;, system-ui, sans-serif;</span>
<span class="wzw-code-line">      background: #0b0f19;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      padding: 40px;</span>
<span class="wzw-code-line">      margin: 0;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 1. O PAI REAGE COM :focus-within */</span></span>
<span class="wzw-code-line">    .formulario-card {</span>
<span class="wzw-code-line">      max-width: 420px;</span>
<span class="wzw-code-line">      background: #1e293b;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">      border-radius: 14px;</span>
<span class="wzw-code-line">      padding: 24px;</span>
<span class="wzw-code-line">      transition: border-color 0.3s ease, box-shadow 0.3s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .formulario-card:focus-within {</span>
<span class="wzw-code-line">      border-color: #38bdf8;</span>
<span class="wzw-code-line">      box-shadow: 0 8px 30px rgba(56, 189, 248, 0.15);</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .campo-grupo {</span>
<span class="wzw-code-line">      margin-bottom: 20px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    label {</span>
<span class="wzw-code-line">      display: block;</span>
<span class="wzw-code-line">      font-size: 0.85rem;</span>
<span class="wzw-code-line">      color: #94a3b8;</span>
<span class="wzw-code-line">      margin-bottom: 8px;</span>
<span class="wzw-code-line">      font-weight: 600;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 2. ESTADOS DO INPUT (:valid e :invalid) */</span></span>
<span class="wzw-code-line">    .input-texto {</span>
<span class="wzw-code-line">      width: 100%;</span>
<span class="wzw-code-line">      background: #0f172a;</span>
<span class="wzw-code-line">      border: 1px solid #334155;</span>
<span class="wzw-code-line">      border-radius: 8px;</span>
<span class="wzw-code-line">      padding: 12px 14px;</span>
<span class="wzw-code-line">      color: #f8fafc;</span>
<span class="wzw-code-line">      font-size: 1rem;</span>
<span class="wzw-code-line">      box-sizing: border-box;</span>
<span class="wzw-code-line">      outline: none;</span>
<span class="wzw-code-line">      transition: border-color 0.2s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .input-texto:focus {</span>
<span class="wzw-code-line">      border-color: #38bdf8;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .input-texto:not(:placeholder-shown):valid {</span>
<span class="wzw-code-line">      border-color: #10b981; /* Borda verde quando válido! */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .input-texto:not(:placeholder-shown):invalid {</span>
<span class="wzw-code-line">      border-color: #ef4444; /* Borda vermelha se formato inválido! */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* 3. BOTÃO COM :hover, :active E :focus-visible */</span></span>
<span class="wzw-code-line">    .btn-enviar {</span>
<span class="wzw-code-line">      width: 100%;</span>
<span class="wzw-code-line">      background: #2563eb;</span>
<span class="wzw-code-line">      color: #fff;</span>
<span class="wzw-code-line">      border: none;</span>
<span class="wzw-code-line">      border-radius: 8px;</span>
<span class="wzw-code-line">      padding: 14px;</span>
<span class="wzw-code-line">      font-size: 1rem;</span>
<span class="wzw-code-line">      font-weight: 700;</span>
<span class="wzw-code-line">      cursor: pointer;</span>
<span class="wzw-code-line">      transition: background 0.2s ease, transform 0.1s ease;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-enviar:hover {</span>
<span class="wzw-code-line">      background: #1d4ed8;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    .btn-enviar:active {</span>
<span class="wzw-code-line">      transform: scale(0.98); /* Feedback tátil ao clicar */</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-comment">/* ACESSIBILIDADE POR TECLADO (TAB) */</span></span>
<span class="wzw-code-line">    .btn-enviar:focus-visible {</span>
<span class="wzw-code-line">      outline: 2px solid #38bdf8;</span>
<span class="wzw-code-line">      outline-offset: 4px;</span>
<span class="wzw-code-line">    }</span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/style&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/head&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;body&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;formulario-card&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;h3</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;margin-top:0; color:#f1f5f9;&quot;</span><span class="wzw-tk-tag">&gt;</span>Acesso ao Portal<span class="wzw-tk-tag">&lt;/h3&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;p</span> <span class="wzw-tk-attr">style</span>=<span class="wzw-tk-str">&quot;color:#64748b; font-size:0.85rem; margin-bottom:20px;&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      Navegue usando o <span class="wzw-tk-tag">&lt;kbd&gt;</span>Tab<span class="wzw-tk-tag">&lt;/kbd&gt;</span> do teclado para ver o <span class="wzw-tk-tag">&lt;code&gt;</span>:focus-visible<span class="wzw-tk-tag">&lt;/code&gt;</span> em ação!</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/p&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;div</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;campo-grupo&quot;</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;label</span> <span class="wzw-tk-attr">for</span>=<span class="wzw-tk-str">&quot;email&quot;</span><span class="wzw-tk-tag">&gt;</span>E-mail Corporativo<span class="wzw-tk-tag">&lt;/label&gt;</span></span>
<span class="wzw-code-line">      <span class="wzw-tk-tag">&lt;input</span> <span class="wzw-tk-attr">type</span>=<span class="wzw-tk-str">&quot;email&quot;</span> <span class="wzw-tk-attr">id</span>=<span class="wzw-tk-str">&quot;email&quot;</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;input-texto&quot;</span> <span class="wzw-tk-attr">placeholder</span>=<span class="wzw-tk-str">&quot;seu@email.com&quot;</span> <span class="wzw-tk-attr">required</span><span class="wzw-tk-tag">&gt;</span></span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line">&nbsp;</span>
<span class="wzw-code-line">    <span class="wzw-tk-tag">&lt;button</span> <span class="wzw-tk-attr">type</span>=<span class="wzw-tk-str">&quot;button&quot;</span> <span class="wzw-tk-attr">class</span>=<span class="wzw-tk-str">&quot;btn-enviar&quot;</span><span class="wzw-tk-tag">&gt;</span>Entrar no Ambiente →<span class="wzw-tk-tag">&lt;/button&gt;</span></span>
<span class="wzw-code-line">  <span class="wzw-tk-tag">&lt;/div&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/body&gt;</span></span>
<span class="wzw-code-line"><span class="wzw-tk-tag">&lt;/html&gt;</span></span>
</code></pre>
            <textarea class="wzw-ide-raw" aria-hidden="true" tabindex="-1" readonly>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Laboratório de Pseudo-classes CSS&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: &#039;Inter&#039;, system-ui, sans-serif;
      background: #0b0f19;
      color: #f8fafc;
      padding: 40px;
      margin: 0;
    }

    /* 1. O PAI REAGE COM :focus-within */
    .formulario-card {
      max-width: 420px;
      background: #1e293b;
      border: 1px solid #334155;
      border-radius: 14px;
      padding: 24px;
      transition: border-color 0.3s ease, box-shadow 0.3s ease;
    }

    .formulario-card:focus-within {
      border-color: #38bdf8;
      box-shadow: 0 8px 30px rgba(56, 189, 248, 0.15);
    }

    .campo-grupo {
      margin-bottom: 20px;
    }

    label {
      display: block;
      font-size: 0.85rem;
      color: #94a3b8;
      margin-bottom: 8px;
      font-weight: 600;
    }

    /* 2. ESTADOS DO INPUT (:valid e :invalid) */
    .input-texto {
      width: 100%;
      background: #0f172a;
      border: 1px solid #334155;
      border-radius: 8px;
      padding: 12px 14px;
      color: #f8fafc;
      font-size: 1rem;
      box-sizing: border-box;
      outline: none;
      transition: border-color 0.2s ease;
    }

    .input-texto:focus {
      border-color: #38bdf8;
    }

    .input-texto:not(:placeholder-shown):valid {
      border-color: #10b981; /* Borda verde quando válido! */
    }

    .input-texto:not(:placeholder-shown):invalid {
      border-color: #ef4444; /* Borda vermelha se formato inválido! */
    }

    /* 3. BOTÃO COM :hover, :active E :focus-visible */
    .btn-enviar {
      width: 100%;
      background: #2563eb;
      color: #fff;
      border: none;
      border-radius: 8px;
      padding: 14px;
      font-size: 1rem;
      font-weight: 700;
      cursor: pointer;
      transition: background 0.2s ease, transform 0.1s ease;
    }

    .btn-enviar:hover {
      background: #1d4ed8;
    }

    .btn-enviar:active {
      transform: scale(0.98); /* Feedback tátil ao clicar */
    }

    /* ACESSIBILIDADE POR TECLADO (TAB) */
    .btn-enviar:focus-visible {
      outline: 2px solid #38bdf8;
      outline-offset: 4px;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;formulario-card&quot;&gt;
    &lt;h3 style=&quot;margin-top:0; color:#f1f5f9;&quot;&gt;Acesso ao Portal&lt;/h3&gt;
    &lt;p style=&quot;color:#64748b; font-size:0.85rem; margin-bottom:20px;&quot;&gt;
      Navegue usando o &lt;kbd&gt;Tab&lt;/kbd&gt; do teclado para ver o &lt;code&gt;:focus-visible&lt;/code&gt; em ação!
    &lt;/p&gt;

    &lt;div class=&quot;campo-grupo&quot;&gt;
      &lt;label for=&quot;email&quot;&gt;E-mail Corporativo&lt;/label&gt;
      &lt;input type=&quot;email&quot; id=&quot;email&quot; class=&quot;input-texto&quot; placeholder=&quot;seu@email.com&quot; required&gt;
    &lt;/div&gt;

    &lt;button type=&quot;button&quot; class=&quot;btn-enviar&quot;&gt;Entrar no Ambiente →&lt;/button&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
        </div>
    </div>
    
</div>
<p>
  Abra este laboratório no Playground IDE e teste clicar no formulário para comprovar o <code>:focus-within</code> no contêiner e a validação de e-mail dinâmica sem JavaScript:
</p>
<p style="text-align: center; margin: 35px 0;">
  <a href="https://webzoneware.com/web-academy/playground-web/" class="wzw-btn-playground" target="_blank" rel="noopener">⚡ Abrir no Playground IDE &rarr;</a>
</p>
<h2>7. Resumo e Próximos Passos</h2>
<ul>
<li>Pseudo-classes (com <code>:</code>) estilizam elementos com base no seu estado dinâmico ou comportamental.</li>
<li>A ordem dos links deve seguir estritamente o mnemônico <strong>LVHA</strong>: <code>:link</code>, <code>:visited</code>, <code>:hover</code> e <code>:active</code>.</li>
<li>Nunca use <code>outline: none</code> sem fornecer um substituto de alta visibilidade!</li>
<li><code>:focus-visible</code> exibe anéis de foco exclusivamente na navegação por teclado (Tab) e leitores de tela, mantendo cliques de mouse limpos.</li>
<li><code>:focus-within</code> estiliza o elemento pai quando qualquer nó filho recebe foco.</li>
<li><code>:valid</code> e <code>:invalid</code> permitem criar feedbacks visuais imediatos em formulários HTML5.</li>
</ul>
<div class="wzw-callout wzw-callout-success">
<p><strong>A Conclusão do Módulo 4 Está Próxima:</strong> Além dos estados do usuário, como selecionar o primeiro filho de uma lista, zebrar tabelas alternadas a cada duas linhas ou ignorar certos nós? Na <strong>Lição 40</strong>, fecharemos o Módulo 4 dominando as <strong>Pseudo-classes Estruturais (:nth-child, :first-child, :last-child, :not e :empty)</strong>!</p>
</div>
<p>O post <a href="https://webzoneware.com/web-academy/curso-css/pseudo-classes-hover-focus-visible/">Pseudo-classes no CSS: hover, focus e visible | Web Academy</a> apareceu primeiro em <a href="https://webzoneware.com">Web-Zoneware</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webzoneware.com/web-academy/curso-css/pseudo-classes-hover-focus-visible/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
