Не все элементы дизайна — прямоугольники. Hexagon-аватары, диагональные секции, звёздные рейтинги, волнообразные разделители — всё это делается через clip-path и mask-image.
/* Круг: circle(radius at center-x center-y) */
.avatar {
clip-path: circle(50%); /* Круг по центру */
clip-path: circle(40px at 50% 50%); /* Явный радиус и центр */
}
/* Эллипс */
.ellipse {
clip-path: ellipse(60px 40px at center);
}
/* Прямоугольник с закруглением */
.rounded-clip {
clip-path: inset(10px 20px round 8px);
/* inset(top right bottom left round radius) */
}
/* Полигон — произвольный многоугольник */
.triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.hexagon {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}.star {
clip-path: path('M 50 0 L 61 35 L 98 35 L 68 57 L 79 91 L 50 70 L 21 91 L 32 57 L 2 35 L 39 35 Z');
}path() принимает SVG path data. Мощно, но координаты абсолютные, а не процентные.
.reveal {
clip-path: inset(0 100% 0 0); /* Полностью скрыт справа */
transition: clip-path 0.6s ease;
}
.reveal.visible {
clip-path: inset(0 0% 0 0); /* Полностью виден */
}
/* Hover-эффект: квадрат → круг */
.card {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: clip-path 0.4s ease;
}
.card:hover {
clip-path: circle(50%);
}/* Gradient mask — fade out снизу */
.faded {
mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}
/* Круговая маска */
.vignette {
mask-image: radial-gradient(ellipse at center, black 60%, transparent 100%);
}
/* SVG-маска */
.shaped {
mask-image: url(#my-svg-mask);
}.complex-mask {
mask-image: url(mask1.svg), url(mask2.svg);
mask-composite: subtract; /* add | subtract | intersect | exclude */
}Диагональная секция сайта:
.diagonal-section {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
/* Нижний правый угол — 85%, нижний левый — 100% */
}Волна:
.wave-section {
clip-path: ellipse(100% 55% at 50% 45%);
}clip-path не вызывает перерасчёт layout — браузер просто маскирует уже нарисованный элемент. Анимация clip-path происходит на GPU через compositing, если анимируются только clip-path и transform/opacity.
Генерация clip-path значений для разных форм и применение их к элементам
// Генератор clip-path для разных геометрических форм
function makeHexagon() {
return 'polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)'
}
function makeStar(points = 5) {
const coords = []
for (let i = 0; i < points * 2; i++) {
const angle = (i * Math.PI) / points - Math.PI / 2
const r = i % 2 === 0 ? 50 : 22 // внешний/внутренний радиус в %
const x = 50 + r * Math.cos(angle)
const y = 50 + r * Math.sin(angle)
coords.push(`${x.toFixed(1)}% ${y.toFixed(1)}%`)
}
return `polygon(${coords.join(', ')})`
}
function makeArrow(direction = 'right') {
const shapes = {
right: 'polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%)',
left: 'polygon(100% 20%, 40% 20%, 40% 0%, 0% 50%, 40% 100%, 40% 80%, 100% 80%)',
up: 'polygon(20% 100%, 20% 40%, 0% 40%, 50% 0%, 100% 40%, 80% 40%, 80% 100%)',
}
return shapes[direction] || shapes.right
}
function makeTriangle(type = 'up') {
const shapes = {
up: 'polygon(50% 0%, 0% 100%, 100% 100%)',
down: 'polygon(0% 0%, 100% 0%, 50% 100%)',
right: 'polygon(0% 0%, 100% 50%, 0% 100%)',
}
return shapes[type] || shapes.up
}
// Демонстрация форм
const shapes = [
{ name: 'Шестиугольник', clip: makeHexagon(), bg: '#7b2ff7' },
{ name: 'Звезда 5 лучей', clip: makeStar(5), bg: '#f59e0b' },
{ name: 'Звезда 6 лучей', clip: makeStar(6), bg: '#06b6d4' },
{ name: 'Стрелка →', clip: makeArrow('right'), bg: '#ef4444' },
{ name: 'Треугольник ↑', clip: makeTriangle('up'), bg: '#10b981' },
]
const container = document.createElement('div')
container.style.cssText = 'display: flex; gap: 20px; flex-wrap: wrap; padding: 20px; font-family: sans-serif;'
document.body.appendChild(container)
shapes.forEach(({ name, clip, bg }) => {
const wrapper = document.createElement('div')
wrapper.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 8px;'
const el = document.createElement('div')
el.style.cssText = `width: 80px; height: 80px; background: ${bg}; clip-path: ${clip};`
const label = document.createElement('span')
label.textContent = name
label.style.cssText = 'font-size: 12px; text-align: center; color: #4a5568;'
wrapper.appendChild(el)
wrapper.appendChild(label)
container.appendChild(wrapper)
console.log(`${name}: ${clip.substring(0, 50)}...`)
})Не все элементы дизайна — прямоугольники. Hexagon-аватары, диагональные секции, звёздные рейтинги, волнообразные разделители — всё это делается через clip-path и mask-image.
/* Круг: circle(radius at center-x center-y) */
.avatar {
clip-path: circle(50%); /* Круг по центру */
clip-path: circle(40px at 50% 50%); /* Явный радиус и центр */
}
/* Эллипс */
.ellipse {
clip-path: ellipse(60px 40px at center);
}
/* Прямоугольник с закруглением */
.rounded-clip {
clip-path: inset(10px 20px round 8px);
/* inset(top right bottom left round radius) */
}
/* Полигон — произвольный многоугольник */
.triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.hexagon {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}.star {
clip-path: path('M 50 0 L 61 35 L 98 35 L 68 57 L 79 91 L 50 70 L 21 91 L 32 57 L 2 35 L 39 35 Z');
}path() принимает SVG path data. Мощно, но координаты абсолютные, а не процентные.
.reveal {
clip-path: inset(0 100% 0 0); /* Полностью скрыт справа */
transition: clip-path 0.6s ease;
}
.reveal.visible {
clip-path: inset(0 0% 0 0); /* Полностью виден */
}
/* Hover-эффект: квадрат → круг */
.card {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: clip-path 0.4s ease;
}
.card:hover {
clip-path: circle(50%);
}/* Gradient mask — fade out снизу */
.faded {
mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}
/* Круговая маска */
.vignette {
mask-image: radial-gradient(ellipse at center, black 60%, transparent 100%);
}
/* SVG-маска */
.shaped {
mask-image: url(#my-svg-mask);
}.complex-mask {
mask-image: url(mask1.svg), url(mask2.svg);
mask-composite: subtract; /* add | subtract | intersect | exclude */
}Диагональная секция сайта:
.diagonal-section {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
/* Нижний правый угол — 85%, нижний левый — 100% */
}Волна:
.wave-section {
clip-path: ellipse(100% 55% at 50% 45%);
}clip-path не вызывает перерасчёт layout — браузер просто маскирует уже нарисованный элемент. Анимация clip-path происходит на GPU через compositing, если анимируются только clip-path и transform/opacity.
Генерация clip-path значений для разных форм и применение их к элементам
// Генератор clip-path для разных геометрических форм
function makeHexagon() {
return 'polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)'
}
function makeStar(points = 5) {
const coords = []
for (let i = 0; i < points * 2; i++) {
const angle = (i * Math.PI) / points - Math.PI / 2
const r = i % 2 === 0 ? 50 : 22 // внешний/внутренний радиус в %
const x = 50 + r * Math.cos(angle)
const y = 50 + r * Math.sin(angle)
coords.push(`${x.toFixed(1)}% ${y.toFixed(1)}%`)
}
return `polygon(${coords.join(', ')})`
}
function makeArrow(direction = 'right') {
const shapes = {
right: 'polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%)',
left: 'polygon(100% 20%, 40% 20%, 40% 0%, 0% 50%, 40% 100%, 40% 80%, 100% 80%)',
up: 'polygon(20% 100%, 20% 40%, 0% 40%, 50% 0%, 100% 40%, 80% 40%, 80% 100%)',
}
return shapes[direction] || shapes.right
}
function makeTriangle(type = 'up') {
const shapes = {
up: 'polygon(50% 0%, 0% 100%, 100% 100%)',
down: 'polygon(0% 0%, 100% 0%, 50% 100%)',
right: 'polygon(0% 0%, 100% 50%, 0% 100%)',
}
return shapes[type] || shapes.up
}
// Демонстрация форм
const shapes = [
{ name: 'Шестиугольник', clip: makeHexagon(), bg: '#7b2ff7' },
{ name: 'Звезда 5 лучей', clip: makeStar(5), bg: '#f59e0b' },
{ name: 'Звезда 6 лучей', clip: makeStar(6), bg: '#06b6d4' },
{ name: 'Стрелка →', clip: makeArrow('right'), bg: '#ef4444' },
{ name: 'Треугольник ↑', clip: makeTriangle('up'), bg: '#10b981' },
]
const container = document.createElement('div')
container.style.cssText = 'display: flex; gap: 20px; flex-wrap: wrap; padding: 20px; font-family: sans-serif;'
document.body.appendChild(container)
shapes.forEach(({ name, clip, bg }) => {
const wrapper = document.createElement('div')
wrapper.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 8px;'
const el = document.createElement('div')
el.style.cssText = `width: 80px; height: 80px; background: ${bg}; clip-path: ${clip};`
const label = document.createElement('span')
label.textContent = name
label.style.cssText = 'font-size: 12px; text-align: center; color: #4a5568;'
wrapper.appendChild(el)
wrapper.appendChild(label)
container.appendChild(wrapper)
console.log(`${name}: ${clip.substring(0, 50)}...`)
})Создай галерею из трёх элементов с разными формами через `clip-path`. Первый элемент — шестиугольник (polygon с 6 точками), второй — треугольник, третий — стрелка вправо. Добавь анимацию `transition: clip-path 0.4s` и при наведении меняй форму на круг через `clip-path: circle(50%)`.
Шестиугольник: `polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)`. Треугольник вверх: `polygon(50% 0%, 0% 100%, 100% 100%)`. При наведении: `clip-path: circle(50%)` превратит в круг. `transition: clip-path 0.4s` — плавный переход.