CSS / clip / Pemotongan persegi panjang dan migrasi ke clip-path

clip adalah properti CSS legacy yang membatasi bagian yang terlihat dari suatu elemen menjadi persegi panjang. Ini diterapkan pada elemen dengan position: absolute atau position: fixed dan sudah usang, jadi lebih disarankan menggunakan clip-path pada kode baru. Saat memigrasi kode yang ada, bedakan koordinat batas di rect() dari jarak ke dalam di inset().

Syarat dan nilai utama

Pemotongan menyembunyikan gambar di luar suatu area. Ini berbeda dari mengedit file gambar asli atau benar-benar mengurangi lebar dan tinggi elemen. Nilai awal dari clip adalah auto, dan nilai ini tidak diwariskan. Mengatur hanya position: relative tidak membuat clip lama berlaku.

Nilai atau kondisi Arti dan pilihan
auto Tidak menerapkan persegi panjang pemotongan melalui properti ini.
rect(top, right, bottom, left) Tentukan batas atas, kanan, bawah, dan kiri menggunakan panjang atau auto. Ini adalah sintaks lama yang dipisahkan koma.
position: absolute / position: fixed Kondisi penempatan untuk clip. Contoh menggunakan posisi absolute.
clip-path: inset(20px) Menampilkan persegi panjang 20px ke dalam dari setiap tepi. Ini juga dapat digunakan pada elemen yang in-flow.

Clip rect lama tidak menerima persentase. Nilai lengkap clip: auto juga berbeda dari rect(auto, auto, auto, auto). Yang terakhir memotong di tepi border bagian dalam, sehingga keturunan yang meluap dapat memperlihatkan perbedaannya. MDN sintaks clip dan kondisi penerapannya

Membandingkan area asli dan terpotong melalui contoh lengkap

Simpan kode lengkap berikut sebagai clip-example.html dalam UTF-8 dan buka di browser. Tidak perlu gambar, pustaka, atau server eksternal. Simpan gaya demonstrasi ini di file ini daripada menempelkannya ke stylesheet situs bersama. Bandingkan ketiga kotak, lalu ubah satu nilai sekaligus, simpan dan muat ulang.

<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Perbandingan clip dan clip-path</title>
  <style>
    body { margin: 0; padding: 16px; font: 16px/1.6 sans-serif; }
    main { max-width: 760px; margin: auto; }
    h1 { font-size: 1.5rem; }
    h2 { font-size: 1rem; }
    .samples { display: flex; flex-wrap: wrap; gap: 24px; }
    .frame { position: relative; width: 200px; height: 120px;
      background: #e5e7eb; outline: 1px solid #666; }
    .target { width: 100%; height: 100%; padding: 0; border: 0;
      background: linear-gradient(135deg, #006c9c, #ffd166); }
    .legacy { position: absolute; top: 0; left: 0;
      clip: rect(20px, 180px, 100px, 20px); }
    .modern { clip-path: inset(20px); }
  </style>
</head>
<body>
  <main>
    <h1>Perbandingan clip dan clip-path</h1>
    <div class="samples">
      <section><h2>clip: auto</h2>
        <div class="frame"><div class="target"></div></div></section>
      <section><h2>clip: rect(20px, 180px, 100px, 20px)</h2>
        <div class="frame"><div class="target legacy"></div></div></section>
      <section><h2>clip-path: inset(20px)</h2>
        <div class="frame"><div class="target modern"></div></div></section>
    </div>
  </main>
</body>
</html>

Kotak pertama adalah referensi, menampilkan seluruh gradien 200×120px. Kotak kedua dan ketiga harus menunjukkan wilayah 160×80px setelah mengecualikan 20px di setiap tepi. Latar belakang abu-abu dan garis besar milik bingkai terpisah, jadi ukuran kotak asli tetap terlihat. Pada jendela yang sempit, kotak perbandingan akan membungkus ke baris lain.

Mengubah koordinat rect menjadi jarak inset

Kedua deklarasi menghasilkan wilayah yang terlihat sama karena angka-angka mereka memiliki arti yang berbeda. Aturan-aturan ini sesuai dengan .legacy dan .modern dalam contoh lengkap.

.legacy {
  position: absolute;
  clip: rect(20px, 180px, 100px, 20px);
}
.modern {
  clip-path: inset(20px);
}

Dalam rect lama, atas dan bawah diukur dari tepi dalam atas border; kiri dan kanan diukur dari tepi dalam kiri border. Koordinat kanan 180px tidak berarti mengurangi 180px dari sisi kanan. Empat nilai inset sebaliknya diukur ke dalam dari tepi masing-masing, menggunakan border-box kecuali jika kotak referensi lain ditentukan. Target dalam contoh ini tidak memiliki padding atau border, sehingga perbedaan kotak referensi tersebut tidak memengaruhi perbandingan.

Tepi koordinat batas rect jarak inset
Atas 20px 20px
Kanan 180px 200 − 180 = 20px
Bawah 100px 120 − 100 = 20px
Kiri 20px 20px

Untuk kotak dengan lebar W dan tinggi H tanpa padding atau border, rect(t, r, b, l) sesuai dengan inset(t, W − r, H − b, l). Dalam CSS nyata, masukkan panjang yang dihitung daripada menyalin ekspresi penjelasan seperti W − r. Jika ada border, padding, atau kotak referensi yang berbeda, selaraskan sistem koordinat terlebih dahulu. MDN referensi kotak dan bentuk clip-path

Mengubah ukuran elemen dan membandingkan

Pertama ubah hanya .frame menjadi lebar 300px dan tinggi 180px dalam contoh lengkap. Tetap menggunakan koordinat rect lama akan meninggalkan area terlihat 160×80px, sementara inset(20px) sekarang menyisakan 260×140px dengan mengecualikan 20px dari setiap sisi kotak yang lebih besar. Bandingkan mengapa angka yang sama tidak menjamin hasil klip yang sama.

Untuk menyamakan kedua metode lagi, ubah batas kanan .legacy menjadi 280px dan batas bawah menjadi 160px. Ganti dua aturan ini dalam contoh lengkap sebagai berikut. Biarkan deklarasi .modern tidak berubah.

.frame {
  width: 300px;
  height: 180px;
}
.legacy {
  clip: rect(20px, 280px, 160px, 20px);
}

Kedua metode sekarang seharusnya meninggalkan area 260×140px. Setelah membandingkan, kembalikan .frame ke 200×120px dan rect ke 20px, 180px, 100px, 20px. Untuk mempertahankan jarak dalam yang sama dalam kotak responsif, inset mengekspresikan maksud lebih langsung daripada terus-menerus menghitung ulang batas tetap.

Pemotongan, tata letak, dan aksesibilitas

Pemotongan dengan clip-path umumnya meninggalkan ruang tata letak elemen tidak berubah. .modern pada contoh menempati 200×120px dan hanya area yang dicat menjadi lebih kecil. Elemen .legacy berada di luar aliran normal karena posisi absolut; induknya .frame memesan ruang perbandingan. Bedakan efek posisi tersebut dari pemotongan itu sendiri.

Untuk kode baru, pertimbangkan bentuk clip-path seperti inset untuk persegi panjang atau circle untuk lingkaran. Ketika tujuannya adalah menyembunyikan konten yang meluap atau menawarkan scroll, pertimbangkan peran terpisah dari overflow. Nilai clip-path selain none juga dapat membuat konteks tumpukan, jadi periksa elemen yang tumpang tindih setelah migrasi. CSS Masking pada pemotongan dan geometri elemen

Pemotongan bukanlah kontrol akses atau perlindungan privasi. Teks yang disembunyikan dapat tetap berada dalam dokumen, dan perlakuannya oleh teknologi bantu perlu diperiksa secara terpisah. Jangan memotong tombol, input, informasi penting, atau indikator fokus keyboard dengan cara yang mencegah pengguna mengoperasikan antarmuka. Sediakan cara untuk membaca konten saat memperbesar atau menggunakan navigasi sentuh dan keyboard.

Jika pemotongan tidak bekerja sesuai harapan

  • Periksa posisi yang dihitung dan klip elemen yang dipilih di alat pengembang. Posisi relatif atau statis tidak memenuhi kondisi clip lama. Dalam contoh, ubah hanya position .legacy menjadi relative, bandingkan apakah pemotongan hilang, lalu kembalikan ke absolute.
  • Urutan rect adalah atas, kanan, bawah, kiri. Jika kanan kurang dari kiri atau bawah kurang dari atas, persegi panjang yang diharapkan tidak akan tetap ada. Periksa apakah koordinat lama dipertahankan setelah mengubah lebar atau tinggi.
  • Overflow, clip-path, atau aturan pemotongan lain dari elemen leluhur (ancestor) dapat lebih lanjut mengurangi wilayah yang terlihat. Nonaktifkan dan aktifkan kembali deklarasi secara individu di alat pengembang untuk mengisolasi penyebabnya.
  • Saat mengganti clip dengan clip-path, bandingkan posisi, kotak referensi, border, padding, tumpukan, dan indikator fokus. rect() legacy yang digunakan oleh clip dan bentuk rect() yang lebih baru di clip-path memiliki sintaks yang berbeda; nama yang cocok tidak menjadikan nilainya dapat dipertukarkan.