Menggunakan shape() untuk pemangkasan responsif

Dipublikasikan: 8 April 2025

Properti clip-path memungkinkan Anda mengubah bentuk elemen dengan memotong ke lingkaran, poligon, atau bahkan jalur SVG. Namun, sebelum Chrome 135 dan Safari 18.4, Anda harus memilih antara poligon responsif dan bentuk yang lebih kompleks yang tidak responsif menggunakan jalur SVG. Dengan fungsi shape() baru, clip-path dapat menggunting elemen ke bentuk non-poligon yang juga responsif.

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: 148.
  • Safari: 18.4.

Source

Membuat bentuk bendera

Sebagai contoh, bandingkan pembuatan bentuk bendera dengan clip-path: path() dan clip-path: shape().

Bentuk bendera hijau dengan garis melengkung di bagian atas dan bawah.

Bentuk bendera tidak persis seperti poligon, karena batas atas dan bawahnya adalah kurva Bézier kubik, bukan garis lurus atau sudut bulat.

Buat tanda dengan clip-path: path()

Bentuk seperti bendera ini dapat direpresentasikan menggunakan jalur 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");
}

Untuk menguraikannya, jalur SVG adalah serangkaian perintah jalur:

  1. Pindahkan ke 0, 20.
  2. Kurva ke 100, 20, menggunakan titik kontrol (25,0 dan 75, 40).
  3. Garis vertikal hingga 80.
  4. Kurva ke 0, 80, menggunakan titik kontrol (75,100 dan 25,50).
  5. Tutup jalur (garis ke 0,20).

Kode ini akan menggambar bentuk bendera, tetapi semua unitnya dalam piksel. SVG dapat menskalakan piksel tersebut ke kotak tampilan, tetapi dengan cara yang akan selalu terlihat seperti skala geometris dari seluruh bentuk.

Misalnya, jika Anda ingin seluruh persegi diskalakan, tetapi mempertahankan tinggi dan lebar kurva 20 px, SVG tidak akan dapat melakukannya.

Buat tanda dengan shape()

Bandingkan hasil yang sama menggunakan shape(). Fungsi bentuk menerima serangkaian perintah, mirip dengan perintah jalur SVG. Namun, perintah ini menerima panjang dan persentase CSS, dalam unit CSS apa pun.

CSS berikut mengonversi bendera shape() dengan unit persentase:

.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
  );
}

Membuatnya responsif

Dengan berbagai panjang CSS yang tersedia, Anda dapat memilih panjang yang akan digunakan untuk setiap koordinat.

Misalnya, untuk membuat seluruh ukuran skala bendera berdasarkan ukuran elemen, tetapi menjaga tinggi kurva tetap konstan, Anda dapat melakukan hal berikut:

.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
  );
}

Menambahkan properti dan animasi kustom

Dengan bentuk yang kini ditentukan dalam CSS, Anda juga dapat menggunakan properti kustom untuk mempermudah manipulasi tinggi:

.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
  )
}

Anda bahkan dapat menganimasikan properti CSS menggunakan deskriptor @property, dan mengapitnya agar tidak melampaui batas:

@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
  )
}

Coba demo

Di Chrome 135 atau Safari 18.4, Anda dapat melihat bentuk bendera yang dianimasikan yang dibuat menggunakan clip-path: shape() di demo CodePen ini.

Ringkasan

clip-path: shape() memungkinkan Anda memangkas elemen menggunakan bentuk arbitrer dan responsif, yang sebelumnya hanya dapat dilakukan menggunakan teknik seperti gradien kerucut atau SVG yang dibuat JavaScript.

Periksa spesifikasi untuk mengetahui sintaksis lengkapnya.

Saat ini, fitur ini hanya berfungsi untuk clip-path. Pada masa mendatang, kami berencana menggunakan bentuk semacam ini untuk menetapkan bentuk batas elemen, yang akan memungkinkan lebih banyak cara ekspresi non-persegi panjang.