Menghitung Dengan Ukuran Intrinsik

calc-size() adalah fungsi CSS untuk melakukan operasi matematika pada kata kunci ukuran intrinsik seperti auto, min-content, dan fit-content. WAJIB: Gunakan calc-size() hanya jika Anda perlu mengubah ukuran intrinsik dengan penghitungan atau batasan; untuk animasi sederhana berbasis kata kunci (misalnya, 0 ke auto), Anda harus menggunakan interpolate-size: allow-keywords.

Langkah-Langkah Penerapan

  1. Identifikasi Dasar Intrinsik: Tentukan kata kunci intrinsik (auto, min-content, dll.) yang harus menjadi dasar penghitungan Anda.
  2. Tentukan Batasan: Gunakan fungsi matematika CSS seperti clamp(), min(), atau max() dalam argumen kedua untuk menerapkan batasan desain pada ukuran intrinsik.
  3. WAJIB: Berikan Penggantian: Selalu deklarasikan kata kunci atau panjang ukuran standar tepat sebelum properti menggunakan calc-size() untuk memastikan tata letak tetap berfungsi di browser yang tidak didukung.
  4. Terapkan Properti Logis: Gunakan properti logis seperti inline-size atau block-size secara default untuk memastikan penghitungan sesuai dengan mode penulisan dokumen.
  5. Opsional: Progressive Enhancement: Gabungkan logika tata letak atau animasi yang kompleks dalam blok @supports (inline-size: calc-size(auto, size + 0px)) untuk memberikan fitur lanjutan hanya ke browser yang mampu.

Sintaksis Dasar

/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: min-content;
  
  /* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
  inline-size: calc-size(min-content, size + 2rem);
}

Argumen Dasar yang Valid (<calc-size-basis>)

Argumen pertama menentukan ukuran "dasar" untuk penghitungan.

Kata Kunci Standar:

  • auto: Ukuran default untuk elemen.
  • min-content: Ukuran terkecil yang dapat diambil elemen tanpa meluap.
  • max-content: Ukuran yang digunakan elemen agar semua konten muat dalam satu baris.
  • fit-content: Setara dengan clamp(min-content, auto, max-content).
  • content: Hanya valid jika calc-size() digunakan dalam properti flex-basis.

Argumen Khusus:

  • any: Basis generik yang digunakan saat jenis intrinsik tertentu tidak diketahui atau saat menyusun penghitungan.
  • calc-size() Bertingkat: Memungkinkan penghitungan bersyarat atau multi-langkah.
  • <calc-sum>: Panjang, persentase, atau ekspresi matematika tertentu (misalnya, 100px atau 20%). Jika nilai tetap digunakan sebagai dasar, kata kunci size masih tersedia (tetapi hanya dalam argumen kedua) dan mewakili nilai yang di-resolve dari dasar tersebut.

WAJIB: Kata kunci size tidak valid dalam argumen pertama (<calc-size-basis>) itu sendiri. Ini adalah variabel lokal yang hanya ada untuk merujuk kembali ke basis dari dalam argumen kedua (<calc-sum>).

Argumen Penghitungan yang Valid (<calc-sum>)

Argumen kedua adalah ekspresi matematika.

  • Biasanya, kata kunci size digunakan untuk merujuk ke nilai dasar.
  • Meskipun kata kunci size secara teknis bersifat opsional, menghilangkannya berarti penghitungan akan menghasilkan nilai tetap, yang sepenuhnya mengabaikan basis.
  • Formula ini dapat menyertakan operator matematika standar (+, -, *, /).
  • Nilai ini dapat mencakup fungsi matematika CSS seperti clamp(), min(), max(), dan round().
  • WAJIB: calc-size() hanya mengizinkan satu nilai ukuran intrinsik (dasar) dalam setiap penghitungan. Anda tidak dapat menggabungkan kata kunci ukuran intrinsik dalam panggilan calc-size() yang sama.

Kasus Penggunaan

Menganimasikan ke dan dari Ukuran Intrinsik

Secara default, browser tidak dapat melakukan interpolasi antara panjang (misalnya, 0px) dan kata kunci intrinsik (misalnya, auto). Menggabungkan kata kunci dalam calc-size() akan membuatnya menjadi nilai yang dapat diinterpolasi.

Memilih Alat yang Tepat untuk Animasi

  • WAJIB: Gunakan interpolate-size: allow-keywords: Untuk animasi sederhana ke atau dari ukuran intrinsik (misalnya, height: 0 ke height: auto) tanpa modifikasi matematis. Ini adalah pendekatan yang diperlukan untuk interpolasi kata kunci sederhana dan idealnya harus diterapkan secara global melalui :root.

    :root {
      /* Best practice: Enable keyword interpolation globally */
      interpolate-size: allow-keywords;
    }
    
    .item {
      height: 0;
      transition: height 0.3s ease;
    }
    
    .item.open {
      /* Simple interpolation from 0 to auto now works without calc-size() */
      height: auto;
    }
    
  • Gunakan calc-size(): HANYA saat Anda perlu melakukan penghitungan matematika pada ukuran intrinsik selama transisi (misalnya, menambahkan padding atau membatasi ukuran).

.accordion-content {
  display: block;
  overflow: hidden;
  /* MANDATORY: Fallback value for closed state */
  block-size: 0;
  transition: block-size 0.3s ease-out;
}

.accordion-content.open {
  /* MANDATORY: Fallback value for open state */
  block-size: auto;

  /* 
    DO: Use calc-size(auto, ...) to enable animation from 0 to the element's 
    intrinsic size while doing a calculation (in this case, adding a space of 2rem).
  */
  block-size: calc-size(auto, size + 2rem);
}

WAJIB: Interpolasi antara dua kata kunci ukuran intrinsik tidak dapat dilakukan secara langsung. Salah satu ujung transisi harus berupa panjang atau persentase.

Menghormati Preferensi Gerakan Pengguna

Animasi yang mengubah ukuran area tata letak yang besar dapat sangat mengganggu bagi pengguna dengan gangguan vestibular. WAJIB: Selalu hormati preferensi gerakan pengguna dengan menggunakan kueri media prefers-reduced-motion untuk menyederhanakan atau meminimalkan animasi yang tidak penting. Strategi umum mencakup menonaktifkan gerakan sepenuhnya, mengurangi durasi, atau mengganti pergeseran tata letak dengan transisi opasitas yang halus.

.accordion-content {
  opacity: 0;
  transition: block-size 0.3s ease, opacity 0.3s ease;
}

.accordion-content.open {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .accordion-content {
    /* 
       EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
       Setting the block-size instantly and transitioning opacity 
       provides a clear state change without large-scale motion.
    */
    transition: opacity 1.5s ease;
  }

  .accordion-content.open {
    /* Jump the size instantly */
    block-size: auto;
  }
}

Menerapkan Batasan ke Ukuran Intrinsik

Anda dapat menggunakan calc-size() dengan fungsi matematika CSS apa pun—seperti min(), max(), clamp(), atau round()—untuk memastikan ukuran intrinsik elemen tetap berada dalam batas desain.

.dynamic-container {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: fit-content;

  /* 
    DO: Establish a dynamic size based on content, while:
    1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
    2. Modifying the intrinsic size with fixed or relative offsets
  */
  inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}

Pertimbangan Penting

  • Masalah Persentase: Persentase di dalam <calc-sum> dihitung berdasarkan ukuran penampung, bukan kata kunci size. Misalnya, calc-size(auto, size + 10%) menambahkan 10% lebar induk ke lebar auto elemen, yang dapat menyebabkan hasil yang tidak terduga atau overflow.
  • Persyaratan penghitungan: WAJIB: Gunakan interpolate-size: allow-keywords, bukan calc-size() untuk animasi sederhana (misalnya, 0 hingga auto). calc-size() hanya boleh digunakan jika tata letak memerlukan penyesuaian matematika dinamis pada dasar intrinsik.
  • Catatan Performa: Menganimasikan properti model kotak seperti inline-size atau block-size akan memicu penghitungan ulang tata letak, yang dapat memerlukan banyak resource. Gunakan animasi calc-size() terutama untuk elemen penting tata letak yang tidak dapat digantikan oleh alternatif non-tata letak.

Strategi penggantian

calc-size() dan interpolate-size adalah progressive enhancement. Di browser yang tidak mendukungnya, properti akan diabaikan dan tata letak akan tetap berfungsi, meskipun animasi ke kata kunci intrinsik akan melompat, bukan bertransisi. Selalu berikan kata kunci atau panjang standar sebagai pengganti.

.element {
  /* Fallback for browsers that don't support calc-size() */
  inline-size: fit-content; 
  /* Modern browsers will override the fallback */
  inline-size: calc-size(fit-content, size + 2rem);
}

Penggantian Animasi dan Transisi

Di browser yang tidak mendukung calc-size() atau interpolate-size, transisi yang melibatkan kata kunci ukuran intrinsik akan gagal diinterpolasi.

  • Degradasi Halus: Penggantian default adalah "lompatan instan" di antara status (misalnya, dari 0 ke auto). Hal ini sering kali dapat diterima karena tata letak tetap berfungsi.
  • Pengalaman yang Ditingkatkan: Gunakan @supports untuk menerapkan logika tata letak yang kompleks atau gaya tambahan yang hanya masuk akal jika animasi intrinsik yang lancar dapat dilakukan.
  • Hindari pengukuran berbasis JS: Meskipun Anda dapat menggunakan JavaScript untuk mengukur elemen dan menganimasikan dimensinya secara manual, hal ini sering kali tidak diperlukan dan dapat menyebabkan layout thrashing. Mengandalkan "lompatan instan" native adalah penggantian yang direkomendasikan untuk aplikasi web modern.

Untuk animasi, pengalaman penggantian akan langsung beralih ke ukuran akhir. Untuk mendeteksi dukungan di CSS atau JavaScript:

/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
  .element {
    /* Apply advanced logic only when supported */
  }
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
  // Apply advanced sizing or animations
}