CSS Özel Özelliklerine Yönelik Bir Strateji Kılavuzu

Yayınlanan: 2022-03-10
Hızlı özet ↬ Dinamik özellikler, yeni yaratıcı fikirler için fırsatlar sağlar, aynı zamanda CSS'ye karmaşıklık ekleme potansiyeli de sağlar. Bunlardan en iyi şekilde yararlanmak için, CSS'yi özel özelliklerle nasıl yazdığımız ve yapılandırdığımız konusunda bir stratejiye ihtiyacımız olabilir.

CSS Özel Özellikleri (bazen 'CSS değişkenleri' olarak da bilinir) artık tüm modern tarayıcılarda destekleniyor ve insanlar bunları üretimde kullanmaya başlıyor. Bu harika, ancak önişlemcilerdeki değişkenlerden farklılar ve ne gibi avantajlar sunduklarını düşünmeden bunları kullanan birçok insan örneği gördüm.

Özel özelliklerin, CSS'yi yazma ve yapılandırma biçimimizi ve daha az bir ölçüde, UI bileşenleriyle etkileşim kurmak için JavaScript'i kullanma biçimimizi değiştirme konusunda büyük bir potansiyeli vardır. Sözdizimine ve nasıl çalıştıklarına odaklanmayacağım (bunun için “Özel Özellikleri Kullanmaya Başlama Zamanı”nı okumanızı tavsiye ederim). Bunun yerine, CSS Özel Özelliklerinden en iyi şekilde yararlanmak için stratejilere daha derinlemesine bakmak istiyorum.

Önişlemcilerdeki Değişkenlere Nasıl Benzerler?

Özel Özellikler, ön işlemcilerdeki değişkenlere biraz benzer ancak bazı önemli farklılıkları vardır. İlk ve en belirgin fark sözdizimidir.

SCSS ile bir değişkeni belirtmek için bir dolar sembolü kullanırız:

 $smashing-red: #d33a2c;

Less'te bir @ sembolü kullanırız:

 @smashing-red: #d33a2c;

Özel özellikler benzer kuralları izler ve bir -- öneki kullanır:

 :root { --smashing-red: #d33a2c; } .smashing-text { color: var(--smashing-red); }

Önişlemcilerdeki özel özellikler ve değişkenler arasındaki önemli bir fark, özel özelliklerin bir değer atamak ve bu değeri almak için farklı bir sözdizimine sahip olmasıdır. Özel bir özelliğin değerini alırken var() işlevini kullanırız.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Bir sonraki en belirgin fark isimde. Bunlar, gerçekten CSS özellikleri oldukları için 'özel özellikler' olarak adlandırılırlar. Ön işlemcilerde, dış bildirim blokları, medya kuralları veya hatta bir seçicinin parçası dahil olmak üzere hemen hemen her yerde değişkenleri bildirebilir ve kullanabilirsiniz.

 $breakpoint: 800px; $smashing-red: #d33a2c; $smashing-things: ".smashing-text, .cats"; @media screen and (min-width: $breakpoint) { #{$smashing-things} { color: $smashing-red; } }

Yukarıdaki örneklerin çoğu, özel özellikler kullanıldığında geçersiz olacaktır.

Özel özellikler, normal CSS özellikleri olarak nerede kullanılabilecekleri konusunda aynı kurallara sahiptir. Bunları değişkenlerden çok dinamik özellikler olarak düşünmek çok daha iyidir. Bu, yalnızca bir bildirim bloğu içinde kullanılabilecekleri anlamına gelir veya başka bir deyişle, özel özellikler bir seçiciye bağlıdır. Bu, :root seçici veya başka bir geçerli seçici olabilir.

 :root { --smashing-red: #d33a2c; } @media screen and (min-width: 800px) { .smashing-text, .cats { --margin-left: 1em; } }

Özel bir özelliğin değerini, aksi takdirde bir özellik bildiriminde bir değer kullanacağınız her yerde alabilirsiniz. Bu, bir steno ifadesinin parçası olarak veya hatta calc() denklemlerinin içinde tek bir değer olarak kullanılabilecekleri anlamına gelir.

 .smashing-text, .cats { color: var(--smashing-red); margin: 0 var(--margin-horizontal); padding: calc(var(--margin-horizontal) / 2) }

Ancak, medya sorgularında veya :nth-child() dahil seçicilerde kullanılamazlar.

Sözdizimi ve geri dönüş değerlerinin nasıl kullanılacağı ve diğer değişkenlere değişkenler atayabilir misiniz (evet) gibi özel özelliklerin nasıl çalıştığı hakkında bilmek isteyeceğiniz çok daha fazla şey olabilir, ancak bu temel giriş, geri kalanını anlamak için yeterli olacaktır. Bu makaledeki kavramlar. Özel mülklerin nasıl çalıştığına dair ayrıntılar hakkında daha fazla bilgi için Serg Hospodarets tarafından yazılan “Özel Özellikleri Kullanmaya Başlama Zamanı” bölümünü okuyabilirsiniz.

Dinamik ve Statik

Kozmetik farklılıklar bir yana, önişlemciler ve özel özelliklerdeki değişkenler arasındaki en önemli fark, kapsamlarının nasıl alındıklarıdır. Değişkenlere statik veya dinamik kapsamlı olarak başvurabiliriz. Ön işlemcilerdeki değişkenler statik, özel özellikler ise dinamiktir.

CSS söz konusu olduğunda, statik, bir değişkenin değerini derleme işleminde farklı noktalarda güncelleyebileceğiniz anlamına gelir, ancak bu, kendisinden önce gelen kodun değerini değiştiremez.

 $background: blue; .blue { background: $background; } $background: red; .red { background: $background; }

sonuçlanır:

 .blue { background: blue; } .red { background: red; }

Bu, CSS'ye dönüştürüldüğünde, değişkenler gider. Bu, potansiyel olarak bir .scss dosyasını okuyabileceğimiz ve HTML, tarayıcı veya diğer girdiler hakkında hiçbir şey bilmeden çıktısını belirleyebileceğimiz anlamına gelir. Özel özelliklerde durum böyle değildir.

Önişlemciler, değişkenlerin bir seçici, işlev veya karışım içinde geçici olarak değiştirilebildiği bir tür "blok kapsamı"na sahiptir. Bu, blok içindeki bir değişkenin değerini değiştirir, ancak yine de statiktir. Bu, seçiciye değil, bloğa bağlıdır. Aşağıdaki örnekte, $background değişkeni .example bloğunun içinde değiştirilir. Aynı seçiciyi kullansak bile bloğun dışındaki ilk değere geri döner.

 $background: red; .example { $background: blue; background: $background; } .example { background: $background; }

Bu, aşağıdakilerle sonuçlanacaktır:

 .example { background: blue; } .example { background: red; }

Özel özellikler farklı çalışır. Özel özellikler söz konusu olduğunda, dinamik olarak kapsam, bunların kalıtım ve kademeye tabi olduğu anlamına gelir. Özellik bir seçiciye bağlıdır ve değer değişirse bu, diğer CSS özellikleri gibi eşleşen tüm DOM öğelerini etkiler.

Bu harika çünkü bir medya sorgusu içindeki özel bir özelliğin değerini, fareyle üzerine gelme gibi bir sözde seçiciyle ve hatta JavaScript ile değiştirebilirsiniz.

 a { --link-color: black; } a:hover, a:focus { --link-color: tomato; } @media screen and (min-width: 600px) { a { --link-color: blue; } } a { color: var(--link-color); }

Özel özelliğin kullanıldığı yeri değiştirmemiz gerekmiyor - özel özelliğin değerini CSS ile değiştiriyoruz. Bu, aynı özel özelliği kullanarak, aynı sayfada farklı yerlerde veya bağlamda farklı değerlere sahip olabileceğimiz anlamına gelir.

Küresel ve Yerel

Değişkenler statik veya dinamik olmanın yanı sıra global veya yerel de olabilir. JavaScript yazarsanız, buna aşina olacaksınız. Değişkenler, bir uygulama içindeki her şeye uygulanabilir veya kapsamları belirli işlevler veya kod bloklarıyla sınırlandırılabilir.

CSS'ye benzer. Küresel olarak uygulanan bazı şeylerimiz ve daha yerel olan bazı şeylerimiz var. Marka renkleri, dikey boşluklar ve tipografi, web sitenizde veya uygulamanızda küresel olarak ve tutarlı bir şekilde uygulanmasını isteyebileceğiniz şeylere örnektir. Bizde de yöresel şeyler var. Örneğin, bir düğme bileşeninin küçük ve büyük bir varyantı olabilir. Bu düğmelerdeki boyutların tüm giriş öğelerine ve hatta sayfadaki her öğeye uygulanmasını istemezsiniz.

Bu, CSS'de aşina olduğumuz bir şey. Yerel bileşenleri ve global tasarım öğelerini yalıtmaya yardımcı olmak için tasarım sistemleri, adlandırma kuralları ve JavaScript kitaplıkları geliştirdik. Özel özellikler, bu eski sorunla başa çıkmak için yeni seçenekler sunar.

CSS Özel Özellikleri, varsayılan olarak yerel olarak, onları uyguladığımız belirli seçicilere göre kapsamlandırılmıştır. Yani yerel değişkenler gibiler. Bununla birlikte, özel özellikler de miras alınır, bu nedenle birçok durumda genel değişkenler gibi davranırlar - özellikle :root seçiciye uygulandığında. Bu, onları nasıl kullanacağımız konusunda düşünceli olmamız gerektiği anlamına gelir.

Pek çok örnek, özel özelliklerin :root öğesine uygulandığını gösteriyor ve bu bir demo için iyi olsa da, dağınık bir küresel kapsam ve kalıtımla ilgili istenmeyen sorunlara neden olabilir. Neyse ki, bu dersleri zaten öğrendik.

Global Değişkenler Statik Olma Eğilimi

Birkaç küçük istisna vardır, ancak genel olarak konuşursak, CSS'deki çoğu küresel şey de statiktir.

Marka renkleri, tipografi ve boşluk gibi küresel değişkenler bir bileşenden diğerine çok fazla değişme eğilimi göstermez. Değişiklik yaptıklarında, bu, küresel bir yeniden markalaşma veya olgun bir üründe nadiren meydana gelen başka bir önemli değişiklik olma eğilimindedir. Bu şeylerin değişken olması hala mantıklı, birçok yerde kullanılıyor ve değişkenler tutarlılığa yardımcı oluyor. Ancak dinamik olmaları mantıklı değil. Bu değişkenlerin değeri herhangi bir dinamik şekilde değişmez.

Bu nedenle global (statik) değişkenler için önişlemcilerin kullanılmasını şiddetle tavsiye ederim. Bu, yalnızca her zaman statik olmalarını sağlamakla kalmaz, aynı zamanda onları kod içinde görsel olarak belirtir. Bu, CSS'yi çok daha okunabilir ve bakımı daha kolay hale getirebilir.

Yerel Statik Değişkenler İyi (Bazen)

Küresel değişkenlerin statik olduğu konusundaki güçlü duruş göz önüne alındığında, yansıma yoluyla tüm yerel değişkenlerin dinamik olması gerekebileceğini düşünebilirsiniz. Yerel değişkenlerin dinamik olma eğiliminde olduğu doğru olsa da, bu hiçbir yerde global bir değişkenin statik olma eğilimi kadar güçlü değildir.

Yerel olarak statik değişkenler birçok durumda tamamen uygundur. Bileşen dosyalarında önişlemci değişkenlerini çoğunlukla geliştirici kolaylığı olarak kullanıyorum.

Birden çok boyut varyasyonu olan bir düğme bileşeninin klasik örneğini düşünün.

düğmeler

Benim scss şöyle görünebilir:

 $button-sml: 1em; $button-med: 1.5em; $button-lrg: 2em; .btn { // Visual styles } .btn-sml { font-size: $button-sml; } .btn-med { font-size: $button-med; } .btn-lrg { font-size: $button-lrg; }

Açıkçası, bu örnek, değişkenleri birden çok kez kullanıyor olsaydım veya boyut değişkenlerinden kenar boşluğu ve dolgu değerleri türetiyor olsaydım daha anlamlı olurdu. Bununla birlikte, farklı boyutları hızlı bir şekilde prototipleme yeteneği yeterli bir neden olabilir.

Çoğu statik değişken global olduğundan, yalnızca bir bileşenin içinde kullanılan statik değişkenleri ayırt etmeyi severim. Bunu yapmak için, bu değişkenleri bileşen adıyla öneklendirebilir veya bileşen için c-variable-name veya yerel için l-variable-name gibi başka bir önek kullanabilirsiniz. İstediğiniz öneki kullanabilir veya global değişkenlerin önüne koyabilirsiniz. Hangisini seçerseniz seçin, özellikle mevcut bir kod tabanını özel özellikleri kullanmak üzere dönüştürüyorsanız, ayırt etmek yardımcı olur.

Özel Özellikler Ne Zaman Kullanılır?

Bileşenlerin içinde statik değişkenler kullanmak uygunsa, özel özellikleri ne zaman kullanmalıyız? Mevcut önişlemci değişkenlerini özel özelliklere dönüştürmek genellikle pek mantıklı değildir. Sonuçta, özel özelliklerin nedeni tamamen farklıdır. Özel özellikler, DOM'deki bir koşula göre değişen CSS özelliklerine sahip olduğumuzda, özellikle de :focus , :hover , medya sorguları veya JavaScript ile dinamik bir koşula sahip olduğumuzda anlamlıdır.

Özel özellikler mantık ve kodu düzenlemek için yeni yollar sunduğundan, gelecekte daha azına ihtiyacımız olsa da, her zaman bir tür statik değişken kullanacağımızdan şüpheleniyorum. O zamana kadar, çoğu durumda önişlemci değişkenleri ve özel özelliklerin bir kombinasyonu ile çalışacağımızı düşünüyorum.

Özel özelliklere statik değişkenler atayabileceğimizi bilmek yararlıdır. İster global ister yerel olsunlar, birçok durumda statik değişkenleri yerel olarak dinamik özel özelliklere dönüştürmek mantıklıdır.

Not : Özel bir özellik için $var değerinin geçerli bir değer olduğunu biliyor muydunuz? Sass'ın son sürümleri bunu tanır ve bu nedenle, bunun gibi özel özelliklere atanan değişkenleri enterpolasyon yapmamız gerekir: #{$var} . Bu, Sass'a stil sayfasında sadece $var yerine değişkenin değerini çıkarmak istediğinizi söyler. Bu yalnızca, değişken adlarının geçerli bir CSS olabileceği özel özellikler gibi durumlar için gereklidir.

Yukarıdaki düğme örneğini ele alırsak ve HTML'de uygulanan sınıf ne olursa olsun tüm düğmelerin mobil cihazlarda küçük varyasyonu kullanması gerektiğine karar verirsek, bu artık daha dinamik bir durumdur. Bunun için özel özellikler kullanmalıyız.

 $button-sml: 1em; $button-med: 1.5em; $button-lrg: 2em; .btn { --button-size: #{$button-sml}; } @media screen and (min-width: 600px) { .btn-med { --button-size: #{$button-med}; } .btn-lrg { --button-size: #{$button-lrg}; } } .btn { font-size: var(--button-size); }

Burada tek bir özel özellik oluşturuyorum: --button-size . Bu özel özellik, başlangıçta btn sınıfını kullanan tüm düğme öğelerini kapsar. Daha sonra btn-med ve btn-lrg sınıfları için --button-size değerini 600 pikselin üzerinde değiştiriyorum. Son olarak, bu özel özelliği tek bir yerde tüm düğme öğelerine uyguluyorum.

Çok Zeki Olma

Özel özelliklerin dinamik doğası, bazı akıllı ve karmaşık bileşenler oluşturmamıza olanak tanır.

Önişlemcilerin tanıtılmasıyla, çoğumuz, karışımlar ve özel işlevler kullanarak akıllı soyutlamalara sahip kitaplıklar oluşturduk. Sınırlı durumlarda, bunun gibi örnekler bugün hala yararlıdır, ancak çoğunlukla ön işlemcilerle ne kadar uzun süre çalışırsam o kadar az özellik kullanırım. Bugün, neredeyse sadece statik değişkenler için önişlemciler kullanıyorum.

Özel özellikler bu tür deneylerden muaf olmayacak (ve olmamalıdır) ve birçok akıllı örnek görmeyi sabırsızlıkla bekliyorum. Ancak uzun vadede, okunabilir ve bakımı yapılabilir kod her zaman akıllı soyutlamalara (en azından üretimde) galip gelecektir.

Geçenlerde Free Code Camp Medium'da bu konuyla ilgili mükemmel bir makale okudum. Bill Sourour tarafından yazılmıştır ve “Çalışma Zamanında Yapma. Tasarım Zamanında Yapın.” Argümanlarını başka sözcüklerle anlatmak yerine, okumana izin vereceğim.

Önişlemci değişkenleri ile özel özellikler arasındaki temel farklardan biri, özel özelliklerin çalışma zamanında çalışmasıdır. Bu, ön işlemcilerle karmaşıklık açısından sınırda kabul edilebilir olabilecek şeylerin özel özelliklerle iyi bir fikir olmayabileceği anlamına gelir.

Bunu benim için son zamanlarda gösteren bir örnek şuydu:

 :root { --font-scale: 1.2; --font-size-1: calc(var(--font-scale) * var(--font-size-2)); --font-size-2: calc(var(--font-scale) * var(--font-size-3)); --font-size-3: calc(var(--font-scale) * var(--font-size-4)); --font-size-4: 1rem; }

Bu modüler bir ölçek oluşturur. Modüler ölçek, bir oran kullanarak birbiriyle ilişkili bir dizi sayıdır. Genellikle web tasarımında ve geliştirmede yazı tipi boyutlarını veya boşlukları ayarlamak için kullanılırlar.

Bu örnekte, her özel özellik, önceki özel özelliğin değeri alınarak ve bunu oran ile çarparak calc() kullanılarak belirlenir. Bunu yaparak, ölçekte bir sonraki sayıyı alabiliriz.

Bu, oranların çalışma zamanında hesaplandığı ve yalnızca --font-scale özelliğinin değerini güncelleyerek bunları değiştirebileceğiniz anlamına gelir. Örneğin:

 @media screen and (min-width: 800px) { :root { --font-scale: 1.33; } }

Bu akıllıca, kısa ve özdür ve ölçeği değiştirmek istemeniz durumunda tüm değerleri yeniden hesaplamaktan çok daha hızlıdır. Aynı zamanda üretim kodunda yapmayacağım bir şey.

Yukarıdaki örnek prototipleme için faydalı olsa da, üretimde şöyle bir şey görmeyi tercih ederim:

 :root { --font-size-1: 1.728rem; --font-size-2: 1.44rem; --font-size-3: 1.2em; --font-size-4: 1em; } @media screen and (min-width: 800px) { :root { --font-size-1: 2.369rem; --font-size-2: 1.777rem; --font-size-3: 1.333rem; --font-size-4: 1rem; } }

Bill'in makalesindeki örneğe benzer şekilde, gerçek değerlerin ne olduğunu görmeyi faydalı buluyorum. Kodu yazdığımızdan çok daha fazla okuyoruz ve yazı tipi ölçekleri gibi global değerler üretimde nadiren değişiyor.

Yukarıdaki örnek hala mükemmel değil. Genel değerlerin statik olması gerektiği kuralını daha önce ihlal ediyor. Önişlemci değişkenlerini kullanmayı ve daha önce gösterilen teknikleri kullanarak bunları yerel olarak dinamik özel özelliklere dönüştürmeyi tercih ederim.

Bir özel mülk kullanmaktan farklı bir özel mülke geçiş yaptığımız durumlardan kaçınmak da önemlidir. Bu, özellikleri böyle adlandırdığımızda olabilir.

Değişkeni Değil Değeri Değiştirin

Değişkeni değil değeri değiştirmek, özelleştirilmiş özellikleri etkin bir şekilde kullanmak için en önemli stratejilerden biridir.

Genel bir kural olarak, tek bir amaç için hangi özel özelliğin kullanıldığını asla değiştirmemelisiniz. Bunu yapmak kolaydır, çünkü biz ön işlemcilerle işleri tam olarak böyle yaparız, ancak özel özelliklerle pek bir anlam ifade etmez.

Bu örnekte, örnek bir bileşende kullanılan iki özel özelliğimiz var. Ekran boyutuna bağlı olarak --font-size-small değerini kullanmaktan --font-size-large .

 :root { --font-size-small: 1.2em; --font-size-large: 2em; } .example { font-size: var(--font-size-small); } @media screen and (min-width: 800px) { .example { font-size: var(--font-size-large); } }

Bunu yapmanın daha iyi bir yolu, bileşen kapsamında tek bir özel özellik tanımlamaktır. Ardından bir medya sorgusu veya başka bir seçici kullanarak değerini değiştirin.

 .example { --example-font-size: 1.2em; } @media screen and (min-width: 800px) { .example { --example-font-size: 2em; } }

Son olarak, tek bir yerde bu özel özelliğin değerini kullanıyorum:

 .example { font-size: var(--example-font-size); }

Bu örnekte ve ondan önceki diğer örneklerde, medya sorguları yalnızca özel özelliklerin değerini değiştirmek için kullanılmıştır. Ayrıca var() ifadesinin kullanıldığı ve normal CSS özelliklerinin güncellendiği tek bir yer olduğunu da fark edebilirsiniz.

Değişken bildirimleri ve özellik bildirimleri arasındaki bu ayrım kasıtlıdır. Bunun birçok nedeni var, ancak faydaları en çok duyarlı tasarım düşünüldüğünde ortaya çıkıyor.

Özel Özelliklerle Duyarlı Tasarım

Duyarlı tasarımın büyük ölçüde medya sorgularına dayandığı durumlarda karşılaşılan zorluklardan biri, CSS'nizi nasıl düzenlerseniz düzenleyin, belirli bir bileşenle ilgili stillerin stil sayfası boyunca parçalanmasıdır.

Hangi CSS özelliklerinin değişeceğini bilmek çok zor olabilir. Yine de, CSS Özel Özellikleri, duyarlı tasarımla ilgili bazı mantığı düzenlememize ve medya sorgularıyla çalışmayı çok daha kolay hale getirmemize yardımcı olabilir.

Değişirse, Değişkendir

Medya sorgularını kullanarak değişen özellikler, doğası gereği dinamiktir ve özel özellikler, CSS'de dinamik değerleri ifade etmenin yollarını sağlar. Bu, herhangi bir CSS özelliğini değiştirmek için bir medya sorgusu kullanıyorsanız, bu değeri özel bir özelliğe yerleştirmeniz gerektiği anlamına gelir.

Daha sonra bunu, tüm medya kuralları, fareyle üzerine gelme durumları veya değerin nasıl değiştiğini tanımlayan dinamik seçicilerle birlikte belgenin en üstüne taşıyabilirsiniz.

Tasarımdan Ayrı Mantık

Doğru yapıldığında, mantık ve tasarımın ayrılması, medya sorgularının yalnızca özel özelliklerin değerini değiştirmek için kullanıldığı anlamına gelir. Bu, duyarlı tasarımla ilgili tüm mantığın belgenin en üstünde olması gerektiği anlamına gelir ve CSS'mizde bir var() ifadesi gördüğümüz her yerde, bu özelliğin değiştiğini hemen biliriz. Geleneksel CSS yazma yöntemleriyle, bunu bir bakışta anlamanın hiçbir yolu yoktu.

Birçoğumuz, farklı durumlarda hangi özelliklerin değiştiğini kafamızda takip ederken, CSS'yi bir bakışta okuyup yorumlamada çok başarılı olduk. Bundan bıktım ve artık bunu yapmak istemiyorum! Özel özellikler artık mantık ve uygulanması arasında bir bağlantı sağlıyor, bu nedenle bunu izlememize gerek yok ve bu inanılmaz derecede faydalı!

Mantık Katlaması

Değişkenleri bir belgenin veya işlevin başında bildirme fikri yeni bir fikir değil. Çoğu dilde yaptığımız bir şey ve şimdi CSS'de de yapabileceğimiz bir şey. CSS'yi bu şekilde yazmak, belgenin üstündeki ve altındaki CSS arasında net bir görsel ayrım oluşturur. Onlar hakkında konuştuğumda bu bölümleri ayırt etmenin bir yoluna ihtiyacım var ve “mantık kıvrımı” fikri, kullanmaya başladığım bir metafor.
Ekranın üst kısmında tüm önişlemci değişkenleri ve özel özellikler bulunur. Bu, özel bir özelliğin sahip olabileceği tüm farklı değerleri içerir. Özel bir özelliğin nasıl değiştiğini izlemek kolay olmalıdır.

Ekranın altındaki CSS basit ve son derece açıklayıcıdır ve okunması kolaydır. Medya sorgularından ve modern CSS'nin diğer gerekli karmaşıklıklarından önce CSS gibi geliyor.

Altı sütunlu esnek kutu ızgara sisteminin gerçekten basit bir örneğine bir göz atın:

 .row { --row-display: block; } @media screen and (min-width: 600px) { .row { --row-display: flex; } }

--row-display özel özelliği başlangıçta block şekilde ayarlanmıştır. 600 pikselin üzerinde görüntüleme modu esnek olarak ayarlanmıştır.

Katlamanın altında şöyle görünebilir:

 .row { display: var(--row-display); flex-direction: row; flex-wrap: nowrap; } .col-1, .col-2, .col-3, .col-4, .col-5, .col-6 { flex-grow: 0; flex-shrink: 0; } .col-1 { flex-basis: 16.66%; } .col-2 { flex-basis: 33.33%; } .col-3 { flex-basis: 50%; } .col-4 { flex-basis: 66.66%; } .col-5 { flex-basis: 83.33%; } .col-6 { flex-basis: 100%; }

--row-display değişen bir değer olduğunu hemen biliyoruz. Başlangıçta block olacak, bu nedenle esnek değerler yok sayılacaktır.

Bu örnek oldukça basittir, ancak kalan alanı dolduran esnek bir genişlik sütunu içerecek şekilde genişletirsek, büyük olasılıkla flex-grow , flex-shrink ve flex-basis değerlerinin özel özelliklere dönüştürülmesi gerekir. Bunu deneyebilir veya daha ayrıntılı bir örneğe buradan göz atabilirsiniz.

Tema için Özel Özellikler

Genelde global dinamik değişkenler için özel özelliklerin kullanılmasına karşı çıktım ve umarım :root seçicisine özel özellikler eklemenin birçok durumda zararlı olarak kabul edildiğini ima ettim. Ancak her kuralın bir istisnası vardır ve özel özellikler için temadır.

Küresel özel özelliklerin sınırlı kullanımı, tema oluşturmayı çok daha kolay hale getirebilir.

Tema oluşturma, genellikle kullanıcıların kullanıcı arayüzünü bir şekilde özelleştirmesine izin vermek anlamına gelir. Bu, bir profil sayfasındaki renkleri değiştirmek gibi bir şey olabilir. Veya daha yerelleştirilmiş bir şey olabilir. Örneğin, Google Keep uygulamasında bir notun rengini seçebilirsiniz.

Google Keep Uygulaması

Tema oluşturma genellikle, varsayılan bir değeri kullanıcı tercihleriyle geçersiz kılmak için ayrı bir stil sayfası derlemeyi veya her kullanıcı için farklı bir stil sayfası derlemeyi içerir. Bunların her ikisi de zor olabilir ve performans üzerinde etkisi olabilir.

Özel özelliklerle, farklı bir stil sayfası derlememiz gerekmez; özelliklerin değerini yalnızca kullanıcının tercihlerine göre güncellememiz gerekiyor. Kalıtsal değerler oldukları için, bunu kök eleman üzerinde yaparsak, uygulamamızın herhangi bir yerinde kullanılabilirler.

Global Dinamik Özelliklerden Büyük Harf Kullanın

Özel mülkler büyük/küçük harfe duyarlıdır ve çoğu özel mülk yerel olacağından, genel dinamik özellikler kullanıyorsanız, bunları büyük harf kullanmak mantıklı olabilir.

 :root { --THEME-COLOR: var(--user-theme-color, #d33a2c); }

Değişkenlerin büyük harf kullanımı genellikle küresel sabitleri ifade eder. Bizim için bu, özelliğin uygulamada başka bir yerde ayarlandığını ve muhtemelen yerel olarak değiştirmememiz gerektiğini gösterecektir.

Global Dinamik Özellikleri Doğrudan Ayarlamaktan Kaçının

Özel özellikler bir geri dönüş değeri kabul eder. Genel özel özelliklerin değerinin üzerine doğrudan yazmaktan kaçınmak ve kullanıcı değerlerini ayrı tutmak yararlı olabilir. Bunu yapmak için geri dönüş değerini kullanabiliriz.

Yukarıdaki örnek, --THEME-COLOR değerini, varsa --user --user-theme-color değerine ayarlar. --user-theme-color ayarlanmadıysa, #d33a2c değeri kullanılacaktır. Bu şekilde, --THEME-COLOR her kullandığımızda bir geri dönüş sağlamamız gerekmez.

Aşağıdaki örnekte arka planın green olarak ayarlanmasını bekleyebilirsiniz. Ancak, kök öğede --user --user-theme-color değeri ayarlanmamıştır, dolayısıyla --THEME-COLOR değeri değişmemiştir.

 :root { --THEME-COLOR: var(--user-theme-color, #d33a2c); } body { --user-theme-color: green; background: var(--THEME-COLOR); }

Bunun gibi dolaylı olarak global dinamik özellikleri ayarlamak, bunların yerel olarak üzerine yazılmasını önler ve kullanıcı ayarlarının her zaman kök öğeden devralınmasını sağlar. Bu, tema değerlerinizi korumak ve istenmeyen kalıtımdan kaçınmak için yararlı bir kuraldır.

Belirli özellikleri kalıtsal olarak göstermek istiyorsak, :root seçiciyi bir * seçici ile değiştirebiliriz:

 * { --THEME-COLOR: var(--user-theme-color, #d33a2c); } body { --user-theme-color: green; background: var(--THEME-COLOR); }

Artık --THEME-COLOR değeri her öğe için yeniden hesaplanır ve bu nedenle --user-theme- --user-theme-color yerel değeri kullanılabilir. Başka bir deyişle, bu örnekte arka plan rengi green olacaktır.

Bu desenin bazı daha ayrıntılı örneklerini Özel Özelliklerle Rengi Değiştirme bölümünde görebilirsiniz.

JavaScript ile Özel Özellikleri Güncelleme

JavaScript kullanarak özel özellikler ayarlamak istiyorsanız, oldukça basit bir API vardır ve şöyle görünür:

 const elm = document.documentElement; elm.style.setProperty('--USER-THEME-COLOR', 'tomato');

Burada, belge öğesinde --USER-THEME-COLOR değerini veya diğer bir deyişle, tüm öğeler tarafından devralınacağı :root öğesini ayarlıyorum.

Bu yeni bir API değil; bir öğedeki stilleri güncellemek için kullanılan JavaScript yöntemiyle aynıdır. Bunlar satır içi stiller olduğundan, normal CSS'den daha yüksek bir özgüllüğe sahip olacaklardır.

Bu, yerel özelleştirmeleri uygulamanın kolay olduğu anlamına gelir:

 .note { --note-color: #eaeaea; } .note { background: var(--note-color); }

Burada --note-color için varsayılan bir değer belirledim ve bunu .note bileşenine dahil ettim. Bu basit örnekte bile değişken bildirimini özellik bildiriminden ayrı tutuyorum.

 const elm = document.querySelector('#note-uid'); elm.style.setProperty('--note-color', 'yellow');

Daha sonra bir .note öğesinin belirli bir örneğini hedefler ve yalnızca o öğe için --note-color özel özelliğinin değerini değiştiririm. Bu artık varsayılan değerden daha yüksek bir özgüllüğe sahip olacaktır.

React kullanarak bu örnekte bunun nasıl çalıştığını görebilirsiniz. Bu kullanıcı tercihleri ​​yerel depolamaya veya belki daha büyük bir uygulama olması durumunda bir veritabanına kaydedilebilir.

Rengi Özel Özelliklerle Değiştirme

Onaltılık değerlere ve adlandırılmış renklere ek olarak, CSS'nin rgb() ve hsl() gibi renk işlevleri vardır. Bunlar, ton veya açıklık gibi bir rengin bileşenlerini ayrı ayrı belirlememize olanak tanır. Özel özellikler, renk işlevleriyle birlikte kullanılabilir.

 :root { --hue: 25; } body { background: hsl(var(--hue), 80%, 50%); }

Bu kullanışlıdır, ancak önişlemcilerin en yaygın olarak kullanılan özelliklerinden bazıları, açıklaştırma, koyulaştırma veya doygunluğu giderme gibi işlevleri kullanarak rengi değiştirmemize izin veren gelişmiş renk işlevleridir:

 darken($base-color, 10%); lighten($base-color, 10%); desaturate($base-color, 20%);

Bu özelliklerden bazılarının tarayıcılarda bulunması faydalı olacaktır. Geliyorlar, ancak CSS'de yerel renk değiştirme işlevlerine sahip olana kadar, özel özellikler bu boşluğun bir kısmını doldurabilir.

Özel özelliklerin rgb() ve hsl() gibi mevcut renk işlevleri içinde kullanılabileceğini gördük, ancak bunlar calc() içinde de kullanılabilir. Bu, gerçek bir sayıyı çarparak bir yüzdeye dönüştürebileceğimiz anlamına gelir, örneğin calc(50 * 1%) = 50% .

 :root { --lightness: 50; } body { background: hsl(25, 80%, calc(var(--lightness) * 1%)); }

Açıklık değerini gerçek bir sayı olarak saklamak istememizin nedeni, yüzdeye dönüştürmeden önce calc ile değiştirebilmemizdir. Örneğin, bir rengi 20% koyulaştırmak istersem, açıklığını 0.8 ile çarpabilirim. Hafiflik hesaplamasını yerel kapsamlı bir özel özelliğe ayırarak bunu okumayı biraz daha kolaylaştırabiliriz:

 :root { --lightness: 50; } body { --lightness: calc(var(--lightness * 0.8)); background: hsl(25, 80%, calc(var(--lightness) * 1%)); }

Hatta daha fazla hesaplamayı soyutlayabilir ve özel özellikleri kullanarak CSS'de renk değiştirme işlevleri gibi bir şey yaratabiliriz. Bu örnek, çoğu pratik tema durumu için muhtemelen fazla karmaşıktır, ancak dinamik özel özelliklerin tam gücünü gösterir.

Tema Oluşturmayı Basitleştirin

Özel özellikleri kullanmanın avantajlarından biri, temayı basitleştirme yeteneğidir. Uygulamanın, özel özelliklerin nasıl kullanıldığının farkında olması gerekmez. Bunun yerine, özel özelliklerin değerini ayarlamak için JavaScript veya sunucu tarafı kodu kullanıyoruz. Bu değerlerin nasıl kullanılacağı stil sayfaları tarafından belirlenir.

Bu, bir kez daha mantığı tasarımdan ayırabildiğimiz anlamına gelir. Teknik bir tasarım ekibiniz varsa, yazarlar stil sayfalarını güncelleyebilir ve tek bir JavaScript satırını veya arka uç kodunu değiştirmeden özel özelliklerin nasıl uygulanacağına karar verebilir.

Özel özellikler ayrıca tema karmaşıklığının bir kısmının CSS'ye taşınmasına izin verir ve bu karmaşıklık CSS'nizin sürdürülebilirliği üzerinde olumsuz bir etkiye sahip olabilir, bu nedenle mümkün olan her yerde basit tutmayı unutmayın.

Bugün Özel Özellikleri Kullanma

IE10 ve 11'i destekliyor olsanız bile, bugün özel özellikleri kullanmaya başlayabilirsiniz. Bu makaledeki örneklerin çoğu, CSS'yi nasıl yazdığımız ve yapılandırdığımızla ilgilidir. Avantajlar, sürdürülebilirlik açısından önemlidir, ancak örneklerin çoğu, yalnızca daha karmaşık kodlarla yapılabilecekleri azaltır.

Özel özelliklerin özelliklerinin çoğunu aynı kodun statik bir temsiline dönüştürmek için postcss-css-variables adlı bir araç kullanıyorum. Diğer benzer araçlar, medya sorguları veya karmaşık seçiciler içindeki özel özellikleri yok sayar ve özel özelliklere önişlemci değişkenleri gibi davranır.

Bu araçların yapamadığı şey, özel özelliklerin çalışma zamanı özelliklerini taklit etmektir. Bu, JavaScript ile tema oluşturma veya özellikleri değiştirme gibi dinamik özelliklerin olmadığı anlamına gelir. Bu, birçok durumda uygun olabilir. Duruma bağlı olarak, UI özelleştirmesi aşamalı bir geliştirme olarak kabul edilebilir ve varsayılan tema eski tarayıcılar için tamamen kabul edilebilir olabilir.

Doğru Stil Sayfasını Yükleme

postCSS'yi kullanmanın birçok yolu vardır. Daha yeni ve daha eski tarayıcılar için ayrı stil sayfaları derlemek için bir gulp işlemi kullanıyorum. gulp görevimin basitleştirilmiş bir versiyonu şuna benziyor:

 import gulp from "gulp"; import sass from "gulp-sass"; import postcss from "gulp-postcss"; import rename from "gulp-rename"; import cssvariables from "postcss-css-variables"; import autoprefixer from "autoprefixer"; import cssnano from "cssnano"; gulp.task("css-no-vars", () => gulp .src("./src/css/*.scss") .pipe(sass().on("error", sass.logError)) .pipe(postcss([cssvariables(), cssnano()])) .pipe(rename({ extname: ".no-vars.css" })) .pipe(gulp.dest("./dist/css")) ); gulp.task("css", () => gulp .src("./src/css/*.scss") .pipe(sass().on("error", sass.logError)) .pipe(postcss([cssnano()])) .pipe(rename({ extname: ".css" })) .pipe(gulp.dest("./dist/css")) );

Bu, iki CSS dosyasıyla sonuçlanır: özel özelliklere sahip normal bir dosya (style.css) ve daha eski tarayıcılar için bir dosya ( styles.css styles.no-vars.css ). Normal CSS dosyasını almak için IE10 ve 11'in styles.no-vars.css ve diğer tarayıcılara sunulmasını istiyorum.

Normalde, özellik sorgularının kullanılmasını savunurum, ancak IE11, özellik sorgularını desteklemiyor ve özel özellikleri o kadar yoğun bir şekilde kullandık ki, bu durumda farklı bir stil sayfası sunmak mantıklı geliyor.

Akıllıca farklı bir stil sayfası sunmak ve stili olmayan içeriğin bir anda ortaya çıkmasını önlemek basit bir iş değildir. Özel özelliklerin dinamik özelliklerine ihtiyacınız yoksa, tüm tarayıcı styles.no-vars.css ve özel özellikleri yalnızca bir geliştirme aracı olarak kullanmayı düşünebilirsiniz.

Özel özelliklerin tüm dinamik özelliklerinden tam olarak yararlanmak istiyorsanız, kritik bir CSS tekniği kullanmanızı öneririm. Bu teknikleri izleyerek, kritik CSS satır içi olarak işlenirken ana stil sayfası eşzamansız olarak yüklenir. Sayfa başlığınız şöyle görünebilir:

 <head> <style> /* inlined critical CSS */ </style> <script> loadCSS('non-critical.css'); </script> </head>

Tarayıcının özel özellikleri destekleyip desteklemediğine bağlı olarak bunu style.css veya styles.css styles.no-vars.css yükleyecek şekilde genişletebiliriz. Desteği şu şekilde tespit edebiliriz:

 if ( window.CSS && CSS.supports('color', 'var(--test)') ) { loadCSS('styles.css'); } else { loadCSS('styles.no-vars.css'); }

Çözüm

CSS'yi verimli bir şekilde organize etmekte zorlanıyorsanız, duyarlı bileşenlerle ilgili zorluk yaşıyorsanız, istemci tarafı tema uygulamak istiyorsanız veya yalnızca özel özelliklerle doğru adımdan başlamak istiyorsanız, bu kılavuz size bilmeniz gereken her şeyi anlatmalıdır.

Birkaç basit kuralın yanı sıra, CSS'deki dinamik ve statik değişkenler arasındaki farkı anlamak için aşağı gelir:

  1. Tasarımdan ayrı mantık;
  2. Bir CSS özelliği değişirse, özel bir özellik kullanmayı düşünün;
  3. Hangi özel özelliğin kullanıldığını değil, özel özelliklerin değerini değiştirin;
  4. Genel değişkenler genellikle statiktir.

If you follow these conventions, you will find that working with custom properties is a whole lot easier than you think. This might even change how you approach CSS in general.

Daha fazla okuma

  • “It's Time To Start Using Custom Properties,” Serg Hospodarets
    A general introduction to the syntax and the features of custom properties.
  • “Pragmatic, Practical, And Progressive Theming With Custom Properties,” Harry Roberts
    More useful information on theming.
  • Custom Properties Collection, Mike Riethmuller on CodePen
    A number of different examples you can experiment with.