name: css-protips description: Uma referência de técnicas modernas e práticas de CSS. Use ao escrever, revisar ou refatorar CSS/Tailwind e você deseja padrões idiomáticos — resets, herança de box-sizing, centralização vertical, aspect-ratio, seletores :is()/:not(), propriedades lógicas e outras dicas de profissional. Inclui uma seção de CSS Moderno agrupada por MDN Baseline (Widely available / Newly available / Limited) além de orientações de progressive enhancement (@supports). Baseline é um sinal de compatibilidade de navegador apenas — ainda teste acessibilidade, comportamento de teclado, preferências de movimento e contraste separadamente. Fonte: AllThingsSmitty/css-protips + adições curadas de Baseline (web.dev/MDN).
CSS Protips
Uma coleção de dicas para ajudar a levar suas habilidades CSS a nível profissional. Cada entrada é um padrão autocontido — aplique aquele que se encaixa no problema à sua frente.
Use um CSS Reset
Resets de CSS ajudam a garantir consistência de estilo entre diferentes navegadores com uma base limpa para estilizar elementos. Existem muitos padrões de reset, ou você pode usar uma abordagem mais simplificada:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Agora os elementos serão removidos de margens e preenchimentos, e box-sizing permite gerenciar layouts com o modelo de caixa CSS.
Demo
[!TIP] Se você seguir a dica Herde
box-sizingabaixo, pode optar por não incluir a propriedadebox-sizingno seu CSS reset.
Herde box-sizing
Deixe box-sizing ser herdado de html:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
Isso facilita a alteração de box-sizing em plugins ou outros componentes que utilizam outro comportamento.
Demo
Use all: unset com Cuidado para Resets de Componentes
Ao redefinir as propriedades de um elemento, você pode redefinir cada propriedade individualmente:
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}
Ou use a abreviação all com unset. all: unset redefine quase todas as propriedades (exceto
unicode-bidi, direction e propriedades personalizadas) — props herdadas revertem para herdar, outras para
initial. Um <button> se torna display: inline e perde sua caixa nativa, então sempre restaure o layout
e o foco após redefinir.
button.reset {
all: unset;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
button.reset:focus-visible {
outline: 2px solid currentColor;
outline-offset: 0.15em;
}
[!TIP] Para restaurar a folha de estilo do user-agent em vez de uma base em branco, use
all: revert— veja Intenção de reset:unsetvsrevertna seção de CSS Moderno.
Use :not() para Aplicar/Remover Bordas em Navegação
Em vez de colocar a borda...
/* adicionar borda */
.nav li {
border-right: 1px solid #666;
}
...e depois removê-la do último elemento...
/* remover borda */
.nav li:last-child {
border-right: none;
}
...use a pseudo-classe :not() para aplicar apenas aos elementos desejados:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
Aqui, o seletor CSS é lido como um humano o descreveria.
Demo
Verifique se a Fonte Está Instalada Localmente
Você pode verificar se uma fonte está instalada localmente antes de buscá-la remotamente, o que também é uma boa dica de desempenho.
@font-face {
font-family: "Dank Mono";
src:
/* Nome completo */ local("Dank Mono"), /* Nome Postscript */ local("Dank Mono"),
/* Caso contrário, baixe-o! */ url("//...a.server/fonts/DankMono.woff");
}
code {
font-family: "Dank Mono", system-ui-monospace;
}
Agradecimentos a Adam Argyle por compartilhar esta dica e demo.
Adicione line-height ao body
Você não precisa adicionar line-height a cada <p>, <h*>, et al. separadamente. Em vez disso, adicione ao body:
body {
line-height: 1.5;
}
Desta forma, elementos textuais podem herdar facilmente de body.
Demo
Defina :focus para Elementos de Formulário
Usuários de teclado com visão dependem do foco para determinar onde os eventos de teclado vão na página. Torne o foco para elementos de formulário destacado e consistente em comparação com a implementação padrão do navegador:
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus {
box-shadow: none;
outline: #000 dotted 2px;
outline-offset: 0.05em;
}
Demo
[!TIP] Em código moderno, prefira
:focus-visiblepara que usuários de teclado mantenham um anel de foco claro sem mostrar estilos de foco a cada clique do mouse.
Centralize Verticalmente Qualquer Coisa
Prefira Grid com uma unidade de viewport dinâmica em dispositivos móveis — 100vh mapeia para a viewport grande e pode
se comportar mal quando as barras de ferramentas do navegador aparecem/desaparecem. Com propriedades lógicas, use 100dvb (viewport dinâmica no bloco).
.center-page {
min-block-size: 100dvb;
display: grid;
place-items: center;
}
Flexbox funciona da mesma forma quando o pai tem um tamanho de bloco definido:
html,
body {
min-block-size: 100%;
}
body {
align-items: center;
display: flex;
justify-content: center;
}
[!NOTE] Padrão legado:
height: 100vh+place-items: centerainda aparece em tutoriais antigos. Prefiradvh/dvb/svh/lvhpara layouts de viewport inteira em dispositivos móveis — veja MDN sobre comprimentos relativos à viewport.
[!TIP] Quer centralizar outra coisa? CSS-Tricks tem um bom artigo sobre como fazer tudo isso.
Demo
Use aspect-ratio em Vez de Altura/Largura
A propriedade aspect-ratio permite dimensionar facilmente elementos e manter uma proporção consistente entre largura e altura. Isso é incrivelmente útil em web design responsivo para evitar mudanças de layout. Use object-fit com ela para evitar interromper o layout se os valores de altura/largura das imagens mudarem.
img {
aspect-ratio: 16 / 9; /* largura / altura */
object-fit: cover;
}
Saiba mais sobre a propriedade aspect-ratio neste post do web.dev.
Demo
Listas Separadas por Vírgula
Faça com que os itens da lista pareçam uma lista real separada por vírgulas:
ul > li:not(:last-child)::after {
content: ",";
}
Use a pseudo-classe :not() e nenhuma vírgula será adicionada ao último item.
[!NOTE] Esta dica pode não ser ideal para acessibilidade, especialmente leitores de tela. E copiar/colar do navegador não funciona com conteúdo gerado por CSS. Proceda com cautela.
Selecione Itens Usando nth-child Negativo
Use nth-child negativo em CSS para selecionar itens de 1 a n.
li {
display: none;
}
/* selecionar itens 1 a 3 e exibi-los */
li:nth-child(-n + 3) {
display: block;
}
Ou, já que você aprendeu um pouco sobre usar :not(), tente:
/* selecionar todos os itens exceto os 3 primeiros e exibi-los */
li:not(:nth-child(-n + 3)) {
display: block;
}
Demo
Use SVG para Ícones
Não há razão para não usar SVG para ícones:
.logo {
background: url("logo.svg");
}
SVG escala bem para todos os tipos de resolução e é suportado em todos os navegadores desde IE9. Abandone seus arquivos .png, .jpg, ou .gif-jif-tanto-faz.
[!NOTE] Se você tem botões apenas com ícone SVG para usuários com visão e o SVG falha ao carregar, isso ajudará a manter a acessibilidade:
.no-svg .icon-only::after {
content: attr(aria-label);
}
Use o Seletor "Coruja Lobotomizada"
Pode ter um nome estranho, mas usar o seletor universal (*) com o seletor de irmão adjacente (+) pode fornecer uma capacidade CSS poderosa:
* + * {
margin-top: 1.5em;
}
Neste exemplo, todos os elementos no fluxo do documento que seguem outros elementos receberão margin-top: 1.5em.
[!TIP] Para mais sobre o seletor "coruja lobotomizada", leia o post de Heydon Pickering no A List Apart.
Demo
Use max-height para Sliders CSS Puros
Implemente sliders apenas com CSS usando max-height com overflow oculto:
.slider {
max-height: 200px;
overflow-y: hidden;
width: 300px;
}
.slider:hover {
max-height: 600px;
overflow-y: scroll;
}
O elemento expande para o valor de max-height ao passar o mouse e o slider é exibido como resultado do overflow.
Células de Tabela com Largura Igual
Tabelas podem ser um saco de trabalhar. Tente usar table-layout: fixed para manter as células com largura igual:
.calendar {
table-layout: fixed;
}
Layouts de tabela sem dor.
Demo
Livre-se de Hacks de Margem com Flexbox
Ao trabalhar com gutters de coluna, você pode se livrar de hacks de nth-, first- e last-child usando a propriedade space-between do flexbox:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}
Agora os gutters das colunas sempre aparecem uniformemente espaçados.
Use Seletores de Atributo com Links Vazios
Exiba links quando o elemento <a> não tiver valor de texto, mas o atributo href tiver um link:
a[href^="http"]:empty::before {
content: attr(href);
}
Isso é muito conveniente.
Demo
[!NOTE] Esta dica pode não ser ideal para acessibilidade, especialmente leitores de tela. E copiar/colar do navegador não funciona com conteúdo gerado por CSS. Proceda com cautela.
Controle Melhor a Especificidade com :is()
A pseudo-classe :is() é usada para segmentar vários seletores ao mesmo tempo, reduzindo redundância e melhorando a legibilidade do código. Isso é incrivelmente útil para escrever seletores grandes de forma mais compacta.
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) {
color: green;
}
O conjunto de regras acima é equivalente ao seguinte conjunto de regras de seletores numéricos...
section h1,
section h2,
section h3,
section h4,
section h5,
section h6,
article h1,
article h2,
article h3,
article h4,
article h5,
article h6,
aside h1,
aside h2,
aside h3,
aside h4,
aside h5,
aside h6,
nav h1,
nav h2,
nav h3,
nav h4,
nav h5,
nav h6 {
color: green;
}
Demo
Estilize Links "Padrão"
Adicione um estilo para links "padrão":
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}
Agora, links inseridos via CMS, que geralmente não têm um atributo class, terão uma distinção sem afetar genericamente a cascata.
Caixas com Proporção Intrínseca (fallback legado)
[!NOTE] Legado apenas. Prefira
aspect-ratio(Baseline Widely available) para código novo. Mantenha este hack de padding apenas quando precisar suportar navegadores muito antigos ou precisar de um padrão que antecedeaspect-ratio.
Para criar uma caixa com proporção intrínseca, aplique padding superior ou inferior a uma div:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
Usar 20% para padding faz com que a altura da caixa seja igual a 20% de sua largura. Não importa a largura da viewport, a div filho manterá sua proporção (100% / 20% = 5:1).
Demo
Estilize Imagens Quebradas
Torne imagens quebradas mais esteticamente agradáveis com um pouco de CSS:
img {
display: block;
font-family: sans-serif;
font-weight: 300;
height: auto;
line-height: 2;
position: relative;
text-align: center;
width: 100%;
}
Agora adicione regras de pseudo-elementos para exibir uma mensagem de usuário e a referência de URL da imagem quebrada:
img::before {
content: "Desculpe, a imagem abaixo está quebrada :(";
display: block;
margin-bottom: 10px;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}
[!TIP] Saiba mais sobre estilização para este padrão no post de Ire Aderinokun.
Use rem para Dimensionamento Global; Use em para Dimensionamento Local
Depois de definir o tamanho da fonte base na raiz (html { font-size: 100%; }), defina o tamanho da fonte para elementos textuais como em:
h2 {
font-size: 2em;
}
p {
font-size: 1em;
}
Em seguida, defina o tamanho da fonte para módulos como rem:
article {
font-size: 1.25rem;
}
aside .module {
font-size: 0.9rem;
}
Agora cada módulo se torna compartimentalizado e mais fácil de estilizar, mais sustentável e flexível.
Oculte Vídeos com Reprodução Automática que Não Estão Silenciados
Esta é uma ótima dica para uma folha de estilo de usuário personalizada. Evite sobrecarregar um usuário com som de um vídeo que é reproduzido automaticamente quando a página é carregada. Se o som não estiver silenciado, não mostre o vídeo:
video[autoplay]:not([muted]) {
display: none;
}
Mais uma vez, estamos aproveitando o uso da pseudo-classe :not().
Use :root para Tipo Flexível
O tamanho da fonte do tipo em um layout responsivo deve ser capaz de se ajustar a cada viewport. Você pode calcular o tamanho da fonte com base na altura e largura da viewport usando :root:
:root {
font-size: calc(1vw + 1vh + 0.5vmin);
}
Agora você pode utilizar a unidade root em com base no valor calculado por :root:
body {
font: 1rem/1.6 sans-serif;
}
Demo
Defina font-size em Elementos de Formulário para uma Melhor Experiência Mobile
Para evitar
…