Bu yazıda HTML elementlerine stil özellikleri eklenirken uygulanan Cascade
algoritması üzerinde duracağım. Tarayıcımız hangi kaynaklardan style dosyaları çekiyor? Bir element için eşleşen birden fazla selector olduğunda hangi selector’un uygulanacağına nasıl karar veriyor ? gibi soruları örnekler vererek yanıtlamaya çalışacağım.
Basit olarak bir CSS Rule’nda bulunan CSS terimlerini hızlıca inceleyelim.
Şimdi yazımıza geçebiliriz.
Bir proje üzerinde çalışıyorsunuz ve bir elemente uygulanması gereken CSS Rule’un çalışmadığını görüyorsunuz. Genellikle sorun aynı elemente birden fazla rule tanımlanması ile oluşuyor. Bir element için birden fazla rules var iken CSS neye göre bir rule seçiyor?
Cascade, belirli bir element için birden fazla kural olduğunda farklı CSS sayfalarını birleştirir ve farklı CSS declarations arasında ‘conflict çözme’ işlemlerini yapar.
Cascade algoritması,CSS property’leri için doğru CSS declaration’ları seçmektir. CSS declaration’lar farklı kaynaklardan gelir. Bu kaynaklar user-agent stylesheet, author stylesheet ve user stylesheet. Bunları açıklayalım.
1)User-agent stylesheet(Default stylesheet): Tarayıcı, herhangi bir HTML sayfasına default bir style veren bir style sayfasına sahiptir. Bu stylesheet tarayıcıdan tarayıcıya farklılık gösterir. Tarayıcılar bu stylesheet’in üzerinde değişiklik yapılmasına izin verir. Veya bu stylesheet tamamen kaldırılabilir de.
2)Author stylesheet: En yaygın stylesheet ‘dir. Geliştiriciler tarafından belirli bir web sayfası için yazılan stylesheet dosyalarıdır. Kendi içinde 3 çeşidi vardır.
2.1) Author Inline stylesheet: Elementin içine yazılan CSS Rules. Aşağıdaki örnek gibi
<div style="font-family: monospace; color: red;">
<p>inheritance can be super useful!</p>
</div>
2.2)Author embedded stylesheet : HTML dosyası içine yazılan CSS Rules. Aşağıdaki örnek gibi:
<style>
p {
font-family: georgia, serif;
font-size: x-small;
}
hr {
color: #ff9900;
height: 1px;
}
a:hover {
color: #ff0000;
text-decoration: none;
}
</style>
2.3)Author external stylesheet : Geliştirici oluşturduğu style dosyasını HTML dosyasına linkler:
<link rel=”stylesheet” href=”styles.css”>
3)User stylesheet : Tarayıcı üzerinde kullanıcı tarafından oluşturulan ayarlardır. Örneğin tarayıcıda yazı tipi boyutunu ayarlama.
CASCADE algoritması Conflict’i nasıl çözer?
Tarayıcınız yüklenen HTML sayfasını ilk olarak parse eder ve ondan bir DOM ağacı oluşturur. CSS selector, bu ağaçtaki elementlerle eşleşip onlara stil özelliklerini verir. Eğer bir element birden fazla rule ile eşleşiyorsa sırasıyla yukarıdaki görseldeki işlemler başlar. Bu işlemlerin hepsinin bir ağırlık puanı var gibi düşünebiliriz. Ağırlık puanı en yüksek olan rule elemente atanacaktır. Ağırlık puanı soldan sağa ve yukarıdan aşağı azalır. Yukarıdaki 3 aşamayı örnekler ile inceleyelim.
Origin & Importance
Bir CSS declaration’da importance, property sonuna eklenen !important
ifadesiyle sağlanır. !important
ifadesi eklendiğinde Cascade algoritmasını atlar ve !important
yazılı rule çalışır. Cascade algoritmasını atladığı için önerilmez. !important
kullanarak kod yazdığınız da bunu override etmesi zor olacağı için ileride size sıkıntılar çıkarabilir. Eklenti olarak Author stylesheet kullanıyorsanız(Bootstrap,Semantic UI gibi) Framework’ten gelenleri ezmek için kullanılabilir.
Burada Origin’den kastımız yukarıda açıkladığımız stylesheet kaynaklarıdır.(User-agent stylesheet,User stylesheet,Author stylesheet). Bu kaynakların da öncelikleri vardır. Bu kaynak önceliklerine ve Importance dikkate alındığında aşağıdaki liste ortaya çıkar. Önceliği yüksekten düşüğe doğru gitmektedir.
- User-Agent &
!important
- User &
!important
- Author &
!important
- CSS Animations,
@keyframes
- Author, normal weight
- User, normal weight
- User agent, normal weight
Bir input
elementi oluşturulduğunda tarayıcıdan gelen style dosyası geçerli olacaktır. Ancak seninput
elementine style
tag’i ekleyip property’lerini yazdığında bu tag içerisindeki style
geçerli olacaktır.
Bu örnektespecificity
(Aşağıda açıklayacağım bu kavramı) olarak alttaki declaration geçerli olması gerekirken !important
keyword’ü kullanıldığı için buton rengini üstteki rule belirleyecektir.
Specificity
Bizim Origin & importance önceliklerimiz iki rule içinde aynı ise bir sonraki aşama olan specificity
‘e bakarız. Specificity’i türkçeye spesifik olarak çevirebiliriz. Bizim tarayıcımız CSS declaration’a bakarak en spesifik selector’u seçecek. Specificity değerlendirilirken CSS selector sayısı ve Selector tiplerine bakılır.
- Inline styles (highest specificity): Bir elemente doğrudan style attribute ile stil verilir. :
<h1 style=”color: #ffffff;”>
. - IDs: Sayfadaki elementler için
unique
bir tanımlayıcıdır.Örneğin#navbar
. - Classes, attributes, and pseudo-classes: Bu kategori
.classes
,[attributes]
ve pseudo-classes(:hover
,:focus
gibi) içerir. - Elements and pseudo-elements (lowest specificity): Bu kategori element isimlerini ve pseudo-elements içerir. Örneğin
h1
,div
,::before
ve::after
gibi.
Tarayıcının Specificity nasıl hesapladığına bakalım. Farklı selector türlerine, puan cinsinden bir değer verilir. Bu puanlar karşılaştırılarak en yüksek puana sahip selector Specificity olarak belirlenir.
Specificity hesaplarken yukarıdaki puanları kullanacağız.
/* specificity: 0101 */
#outer a {
background-color: red;
}
/* specificity: 0201 */
#outer #inner a {
background-color: blue;
}/* specificity: 0104 */
#outer div ul li a {
color: yellow;
}/* specificity: 0113 */
#outer div ul .nav a {
color: white;
}/* specificity: 0024 */
div div li:nth-child(2) a:hover {
border: 10px solid black;
}/* specificity: 0023 */
div li:nth-child(2) a:hover {
border: 10px dashed black;
}/* specificity: 0033 */
div div .nav:nth-child(2) a:hover {
border: 10px double black;
}a {
display: inline-block;
line-height: 40px;
font-size: 20px;
text-decoration: none;
text-align: center;
width: 200px;
margin-bottom: 10px;
}ul {
padding: 0;
}li {
list-style-type: none;
}
<div id="outer" class="container">
<div id="inner" class="container">
<ul>
<li class="nav"><a href="#">One</a></li>
<li class="nav"><a href="#">Two</a></li>
</ul>
</div>
</div>
Specificity puanlarımız belli, şimdi sayfamızın çıktısında neler olacağını tahmin edelim. <a>
tagında içerisindeki metnin arka planı mavi renkte olacak. Metnin rengi beyaz olacak çünkü en spesifik selector’ler bunlar. Mouse Two yazısının üzerine getirdiğimizde de border oluşacak. Aşağıda çıktımız görünmektedir.
Elementimiz ile eşleşecek en spesifik selector bu şekilde seçilir.
Source Order
Eğer senin bütün selector’lerin aynı specificity değerine sahipse. En son declaration geçerli olacaktır.
Bu işlemlerin ardından elementlerimize style özellikleri veriliyor. CSS Cascading algoritması bu şekilde çalışıyor. Umarım yazım sizin için faydalı olmuştur.
Twitter: cihatata
Yazımı yazarken yararlandığım kaynakların listesi