Variabel CSS - Mengapa Anda harus peduli?

Variabel CSS, yang lebih dikenal sebagai properti khusus CSS, akan hadir di Chrome 49. Fungsi ini dapat berguna untuk mengurangi pengulangan di CSS, dan juga untuk efek runtime yang efektif seperti pengalihan tema dan berpotensi memperluas/mem-polyfill fitur CSS mendatang.

Kekacauan CSS

Saat mendesain aplikasi, praktik umum adalah menyisihkan serangkaian warna merek yang akan digunakan kembali agar tampilan aplikasi tetap konsisten. Sayangnya, mengulangi nilai warna ini berulang kali di CSS Anda tidak hanya merepotkan, tetapi juga rentan error. Jika, pada suatu saat, salah satu warna perlu diubah, Anda dapat mengabaikan kehati-hatian dan “menemukan dan mengganti” semuanya, tetapi pada project yang cukup besar, hal ini dapat dengan mudah menjadi berbahaya.

Akhir-akhir ini, banyak developer beralih ke preprocessor CSS seperti SASS atau LESS yang memecahkan masalah ini melalui penggunaan variabel preprocessor. Meskipun alat ini telah sangat meningkatkan produktivitas developer, variabel yang mereka gunakan memiliki kelemahan utama, yaitu bersifat statis dan tidak dapat berubah saat runtime. Menambahkan kemampuan untuk mengubah variabel saat runtime tidak hanya membuka peluang untuk hal-hal seperti tema aplikasi dinamis, tetapi juga memiliki implikasi utama untuk desain responsif dan potensi untuk melakukan polyfill pada fitur CSS mendatang. Dengan rilis Chrome 49, kemampuan ini kini tersedia dalam bentuk properti khusus CSS.

Ringkasan properti kustom

Properti kustom menambahkan dua fitur baru ke toolbox CSS:

  • Kemampuan penulis untuk menetapkan nilai arbitrer ke properti dengan nama yang dipilih penulis.
  • Fungsi var(), yang memungkinkan penulis menggunakan nilai ini di properti lain.

Berikut adalah contoh singkat untuk menunjukkan

:root {
    --main-color: #06c;
}

#foo h1 {
    color: var(--main-color);
}

--main-color adalah properti kustom yang ditentukan penulis dengan nilai #06c. Perhatikan bahwa semua properti kustom dimulai dengan dua tanda hubung.

Fungsi var() mengambil dan mengganti dirinya sendiri dengan nilai properti kustom, sehingga menghasilkan color: #06c; Selama properti kustom ditentukan di suatu tempat dalam stylesheet, properti tersebut akan tersedia untuk fungsi var.

Sintaksnya mungkin terlihat sedikit aneh pada awalnya. Banyak developer bertanya, "Mengapa tidak menggunakan $foo untuk nama variabel?" Pendekatan ini dipilih secara khusus agar sesefleksibel mungkin dan berpotensi memungkinkan makro $foo di masa mendatang. Untuk mengetahui latar belakangnya, Anda dapat membaca postingan ini dari salah satu penulis spesifikasi, Tab Atkins.

Sintaksis properti kustom

Sintaksis untuk properti kustom cukup sederhana.

--header-color: #06c;

Perhatikan bahwa properti kustom peka huruf besar/kecil, sehingga --header-color dan --Header-Color adalah properti kustom yang berbeda. Meskipun mungkin terlihat sederhana, sintaksis yang diizinkan untuk properti kustom sebenarnya cukup permisif. Misalnya, berikut adalah properti kustom yang valid:

--foo: if(x > 5) this.width = 10;

Meskipun tidak berguna sebagai variabel, karena tidak valid dalam properti normal, variabel ini berpotensi dapat dibaca dan ditindaklanjuti dengan JavaScript saat runtime. Artinya, properti kustom memiliki potensi untuk membuka semua jenis teknik menarik yang saat ini tidak dapat dilakukan dengan preprocessor CSS saat ini. Jadi, jika Anda berpikir “menguap Saya sudah memiliki SASS, jadi siapa yang peduli…”, pertimbangkan kembali. Ini bukan variabel yang biasa Anda gunakan.

Cascade

Properti kustom mengikuti aturan kaskade standar, sehingga Anda dapat menentukan properti yang sama pada tingkat kekhususan yang berbeda

:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id="alert">
    While I got red set directly on me!
    <p>I’m red too, because of inheritance!</p>
</div>

Artinya, Anda dapat memanfaatkan properti kustom di dalam kueri media untuk membantu desain responsif. Salah satu kasus penggunaannya adalah memperluas margin di sekitar elemen pemisahan utama saat ukuran layar meningkat:

:root {
    --gutter: 4px;
}

section {
    margin: var(--gutter);
}

@media (min-width: 600px) {
    :root {
    --gutter: 16px;
    }
}

Penting untuk diperhatikan bahwa cuplikan kode di atas tidak dapat dilakukan menggunakan praprosesor CSS saat ini yang tidak dapat menentukan variabel di dalam kueri media. Kemampuan ini membuka banyak potensi.

Anda juga dapat memiliki properti kustom yang memperoleh nilainya dari properti kustom lain. Hal ini dapat sangat berguna untuk tema:

:root {
    --primary-color: red;
    --logo-text: var(--primary-color);
}

Fungsi var()

Untuk mengambil dan menggunakan nilai properti kustom, Anda harus menggunakan fungsi var(). Sintaksis untuk fungsi var() terlihat seperti ini:

var(<custom-property-name> [, <declaration-value> ]? )

Dengan <custom-property-name> adalah nama properti kustom yang ditentukan penulis, seperti --foo, dan <declaration-value> adalah nilai penggantian yang akan digunakan saat properti kustom yang dirujuk tidak valid. Nilai penggantian dapat berupa daftar yang dipisahkan koma, yang akan digabungkan menjadi satu nilai. Misalnya, var(--font-stack, "Roboto", "Helvetica"); menentukan penggantian "Roboto", "Helvetica". Perlu diingat bahwa nilai singkatan, seperti yang digunakan untuk margin dan padding, tidak dipisahkan koma, sehingga penggantian yang sesuai untuk padding akan terlihat seperti ini.

p {
    padding: var(--pad, 10px 15px 20px);
}

Dengan menggunakan nilai penggantian ini, penulis komponen dapat menulis gaya defensif untuk elemennya:

/* In the component’s style: */
.component .header {
    color: var(--header-color, blue);
}
.component .text {
    color: var(--text-color, black);
}

/* In the larger application’s style: */
.component {
    --text-color: #080;
    /* header-color isn’t set,
        and so remains blue,
        the fallback value */
}

Teknik ini sangat berguna untuk tema Komponen Web yang menggunakan Shadow DOM, karena properti kustom dapat melintasi batas bayangan. Penulis Komponen Web dapat membuat desain awal menggunakan nilai penggantian, dan mengekspos "hook" tema dalam bentuk properti kustom.

<!-- In the web component's definition: -->
<x-foo>
    #shadow
    <style>
        p {
        background-color: var(--text-background, blue);
        }
    </style>
    <p>
        This text has a yellow background because the document styled me! Otherwise it
        would be blue.
    </p>
</x-foo>
/* In the larger application's style: */
x-foo {
    --text-background: yellow;
}

Saat menggunakan var(), ada beberapa hal yang perlu diperhatikan. Variabel tidak boleh berupa nama properti. Misalnya:

.foo {
    --side: margin-top;
    var(--side): 20px;
}

Namun, hal ini tidak setara dengan menetapkan margin-top: 20px;. Sebagai gantinya, deklarasi kedua tidak valid dan ditampilkan sebagai error.

Demikian pula, Anda tidak dapat (secara naif) membuat nilai yang sebagiannya disediakan oleh variabel:

.foo {
    --gap: 20;
    margin-top: var(--gap)px;
}

Sekali lagi, hal ini tidak setara dengan menetapkan margin-top: 20px;. Untuk membuat nilai, Anda memerlukan hal lain: fungsi calc().

Membuat nilai dengan calc()

Jika Anda belum pernah menggunakannya sebelumnya, fungsi calc() adalah alat kecil yang berguna yang memungkinkan Anda melakukan penghitungan untuk menentukan nilai CSS. Fungsi ini didukung di semua browser modern, dan dapat digabungkan dengan properti kustom untuk membuat nilai baru. Contoh:

.foo {
    --gap: 20;
    margin-top: calc(var(--gap) * 1px); /* niiiiice */
}

Menggunakan properti kustom di JavaScript

Untuk mendapatkan nilai properti kustom saat runtime, gunakan metode getPropertyValue() dari objek CSSStyleDeclaration yang dihitung.

/* CSS */
:root {
    --primary-color: red;
}

p {
    color: var(--primary-color);
}
<!-- HTML -->
<p>I’m a red paragraph!</p>
/* JS */
var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--primary-color')).trim();
// value = 'red'

Demikian pula, untuk menetapkan nilai properti kustom saat runtime, gunakan metode setProperty() dari objek CSSStyleDeclaration.

/* CSS */
:root {
    --primary-color: red;
}

p {
    color: var(--primary-color);
}
<!-- HTML -->
<p>Now I’m a green paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'green');

Anda juga dapat menetapkan nilai properti kustom untuk merujuk ke properti kustom lain saat runtime menggunakan fungsi var() dalam panggilan ke setProperty().

/* CSS */
:root {
    --primary-color: red;
    --secondary-color: blue;
}
<!-- HTML -->
<p>Sweet! I’m a blue paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'var(--secondary-color)');

Karena properti kustom dapat merujuk ke properti kustom lain dalam lembar gaya, Anda dapat membayangkan bagaimana hal ini dapat menyebabkan berbagai efek runtime yang menarik.

Dukungan browser

Saat ini, Chrome 49, Firefox 42, Safari 9.1, dan iOS Safari 9.3 mendukung properti kustom.

Demo

Coba contoh untuk melihat sekilas semua teknik menarik yang kini dapat Anda manfaatkan berkat properti kustom.

Bacaan lebih lanjut

Jika Anda tertarik untuk mempelajari properti kustom lebih lanjut, Philip Walton dari tim Google Analytics telah menulis pengantar tentang alasan ia antusias dengan properti kustom dan Anda dapat memantau progresnya di browser lain di chromestatus.com.