Variabel CSS - Mengapa Anda harus peduli?

Variabel CSS, yang lebih akurat dikenal sebagai properti khusus CSS, akan tersedia di Chrome 49. Fitur ini dapat berguna untuk mengurangi pengulangan dalam CSS, dan juga untuk efek runtime yang kuat seperti pengalihan tema dan berpotensi memperluas/memperluas fitur CSS di masa mendatang.

Kekacauan CSS

Saat mendesain aplikasi, praktik yang umum adalah menyisihkan satu set warna merek yang akan digunakan kembali untuk menjaga tampilan aplikasi tetap konsisten. Sayangnya, mengulangi nilai warna ini berulang kali di CSS tidak hanya membuat Anda repot, tetapi juga rentan terhadap error. Jika suatu saat salah satu warna perlu diubah, Anda dapat berhati-hati dan memilih opsi "temukan dan ganti" semua hal, tetapi pada project yang cukup besar, hal ini bisa dengan mudah menjadi berbahaya.

Belakangan ini, banyak developer beralih ke praprosesor CSS seperti SASS atau LESS, yang mengatasi masalah ini melalui penggunaan variabel preprosesor. Meskipun alat ini telah sangat meningkatkan produktivitas developer, variabel yang digunakan memiliki kelemahan utama, yaitu variabel tersebut bersifat statis dan tidak dapat diubah saat runtime. Menambahkan kemampuan untuk mengubah variabel saat runtime tidak hanya membuka pintu untuk hal-hal seperti tema aplikasi dinamis, tetapi juga memiliki konsekuensi besar bagi desain responsif dan potensi untuk mem-polyfill fitur CSS pada masa mendatang. Dengan dirilisnya Chrome 49, kemampuan ini kini tersedia dalam bentuk properti kustom CSS.

Ringkasan properti khusus

Properti khusus menambahkan dua fitur baru ke toolbox CSS kami:

  • 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 ini adalah contoh singkat untuk mendemonstrasikan

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

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

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

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

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

Sintaksis properti kustom

Sintaksis untuk properti kustom sangat sederhana.

--header-color: #06c;

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

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

Meskipun tidak berguna sebagai variabel, karena tidak valid di properti normal, metode ini berpotensi untuk dibaca dan ditindaklanjuti dengan JavaScript saat runtime. Artinya, properti khusus berpotensi membuka semua jenis teknik menarik yang saat ini tidak dimungkinkan dengan praprosesor CSS saat ini. Jadi jika Anda berpikir “yawn, saya punya SASS, jadi siapa yang peduli...” maka coba lihat lagi. Ini bukanlah variabel yang biasa Anda gunakan.

Air terjun

Properti khusus mengikuti aturan menurun 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>

Ini berarti Anda dapat memanfaatkan properti khusus di dalam kueri media untuk membantu desain yang responsif. Salah satu kasus penggunaan adalah memperluas margin di sekitar elemen pembagian utama saat ukuran layar meningkat:

:root {
    --gutter: 4px;
}

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

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

Penting untuk diketahui bahwa cuplikan kode di atas tidak mungkin menggunakan praprosesor CSS saat ini yang tidak dapat menentukan variabel di dalam kueri media. Memiliki kemampuan ini akan membuka banyak potensi.

Anda juga dapat memiliki properti khusus yang memperoleh nilainya dari properti khusus lainnya. Hal ini bisa sangat berguna untuk penerapan tema:

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

Fungsi var()

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

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

<custom-property-name> adalah nama properti kustom yang ditentukan penulis, seperti --foo, dan <declaration-value> adalah nilai penggantian yang digunakan saat properti kustom yang direferensikan 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 singkat, 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 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 memberi tema Komponen Web yang menggunakan DOM Bayangan, karena properti khusus dapat melewati batas bayangan. Penulis Komponen Web dapat membuat desain awal menggunakan nilai penggantian, dan menampilkan “hook” 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 kesalahan yang harus diperhatikan. Variabel tidak boleh berupa nama properti. Misalnya:

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

Namun, hal ini tidak sama dengan menyetel margin-top: 20px;. Sebaliknya, 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, ini tidak sama dengan menetapkan margin-top: 20px;. Untuk membuat nilai, Anda memerlukan hal lain: fungsi calc().

Membangun nilai dengan calc()

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

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

Menangani properti khusus di JavaScript

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

/* 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 khusus 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 khusus untuk merujuk ke properti khusus lainnya saat runtime dengan 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 lainnya di stylesheet, Anda dapat membayangkan bagaimana hal ini dapat menghasilkan semua jenis efek runtime yang menarik.

Dukungan browser

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

Demo

Cobalah contoh ini untuk melihat sekilas semua teknik menarik yang kini dapat Anda manfaatkan berkat properti khusus.

Bacaan lebih lanjut

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