Uma coleção de dicas para aumentar suas habilidades no CSS.
Dê uma olhada em mais algumas listas fantásticas mantidas por @sindresorhus.
- Use um Reset CSS
- Herde o
box-sizing
- Use
unset
em vez de redefinir todas as propriedades - Use
:not()
para Aplicar/Remover Bordas - Verifique se a fonte está instalada localmente
- Defina o
line-height
nobody
- Definir
:focus
para elementos de formulário - Alinhe Elementos Verticalmente
- Use
aspect-ratio
ao invés de Height/Width - Listas Separadas por Vírgula
- Selecione Itens Usando
nth-child
Negativo - Ícones SVG
- Use o Seletor "Lobotomized Owl"
- Sliders em CSS com
max-height
- Tabelas com Células de Tamanho Igual
- Esqueça as "Margin Hacks", use Flexbox
- Use Seletores de Atributo em Links Vazios
- Controle Melhor a Especificidade Com
:is()
- Estilize Links "Default"
- Div com Proporção de Tela Fixa
- Estilize Imagens Quebradas
- Use
rem
para Definir Tamanhos Globais; Useem
para Definir Tamanhos Locais - Esconda Vídeos em Autoplay Que Não Estejam no Mudo
- Use
:root
para uma Tipografia Flexível - Defina
font-size
em Elementos de Formulário para uma Melhor Experiência Mobile - Use eventos de ponteiro para controlar eventos do mouse
- Definir
display: none
em quebras de linha usadas como espaçamento - Use
:empty
para Esconder Eelementos HTML Vazios
Resetar o CSS vai te ajudar a manter a consistência de estilo em diferentes navegadores com um ponto de partida limpo para elementos de estilo. Você pode usar a biblioteca de reset CSS como Normalize, ou se preferir, usar uma abordagem mais simplificada.:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Agora os elementos estarão sem margens, preenchimento e box-sizing
. Te permitindo gerenciar o layout com o seu CSS.
Nota: Se você seguir a dica Herde o box-sizing abaixo você pode optar por não incluir a propriedade box-sizing
em sua redefinição de CSS.
Faça com que o box-sizing
seja herdado do html
:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
Assim fica fácil de alterar o box-sizing
em plugins ou outros componentes que tenham um comportamento diferente.
Ao redefinir as propriedades de um elemento, não é necessário redefinir cada propriedade individual:
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}
Você pode especificar todas as propriedades de um elemento usando a abreviação all
. Definir o valor como unset
altera as propriedades de um elemento para seus valores iniciais:
button {
all: unset;
}
Ao invés de colocar a borda…
/* adiciona a borda */
.nav li {
border-right: 1px solid #666;
}
…para então remover no último elemento…
/* remove a borda */
.nav li:last-child {
border-right: none;
}
…utilize a pseudo-classe :not()
para aplicar a borda apenas nos elementos corretos:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
O seletor CSS define a borda da maneira que um humano a descreveria.
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:
/* Full name */
local("Dank Mono"),
/* Postscript name */
local("Dank-Mono"),
/* Otherwise, download it! */
url("//...a.server/fonts/DankMono.woff");
}
code {
font-family: "Dank Mono", system-ui-monospace;
}
Dica de chapéu para Adam Argyle por compartilhar este protip e exemplo.
Você não precisa adicionar o line-height
para cada <p>
, <h*>
, et al. separadamente. Apenas adicione ao body
:
body {
line-height: 1.5;
}
Dessa maneira elementos de texto vão herdar o line-height
do body
.
Os usuários de teclado com visão dependem do foco para determinar onde os eventos de teclado vão na página. Faça com que os elementos do formulário se foquem e sejam consistentes 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: .05em;
}
Que bruxaria é essa? Não é bruxaria! Você realmente pode centralizar elementos verticalmente:
html,
body {
height: 100%;
margin: 0;
}
body {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-flex;
display: flex;
}
...e também com CSS Grid:
body {
display: grid;
height: 100vh;
margin: 0;
place-items: center center;
}
Isso não resolveu seu problema? O site CSS-Tricks tem um guia completo de como centralizar elementos com CSS.
A propriedade aspect-ratio
permite que você dimensione elementos facilmente e mantem a proporção largura-altura (width-to-height) consistênte. Isso é incrivelmente útil em web design responsivo para prevenir alterações no layout. Use object-fit
com isso para prevenir quebras no layout se os valores de altura/largura das images mudar.
img {
aspect-ratio: 16 / 9; /* width / height */
object-fit: cover;
}
Aprenda mais sobre a propriedade aspect-ratio
neste web.dev post.
[!NOTA]
aspect-ratio
eobject-fit
não são suportados em IE11.
Transforme listas normais em listas separadas por vírgula:
ul > li:not(:last-child)::after {
content: ",";
}
Utilize a pseudo-classe :not()
para evitar que a vírgula seja adicionada depois do último item.
Aviso: Se considerarmos acessibilidade essa dica pode não ser ideal, especialmente para usuários de leitores de tela. Além disso, copiar e/ou colar não funcionam em conteúdo criado com CSS. Proceda com cautela.
Utilize nth-child
negativo no CSS para selecionar itens de 1 a n.
li {
display: none;
}
/* mostrar itens de 1 a 3 */
li:nth-child(-n+3) {
display: block;
}
Já que você aprendeu um pouquinho sobre como usar a pseudo-classe using :not()
, você pode tentar:
/* selecione todos os itens, exceto os primeiros 3 e exiba-os */
li:not(:nth-child(-n+3)) {
display: none;
}
Mais fácil que isso só dois disso.
Não tem porque você não usar ícones em SVG:
.logo {
background: url("logo.svg");
}
A vantagem do SVG é que o ícone fica bom em qualquer resolução, além de ter suporte amplo em todos os browsers desde o IE9. Agora você pode se desfazer dos seus arquivos .png, .jpg, ou ainda .gif-jif-qissomano.
Aviso: Se você tem botões feitos apenas com ícones SVG, a dica a seguir o ajudará a manter a acessibilidade:
.no-svg .icon-only::after {
content: attr(aria-label);
}
O nome é super estranho (coruja lobotomizada), mas o uso do seletor universal (*
) com o seletor adjacente (+
) pode ser muito útil:
* + * {
margin-top: 1.5em;
}
Nesse exemplo, todos os elementos acompanhados de outros elementos recebem margin-top: 1.5em
.
Para mais exemplos utilizando o seletor "lobotomized owl", leia o artigo escrito por Heydon Pickering no site A List Apart.
Crie sliders usando apenas CSS com max-height
e overflow-y: hidden
:
.slider {
max-height: 200px;
overflow-y: hidden;
width: 300px;
}
.slider:hover {
max-height: 600px;
overflow-y: scroll;
}
O elemento se expandirá ao valor definido no max-height
no hover e você terá um slider devido ao uso do overflow.
Não tem nada mais chato do que trabalhar com tabelas, mas você pode usar table-layout: fixed
para manter as células do mesmo tamanho:
.calendar {
table-layout: fixed;
}
Tabelas sem dor de cabeça.
Quando definir o espaçamento entre as colunas, você pode deixar os seletores nth-
, first-
, e last-child
de lado e usar a propriedade space-between
do flexbox:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}
Assim as colunas ficam espaçadas uniformemente.
Mostre links para tags <a>
vazias que possuem o atributo href
:
a[href^="http"]:empty::before {
content: attr(href);
}
Mão na roda.
A pseudoclasse :is()
é usada para marca vários seletores de uma só vez, reduzindo a redundância e melhorando a legibilidade do código. Isso é extremamente útil para escrever seletores grandes de uma forma mais compacta.
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) {
color: green;
}
O conjunto de regras acima é equivalente às seguintes regras do seletor de números...
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;
}
[!NOTA] A pseudoclasse
:is()
não é suportada em IE11.
Defina estilos para links "default":
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}
Dessa forma, links que são inseridos por CMS – que normalmente não possuem o atributo class
– vão ser estilizados sem comprometer outros links.
Para criar uma div com proporção de tela fixa, tudo que você precisa fazer é adicionar padding
(top
ou bottom
) a div pai:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
Se você usar 20% no padding
a altura da div vai ser igual a 20% de sua largura. Independente da largura do viewport, a div filho vai sempre manter a proporção de tela (100% / 20% = 5:1).
Faça com que imagens quebradas fiquem esteticamente mais agradáveis com um pouquinho 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 com pseudo-elementos para mostrar uma mensagem e a URL da imagem quebrada:
img::before {
content: "Desculpe, a imagem abaixo não pode ser carregada :(";
display: block;
margin-bottom: 10px;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}
Leia mais sobre como estilizar imagens quebradas no artigo original por Ire Aderinokun.
Depois de definir o tamanho de fonte base na raíz (html { font-size: 100%; }
), defina o tamanho de fonte para elementos de texto utilizando em
:
h2 {
font-size: 2em;
}
p {
font-size: 1em;
}
Então defina o tamanho da fonte de módulos utilizando rem
:
article {
font-size: 1.25rem;
}
aside .module {
font-size: .9rem;
}
Assim fica mais fácil de estilizar e manter cada módulo, além de ser flexível.
Ótima dica para uma stylesheet personalizada. Evite sobrecarregar o usuário com som de vídeos em autoplay. Se o som não estiver no mudo, esconda o vídeo:
video[autoplay]:not([muted]) {
display: none;
}
E aqui mais uma entre as muitas vantagens de usar a pseudo-classe :not()
.
O tamanho de fonte de um site responsivo deveria ser ajustável de acordo com cada viewport. Você pode calcular o tamanho da fonte baseado na largura e na altura do viewport usando :root
:
:root {
font-size: calc(1vw + 1vh + .5vmin);
}
Assim você pode utilizar a unidade de medida root em
baseada no valor calculado por :root
:
body {
font: 1rem/1.6 sans-serif;
}
Para evitar zoom indesejado em elementos de formulários de navegadores mobile (iOS Safari, et al) quando um <select>
é selecionado, adicione font-size
no seletor:
input[type="text"],
input[type="number"],
select,
textarea {
font-size: 16px;
}
💃
Eventos de ponteiro permitem que você especifique como o mouse interage com o elemento que está tocando. Para desativar o evento de ponteiro padrão em um botão, por exemplo:
button:disabled {
opacity: .5;
pointer-events: none;
}
É simples assim.
Como Harry Roberts apontou, isso pode ajudar a impedir que os usuários do CMS usem quebras de linha extras para espaçamento:
br + br {
display: none;
}
Se você tem elementos HTML vazios, ou seja, o conteúdo ainda tem que ser definido ou pela CMS ou injetado dinamicamente (e.g., <p class="error-message"></p>
) e está criando espaços indesejáveis no seu layout, use a pseudoclasse :empty
para esconder os elementos no layout.
:empty {
display: none;
}
[!NOTA] Lembre-se que os elementos com espaços em branco não são considerados vazios, e.g.,
<p class="error-message"> </p>
.
Versões atuais do Chrome, Firefox, Safari, e Edge.