A renderização de HTML é criada com base no modelo de caixa, mas há mais na vida (e no web design) do que retângulos. O CSS oferece várias maneiras de mudar quais áreas de um elemento são renderizadas, aos desenvolvedores a liberdade de criar designs compatíveis com todos os formatos e tamanhos. O recorte permite formas geométricas, enquanto o mascaramento afeta a visibilidade no nível do pixel.
Caminhos e formas
O CSS usa funções para definir formas. Abordamos informações gerais sobre funções no módulo de funções do CSS. Nesta seção, você vai aprender a criar formas em CSS. Todos os exemplos a seguir usam as formas criadas com a propriedade clip-path
, que reduz a área visível apenas ao que está dentro da forma. Isso permite que os elementos sejam visualmente diferentes da caixa do elemento. Vamos falar sobre corte com mais detalhes depois.
As formas definidas em CSS podem ser básicas (como círculos, retângulos e polígonos) ou caminhos (que podem definir formas complexas e compostas).
Formas básicas
circle()
e ellipse()
As funções circle()
e ellipse()
definem formas redondas e ovais com raios relativos a um elemento. A função circle()
aceita um único tamanho ou porcentagem como argumento. Por padrão, as duas funções posicionam a forma em relação ao centro do elemento. Ambos aceitam uma posição opcional após a palavra-chave at
, que pode ser expressa como comprimentos, porcentagens ou palavras-chave posicionais.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: circle(50%);
}
O exemplo anterior mostra um caminho de recorte circular usando a função circle()
. Um raio de 50%
cria um círculo com a largura total do elemento. A função ellipse()
aceita dois argumentos que representam os raios horizontal e vertical da forma.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: ellipse(50% 25%);
}
O exemplo anterior mostra um caminho de recorte elíptico usando a função ellipse()
. Um raio de 50% cria uma elipse com a largura total do elemento. O exemplo a seguir mostra a mesma elipse posicionada com o centro na parte de cima do elemento.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: ellipse(50% 25% at center top);
}
rect()
e inset()
As funções rect()
e inset()
oferecem diferentes maneiras de definir um retângulo definindo a posição dos lados dele em relação aos lados de um elemento. Isso permite criar retângulos que diferem visualmente da caixa padrão do elemento. Eles aceitam opcionalmente a palavra-chave round
para criar um retângulo com cantos arredondados, usando a mesma sintaxe da propriedade abreviada border-radius
.
A função rect()
define a posição dos lados superior e inferior do retângulo em relação à borda superior do elemento e os lados esquerdo e direito em relação à borda esquerda do elemento. Essa função aceita quatro unidades de tamanho ou porcentagem como argumentos que definem os lados superior, direito, inferior e esquerdo. Você pode escolher a função rect()
quando quiser um retângulo que não seja dimensionado quando o tamanho do elemento muda ou que mantenha as mesmas proporções à medida que o elemento muda.
.my-element {
width: 80px;
height: 60px;
background: blue;
clip-path: rect(15px 75px 45px 10px);
}
O exemplo anterior mostra um caminho de recorte retangular definido usando a função rect()
. As dimensões são relativas às bordas superior e esquerda do elemento, conforme mostrado no diagrama.
A função inset()
define a posição dos lados de um retângulo pela distância para dentro de cada um dos lados de um elemento. Essa função aceita de uma a quatro unidades de tamanho ou porcentagem como argumentos, permitindo definir vários lados de uma só vez. Você pode escolher a função inset()
quando quiser um retângulo que seja dimensionado com o elemento ou que tenha uma distância fixa das bordas dele.
.my-element {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px);
}
O exemplo anterior mostra um caminho de recorte retangular definido usando a função inset()
. As dimensões são relativas aos lados do elemento.
As funções rect()
e inset()
aceitam opcionalmente a palavra-chave round
para criar um retângulo com cantos arredondados, usando a mesma sintaxe da propriedade abreviada border-radius
. O exemplo a seguir demonstra versões arredondadas dos retângulos mostrados anteriormente.
.rounded-rect {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px round 5px);
}
.rounded-inset {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px round 5px);
}
polygon()
Para outras formas, como triângulos, pentágonos, estrelas etc., a função polygon()
permite criar formas conectando vários pontos com linhas retas. A função polygon()
aceita uma lista de pares que consistem em duas unidades de comprimento ou porcentagem. Cada par descreve um ponto no polígono: o primeiro valor é a distância da borda esquerda do elemento, e o segundo é a distância da borda superior. Não é necessário fechar o polígono, porque ele será concluído conectando o último ponto ao primeiro.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: polygon(
50% 0,
0 100%,
100% 100%
);
}
O exemplo anterior cria um caminho de recorte triangular definindo três pontos.
Por padrão, a função polygon()
renderiza áreas sobrepostas como preenchidas. É possível mudar esse comportamento com um primeiro argumento opcional chamado regra de preenchimento. Para alternar entre áreas preenchidas e não preenchidas, defina a regra de preenchimento como evenodd
. Para usar a regra de preenchimento padrão, defina-a como nonzero
.
O exemplo anterior mostra a função polygon()
com funções trigonométricas para criar polígonos regulares e formas de estrela. Isso não cria o maior polígono regular possível que se encaixa em um elemento ou o centraliza. Deixamos isso como um exercício para você tentar. As formas de estrela neste exemplo também demonstram as regras de preenchimento nonzero
e evenodd
.
Formas complexas
Quando as funções de forma básica não são suficientes para descrever uma forma complexa, o CSS oferece funções que usam uma sintaxe mais sofisticada para descrever recursos como curvas e linhas. Essas funções também são úteis para formas compostas (formas compostas por várias formas, como um círculo com um buraco).
path()
A função path()
aceita uma string de sintaxe de caminho SVG para descrever uma forma. Isso permite criar formas complexas usando instruções que descrevem as linhas e curvas que compõem a forma. Editar diretamente a sintaxe SVG pode ser complicado. Por isso, recomendamos considerar um editor visual dedicado que possa exportar a sintaxe ao criar formas com a função path()
.
A função path()
não usa unidades de dimensionamento CSS, e todos os valores são interpretados como pixels. Isso significa que as formas criadas com a função de caminho não são responsivas ao tamanho do elemento ou contêiner. Recomendamos usar path()
apenas para formas com dimensões fixas.
shape()
A função shape()
usa uma sintaxe de comando para descrever uma forma, semelhante à função path()
. No entanto, os comandos da função shape()
são CSS nativos e podem usar unidades de tamanho do CSS. Isso permite que formas definidas usando a função shape()
sejam dimensionadas de maneira responsiva.
O exemplo anterior usa as funções path()
e shape()
para definir um formato de coração e um círculo com um buraco no centro. O exemplo usa o mesmo valor em pixels para as duas funções, mas as funções shape()
também poderiam ter usado outras unidades de tamanho CSS, como porcentagens ou unidades relativas ao contêiner.
Corte
O recorte define quais áreas de um elemento estão visíveis, semelhante a recortar uma imagem de uma revista. A propriedade clip-path
define o caminho usado para definir a área de corte.
Como você viu nos exemplos da seção anterior, qualquer uma das funções básicas de forma ou caminho pode ser usada como clip-path
. A propriedade clip-path
também aceita caminhos definidos em um elemento clipPath
SVG, que pode ser incorporado ou estar em um arquivo separado.
O diagrama anterior mostra como a adição de um clip-path
a um elemento de imagem muda a área visível dela. O caminho de recorte superior usa a função circle()
, enquanto o inferior usa um clipPath
SVG. O círculo criado usando a função circle()
é posicionado centralizado no elemento por padrão.
A propriedade clip-path
aceita apenas um caminho. Para cortar um elemento com várias formas que não se sobrepõem, use as funções path()
ou shape()
para definir um caminho composto ou use um clipPath
SVG. Outra opção para cenários complexos é usar mascaramento em vez de corte, que abordaremos em uma seção posterior.
Como cortar com formas
Para fazer o recorte usando uma forma básica ou uma função de caminho, defina a propriedade clip-path
como o valor retornado pela função, como nos exemplos anteriores. Cada função posiciona a forma de corte de maneira diferente em relação ao elemento. Consulte a referência de cada função.
No exemplo anterior, dois elementos têm um clip-path
circular aplicado usando a classe .clipped
. O clip-path
é posicionado em relação a cada elemento, e o texto dentro dele não é reformatado para seguir a forma.clip-path
Uma caixa de referência de um caminho de recorte
Por padrão, o caminho de corte de um elemento inclui a borda dele. Ao usar uma das funções de forma básica, é possível definir a caixa de referência do clip-path para incluir apenas a área do elemento dentro da borda. Os valores válidos para a caixa de referência são stroke-box
(o padrão) e fill-box
(para incluir apenas a área dentro da borda).
O exemplo anterior mostra elementos com uma borda grande (20px
), cada um usando a função inset()
para definir o clip-path
. O elemento que corta em relação à borda ainda mostra uma parte dela. Os elementos que são cortados em relação à área dentro da borda não mostram nenhuma borda e são menores, mesmo com o mesmo valor de encarte.
Recorte com gráficos
Um caminho de recorte pode ser definido em um documento SVG, incorporado ao documento HTML ou referenciado externamente. Isso pode ser útil para definir caminhos de recorte complexos criados em programas gráficos ou caminhos de recorte que combinam várias formas.
<img id="kitten" src="kitten.png">
<svg>
<defs>
<clipPath id="kitten-clip-shape">
<circle cx="130" cy="175" r="100" />
</clipPath>
</defs>
</svg>
<style>
#kitten {
clip-path: url(#kitten-clip-shape);
}
</style>
No exemplo anterior, o clipPath
com um id
de kitten-clip-shape
é aplicado ao elemento <img>
. Nesse caso, o documento SVG está incorporado ao HTML. Se o documento SVG for um arquivo externo chamado kitten-clipper.svg
, o clipPath
será referenciado como url(kitten-clipper.svg#kitten-clip-shape)
.
Mascaramento
O mascaramento é outro método para definir quais áreas de um elemento são mostradas ou ocultadas. Enquanto o corte usa formas ou trajetórias básicas, a máscara usa os pixels de uma imagem ou um gradiente para determinar a visibilidade. Ao contrário do recorte, a máscara permite que áreas de um elemento sejam parcialmente transparentes. Várias imagens de máscara podem ser aplicadas a um elemento para produzir uma variedade de efeitos.
Para aplicar uma máscara, defina a propriedade mask-image
. Essa propriedade aceita uma ou mais imagens, gradientes ou referências a elementos <mask>
em um documento SVG. É possível aplicar várias imagens de máscara separando-as com vírgulas.
.my-element {
mask-image: url(my-mask.png),
linear-gradient(black 0%, transparent 100%);
}
No exemplo anterior, .my-element
é mascarado usando uma imagem PNG, seguida por um gradiente linear. Várias máscaras são adicionadas por padrão para criar a máscara final.
O exemplo anterior mostra uma imagem com uma ou mais máscaras aplicadas. Alterne cada máscara para ver como elas se combinam e produzem o efeito final.
Máscara alfa x máscara de luminância
É possível aplicar uma máscara usando o alpha
ou o luminance
da imagem. Ao mascarar com base em alpha
, a transparência de cada pixel na imagem da máscara é aplicada ao elemento, ignorando as informações de cor desse pixel. Ao mascarar com base em luminance
, a transparência e o valor de cada pixel (brilho ou escuridão) são aplicados ao elemento. A máscara por luminância trata cores mais claras como visíveis e cores mais escuras como invisíveis.
Para definir o modo de mascaramento, use a propriedade mask-mode
. Por padrão, a propriedade mask-mode
é definida como match-source
, que define um modo com base no tipo da imagem de máscara. Para imagens e gradientes, o padrão é alpha
. Para máscaras SVG, o padrão será o valor da propriedade mask-type
do elemento <mask>
ou luminance
, se não houver um mask-type
definido.
No exemplo anterior, um padrão de teste que mostra diferentes valores de cor e alfa é usado como máscara. Ao alternar o mask-mode
, você pode ver como o modo alpha
se baseia na transparência, enquanto o modo luminance
se baseia no brilho da cor e na transparência.
Outras propriedades de mascaramento
O CSS oferece outras propriedades para ajustar o comportamento das máscaras. Cada uma das propriedades aceita uma lista de valores separados por vírgulas, que serão correspondentes à lista de máscaras definidas pela propriedade mask-image
. Se houver menos valores do que máscaras, a lista vai se repetir até que um valor seja definido para cada máscara. Se houver mais valores do que máscaras, os valores excedentes serão descartados.
Propriedade | Descrição |
---|---|
mask-clip |
Define a caixa de referência a que as máscaras de elemento são aplicadas. O valor padrão é |
mask-composite |
Define a interação entre máscaras quando várias delas são aplicadas ao mesmo elemento. O valor padrão é |
mask-origin |
Define a caixa de referência que atua como a origem de uma máscara. O valor padrão é |
mask-position |
Define a posição de uma máscara em relação ao |
mask-repeat |
Define como uma máscara se repete se o elemento mascarado for maior que a máscara. O valor padrão é |
mask-size |
Define como uma máscara é redimensionada em relação ao tamanho do elemento mascarado. O valor padrão é |
A abreviação de máscara
É possível definir várias propriedades de máscara de uma só vez com a abreviação de máscara. Isso pode simplificar a configuração de várias máscaras agrupando todas as propriedades de cada uma. O atalho de máscara equivale a definir estas propriedades em ordem: mask-image
, mask-mode
, mask-position
, mask-size
, mask-repeat
, mask-origin
, mask-clip
e mask-composite
. Nem todas as propriedades precisam ser incluídas, e as que não forem serão redefinidas para o valor inicial. Com suporte para até oito propriedades por máscara, é útil ter uma referência completa disponível.
.longhand {
mask-image: linear-gradient(white, black),
linear-gradient(90deg, black, transparent);
mask-mode: luminance, alpha;
mask-position: bottom left, top right;
mask-size: 50% 50%, 30% 30%;
}
.shorthand {
mask: linear-gradient(white, black) luminance bottom left / 50% 50%,
linear-gradient(90deg, black, transparent) alpha top right / 30% 30%;
}
No exemplo anterior, cada classe tem duas máscaras aplicadas. O primeiro usa propriedades individuais, enquanto o segundo usa o atalho mask
. Os dois estilos são equivalentes.
Texto corrido ao redor de elementos flutuantes
Ao cortar ou mascarar um elemento, você só muda a área visível dentro da caixa dele, mas a caixa em si permanece inalterada. Isso significa que um elemento flutuante vai afetar o fluxo do documento com base na caixa delimitadora original, não nas partes visíveis do elemento. Para definir o fluxo ao redor de um elemento, use a propriedade shape-outside
com o caminho de corte.
A propriedade shape-outside
define o formato em que o conteúdo vai fluir ao redor de um elemento. Essa forma pode ser qualquer uma das funções de forma básica, mas não as definidas usando as funções path()
ou shape()
, ou um clipPath
definido em um documento SVG.
A propriedade shape-outside
também aceita uma imagem ou um gradiente. Assim como no mascaramento, os limites da forma são determinados pela transparência da imagem ou do gradiente. A propriedade shape-image-threshold
define quais níveis de transparência são considerados dentro da forma.
Formas em animação
Como animar clip-path
É possível animar a propriedade clip-path
, misturando forma a forma. Use a mesma função de forma para cada frame-chave e produzir animações suaves. Ao usar as funções polygon()
ou shape()
, o mesmo número de pontos precisa ser usado em cada frame-chave.
No exemplo anterior, o clip-path
de um elemento faz a transição entre um pentágono e uma estrela definidos usando a função polygon()
. O exemplo usa a regra de preenchimento evenodd
para mostrar como os pontos de animação criam áreas sobrepostas.
Animação com offset-path
Também é possível animar elementos ao longo dos caminhos criados com essas funções de forma. A propriedade offset-path
define a forma a ser usada como o caminho, e offset-distance
define a posição ao longo desse caminho. Você também pode usar a função ray()
com a propriedade offset-path
para animar ao longo de uma linha reta.
O exemplo anterior demonstra o uso do mesmo polígono para um clip-path
e um offset-path
. A animação usa offset-distance
para mover as estrelas menores ao longo do mesmo polígono que a estrela grande usa como clip-path
.
Teste seu conhecimento
Quais das opções a seguir são funções de forma válidas?
circle()
square()
hexagon()
polygon()
rectangle()
inset()
Verdadeiro ou falso: as formas definidas com a função path()
podem ser definidas usando porcentagens.
Verdadeiro ou falso: definir o caminho de recorte de um elemento não muda o fluxo de texto ao redor dele.
Qual das opções a seguir pode ser usada como um caminho de recorte?
clipMask
SVGQual das opções a seguir pode ser usada como máscara?
circle()
ou rect()