CSS Değişkenleri: Neden önemsemelisiniz?

Daha doğru bir ifadeyle CSS özel özellikleri olarak bilinen CSS değişkenleri, Chrome 49'a eklendi. Bunlar, CSS'deki tekrarları azaltmanın yanı sıra tema değiştirme gibi güçlü çalışma zamanı efektlerinde ve gelecekteki CSS özelliklerini artırma/çoklu doldurmada kullanılabilir.

CSS karmaşıklığı

Uygulama tasarlanırken, uygulamanın görünümünü tutarlı tutmak için yeniden kullanılacak bir dizi marka rengi ayırmak yaygın bir uygulamadır. Maalesef bu renk değerlerini CSS'nizde tekrar tekrar yazmak hem zahmetli hem de hatalara açıktır. Bir noktada renklerden birinin değiştirilmesi gerekirse tüm öğeleri "bul ve değiştir" seçeneğiyle değiştirebilirsiniz ancak bu işlem, yeterince büyük bir projede tehlikeli olabilir.

Son zamanlarda birçok geliştirici, önişleyici değişkenleri kullanarak bu sorunu çözen SASS veya LESS gibi CSS önişleyicilerine yöneldi. Bu araçlar geliştirici üretkenliğini büyük ölçüde artırsa da kullandıkları değişkenler önemli bir dezavantaja sahiptir. Bu değişkenler statiktir ve çalışma zamanında değiştirilemez. Değişkenleri çalışma zamanında değiştirme özelliğinin eklenmesi, yalnızca dinamik uygulama temaları gibi işlevlere kapı açmakla kalmaz, aynı zamanda duyarlı tasarım ve gelecekteki CSS özelliklerini doldurma potansiyeli açısından da önemli sonuçlar doğurur. Chrome 49'un yayınlanmasıyla birlikte bu özellikler artık CSS özel özellikleri biçiminde kullanılabilir.

Özel özellikler hakkında

Özel mülkler, CSS araç kutumuza iki yeni özellik ekler:

  • Yazarın, yazar tarafından seçilen bir ada sahip bir mülke keyfi değerler atayabilmesi.
  • Yazarın bu değerleri diğer özelliklerde kullanmasına olanak tanıyan var() işlevi.

Şimdi, Çevik yaklaşımın

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

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

--main-color, değeri #06c olan yazar tarafından tanımlanmış bir özel özelliktir. Tüm özel mülklerin iki kısa çizgiyle başladığını unutmayın.

var() işlevi, kendisini alıp özel mülk değeriyle değiştirir. Bu işlem sonucunda color: #06c; elde edilir. Özel mülk, stil sayfanızda bir yerde tanımlandığı sürece var işlevi tarafından kullanılabilir.

Söz dizimi ilk başta biraz tuhaf görünebilir. Birçok geliştirici, "Değişken adları için neden $foo kullanılmıyor?" diye soruyor. Bu yaklaşım, mümkün olduğunca esnek olacak ve gelecekte $foo makrolarına izin verebilecek şekilde özel olarak seçilmiştir. Arka plan bilgisi için spesifikasyon yazarlarından biri olan Tab Atkins'in bu yayınını okuyabilirsiniz.

Özel özellik söz dizimi

Özel mülkün söz dizimi basittir.

--header-color: #06c;

Özel özelliklerin büyük/küçük harfe duyarlı olduğunu unutmayın. Bu nedenle --header-color ve --Header-Color farklı özel özelliklerdir. Bu özellikler ilk bakışta basit gibi görünse de özel mülkler için izin verilen söz dizimi aslında oldukça serbesttir. Örneğin, aşağıdakiler geçerli özel mülkler olarak kabul edilir:

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

Bu değişken, herhangi bir normal özellikte geçersiz olacağı için değişken olarak yararlı olmasa da, çalışma zamanında JavaScript ile okunabilir ve üzerinde işlem yapılabilir. Bu, özel mülklerin, günümüzün CSS ön işlemcileriyle şu anda mümkün olmayan her türlü ilginç tekniğin kilidini açma potansiyeline sahip olduğu anlamına gelir. Dolayısıyla, "Yawn SASS'im var, ne olacak?" diye düşünüyorsanız bir kez daha düşünün. Bunlar, alıştığınız değişkenler değildir.

Çağlayan

Özel mülkler standart basamaklı kurallara uyar. Bu nedenle, aynı mülkü farklı düzeylerde tanımlayabilirsiniz.

: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>

Bu sayede, duyarlı tasarıma yardımcı olmak için medya sorgularındaki özel özelliklerden yararlanabilirsiniz. Bir kullanım alanı, ekran boyutu arttıkça ana bölümlendirme öğelerinizin etrafındaki marjı genişletmektir:

:root {
    --gutter: 4px;
}

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

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

Yukarıdaki kod snippet'inin, medya sorguları içinde değişkenleri tanımlayamayan günümüzün CSS ön işlemcileri ile mümkün olmadığını belirtmek gerekir. Bu yeteneğe sahip olmak büyük bir potansiyelin kapısını aralar.

Değerlerini diğer özel mülklerden alan özel mülklere de sahip olabilirsiniz. Bu yöntem, tema oluşturmak için son derece faydalı olabilir:

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

var() işlevi

Özel bir mülkün değerini almak ve kullanmak için var() işlevini kullanmanız gerekir. var() işlevinin söz dizimi şu şekildedir:

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

Burada <custom-property-name>, yazar tarafından tanımlanan bir özel mülkün adı (ör. --foo) ve <declaration-value>, başvurulan özel mülk geçersiz olduğunda kullanılacak yedek değerdir. Yedek değerler virgülle ayrılmış bir liste olabilir. Bu liste tek bir değer halinde birleştirilir. Örneğin var(--font-stack, "Roboto", "Helvetica");, "Roboto", "Helvetica" için yedek tanımlar. Boşluk ve dolgu için kullanılanlar gibi kısaltma değerlerinin virgülle ayrılmadığını unutmayın. Bu nedenle, dolgu için uygun bir yedek şöyle görünür.

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

Bileşen yazarları, bu yedek değerleri kullanarak öğesi için savunma stilleri yazabilir:

/* 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 */
}

Özel özellikler gölge sınırlarını geçebileceğinden, bu teknik özellikle Gölge DOM kullanan Web Bileşenleri tema oluşturmak için yararlıdır. Web bileşeni yazarı, yedek değerleri kullanarak ilk tasarımı oluşturabilir ve özelleştirme "kancalarını" özel mülk biçiminde gösterebilir.

<!-- 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;
}

var() kullanırken dikkat etmeniz gereken birkaç nokta vardır. Değişkenler özellik adları olamaz. Örneğin:

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

Ancak bu, margin-top: 20px; ayarıyla aynı değildir. Bunun yerine ikinci bildirim geçersiz olur ve hata olarak atılır.

Benzer bir şekilde, bir kısmının bir değişken tarafından sağlandığı bir değeri (nadiren) oluşturamazsınız:

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

Tekrar belirtmek gerekirse bu, margin-top: 20px; ayarlamakla eşdeğer değildir. Bir değer oluşturmak için başka bir şeye ihtiyacınız vardır: calc() işlevi.

calc() ile değer oluşturma

calc() işleviyle daha önce hiç çalışmadıysanız CSS değerlerini belirlemek için hesaplamalar yapmanıza olanak tanıyan küçük bir araçtır. Tüm modern tarayıcılarda desteklenir ve yeni değerler oluşturmak için özel özelliklerle birleştirilebilir. Örneğin:

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

JavaScript'te özel mülklerle çalışma

Özel bir mülkün değerini çalışma zamanında almak için hesaplanan CSSStyleDeclaration nesnesinin getPropertyValue() yöntemini kullanın.

/* 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'

Benzer şekilde, özel özelliğin değerini çalışma zamanında ayarlamak için CSSStyleDeclaration nesnesinin setProperty() yöntemini kullanın.

/* 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');

Ayrıca, setProperty() çağrınızda var() işlevini kullanarak özel mülkün değerini çalışma zamanında başka bir özel mülke referans verecek şekilde ayarlayabilirsiniz.

/* 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)');

Özel nitelikler stil sayfalarınızdaki diğer özel özelliklere başvuruda bulunabildiğinden, bunun nasıl her türlü ilginç çalışma zamanı efektine yol açacağını hayal edebilirsiniz.

Tarayıcı desteği

Özel mülkler şu anda Chrome 49, Firefox 42, Safari 9.1 ve iOS Safari 9.3'te desteklenmektedir.

Demo

Özel özellikler sayesinde artık yararlanabileceğiniz tüm ilginç tekniklere göz atmak için örneği deneyin.

Daha fazla bilgi

Özel mülkler hakkında daha fazla bilgi edinmek istiyorsanız Google Analytics ekibinden Philip Walton, özel mülkler konusunda neden heyecan duyduğu hakkında bir makale yazdı. Özel özelliklerin ilerleme durumunu chromestatus.com adresinden diğer tarayıcılarda takip edebilirsiniz.