Publicado em 8 de abril de 2025
A propriedade clip-path
permite mudar a forma de um elemento cortando-o em
um círculo, polígono ou até mesmo um caminho SVG. No entanto, antes do Chrome 135 e do Safari 18.4,
era necessário escolher entre polígonos responsivos
e formas mais complexas que não são responsivas usando caminhos SVG.
Com a nova função shape()
, um clip-path
pode recortar o elemento para uma
forma não poligonal que também é responsiva.
Criar uma forma de bandeira
Como exemplo, compare a criação de uma forma de bandeira com clip-path: path()
e
clip-path: shape()
.
Uma forma de bandeira não é exatamente um polígono, já que as bordas de cima e de baixo são curvas Bézier cúbicas, e não linhas retas ou cantos arredondados.
Crie a flag com clip-path: path()
Uma forma como esta bandeira pode ser representada usando um caminho SVG:
.flag {
clip-path: path(
"M 0 20 \
C 25 0 75 40 100 20 \
V 80 \
C 75 100 25 60 0 80 \
z");
}
Um caminho SVG é uma série de comandos de caminho:
- Mova para 0, 20.
- Curva para 100, 20, usando pontos de controle (25,0 e 75, 40).
- Linha vertical para 80.
- Curva para 0, 80, usando pontos de controle (75,100 e 25,50).
- Feche o caminho (linha para 0,20).
Isso desenha uma forma de bandeira, mas todas as unidades estão em pixels. O SVG pode dimensionar esses pixels para uma caixa de visualização, mas de uma maneira que sempre pareça uma escala geométrica de toda a forma.
Por exemplo, se você quiser que o retângulo inteiro seja dimensionado, mas mantenha a altura e a largura das curvas em 20 px, o SVG não vai conseguir fazer isso.
Crie a flag com shape()
Compare o mesmo resultado usando shape()
. A função de forma aceita uma série de
comandos, semelhante aos comandos de caminho SVG. No entanto, esses comandos aceitam comprimentos
e porcentagens do CSS em qualquer unidade do CSS.
O CSS a seguir converte a flag shape()
com unidades percentuais:
.flag {
clip-path: shape(from 0% 20%,
curve to 100% 20% with 25% 0% / 75% 40%,
vline to 80%,
curve to 0% 80% with 75% 100% / 25% 60%,
close
);
}
Crie uma versão responsiva
Com a gama completa de comprimentos CSS disponíveis, você pode escolher quais usar para cada coordenada.
Por exemplo, para fazer o tamanho inteiro da bandeira variar de acordo com o tamanho do elemento, mas manter a altura da curva constante, faça o seguinte:
.flag {
clip-path: shape(from 0% 20px,
curve to 100% 20px with 25% 0% / 75% 40px,
vline to calc(100% - 20px),
curve to 0% calc(100% - 20px)
with 75% 100% / 25% calc(100% - 40px),
close
);
}
Adicionar propriedades e animações personalizadas
Com a forma definida no CSS, você também pode usar propriedades personalizadas para facilitar a manipulação da altura:
.flag {
--wave-height: 40px;
clip-path: shape(
from 0px var(--wave-height),
curve to 100% var(--wave-height)
with 25% 0px / 75% calc(var(--wave-height) * 2),
vline to calc(100% - var(--wave-height)),
curve to 0 calc(100% - var(--wave-height))
with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
close
)
}
Você pode até animar a propriedade CSS usando o descritor @property
e fixá-la para que ela não ultrapasse:
@property --animated-wave-height {
syntax: "<length>";
inherits: false;
initial-value: 40px;
}
@keyframes curve {
from { --animated-wave-height: 0px; }
to { --animated-wave-height: 180px; }
}
.flag {
width: 600px;
height: 400px;
background: green;
animation: curve 1s infinite alternate;
--wave-height: calc(min(var(--animated-wave-height, 40px), 40%));
clip-path: shape(
from 0px var(--wave-height),
curve to 100% var(--wave-height)
with 25% 0px / 75% calc(var(--wave-height) * 2),
vline to calc(100% - var(--wave-height)),
curve to 0 calc(100% - var(--wave-height))
with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
close
)
}
Teste a demonstração
No Chrome 135 ou no Safari 18.4, é possível ver a forma de bandeira animada criada usando
clip-path: shape()
nesta
demonstração do CodePen.
Resumo
clip-path: shape()
permite recortar o elemento usando formas arbitrárias e
responsivas, o que antes só era possível usando técnicas como gradientes
cônicos ou SVGs construídos em JavaScript.
Consulte a especificação para conferir a sintaxe completa.
No momento, isso só funciona para clip-path
. No futuro, planejamos usar
esse tipo de forma para
definir a forma da borda do elemento,
o que permitiria ainda mais formas de expressão não retangulares.