İçeriğe geç

Kurallar & Sınırlar

Observed işaretçileri için bilmeniz gereken ana kurallar ve çalışma zamanı sınırları bu sayfada toplanır.


? ve ?! selector parçasının en sonuna, boşluksuz yazılır. Pseudo varsa işaretçi pseudo'dan sonra gelir. Descendant zincirinde marker, CSS'in uygulandığı son element'e yazılır; ara selector'e değil. Bir selector ? veya ?! ile observed secildiyse, ayni kaynak icinde o selector observed root kabul edilir.

/* doğru */
.card?
.card?!
.btn:hover?
.btn:focus?!
.accordion-item.is-open .accordion-body?
/* yanlış */
.btn?:hover
.btn?!:focus
.card ?
.card ?!
.accordion-item.is-open? .accordion-body

Dis selector observed ise nested selector'lara tekrar ? veya ?! yazmak gerekmez.

.card? {
.title { color: red; }
&:hover { color: blue; }
}
@media (min-width: 920px) {
.card { display: flex; }
}

Bu kaynakta .card .title, .card:hover ve @media icindeki .card dynamic observed olur. .card?! kullanilsaydi ayni miras initial observed olarak calisirdi.

Root eslesmesi selector'un baslangicindan yapilir:

  • .card .title, .card:hover, .card > .title observed olur
  • .layout .card, .x + .card, :has(.card) observed olmaz

Observed işaretçisi @keyframes ve @-webkit-keyframes içinde anlamlı değildir.

/* yanlış kullanım */
@keyframes fade {
to? { opacity: 1; }
}

:root, html, body ve global reset amaçlı * selector'lerinde observed marker kullanmayın. Bu selector'ler normal dokümanlarda zaten vardır; observed kontrolü anlamlı bir tasarruf sağlamaz.

/* yanlış / gereksiz */
:root? { --brand: #2060ff; }
html? { min-height: 100%; }
body? { margin: 0; }
*? { box-sizing: border-box; }
/* doğru */
:root { --brand: #2060ff; }
html { min-height: 100%; }
body { margin: 0; }
* { box-sizing: border-box; }

*? syntax olarak geçerlidir, ancak çok geniştir. Yalnız gerçekten "bu subtree içinde herhangi bir eleman var mı" ihtiyacında düşünülmelidir.

Class / Id Değişiklikleri State Sistemi Değildir

Section titled “Class / Id Değişiklikleri State Sistemi Değildir”

Observed selector presence izler. Runtime class ve id mutation'larını yeniden değerlendirme için kullanabilir; çünkü bu değişiklikler selector'ın DOM'da eşleşip eşleşmediğini değiştirebilir.

.card.is-active? {
outline: 2px solid var(--c-accent);
}

Bu kural .is-active class'ı geldiğinde aktif, class kalktığında devre dışı kalabilir. Ama .card zaten her zaman DOM'daysa ve .is-active yalnız UI state ise çoğu durumda static CSS daha nettir:

.card.is-active {
outline: 2px solid var(--c-accent);
}

Observed'ı arbitrary state sistemi gibi kullanmayın; elemanın gerçekten bazen DOM'da olmayabileceği durumlara saklayın.

Observed selector'lar @media ve @supports içinde kullanılabilir. Önce at-rule koşulu değerlendirilir, sonra DOM selector kontrolü yapılır.

@media (min-width: 920px) {
.card? { display: flex; }
}

Virgullu Selector Parcalari Ayri Degerlendirilir

Section titled “Virgullu Selector Parcalari Ayri Degerlendirilir”

Observed ve normal selector ayni kural icinde virgulle karisik yazilabilir. Compiler her selector parcasini ayri siniflandirir.

.card?, .panel { color: red; }
.d .card, .card, .card .title { padding: 8px; }

Sonuc:

  • .card observed olur
  • .panel static kalir
  • .d .card static kalir
  • .card ve .card .title observed olur

Descendant Zinciri Tüm Selector İçin Kontrol Edilir

Section titled “Descendant Zinciri Tüm Selector İçin Kontrol Edilir”
.a .b .c? {
color: red;
}

Bu durumda yalnızca .c değil, tüm .a .b .c zincirinin DOM'da eşleşmesi gerekir.

Observed, DOM'da selector var mı yok mu sorusuna bakar. :hover, :focus, :active gibi kullanıcı etkileşimi state'lerini event tabanlı takip etmez.

Net kural:

  • observed = DOM presence
  • static selector = interaction state
/* güvenmeyin */
.tooltip-wrap:hover .tooltip?
.btn:focus?
.btn:active?!
/* doğru yaklaşım */
.tooltip? { opacity: 0; }
.tooltip-wrap:hover .tooltip { opacity: 1; }

Tooltip, modal, toast gibi eleman bazen DOM'da var bazen yoksa observed mantıklıdır. Ama hover/focus/active gibi görünürlük veya stil değişimi native CSS selector olarak yazılmalıdır.

.card? ve .card:hover? Aynı Şey Değildir

Section titled “.card? ve .card:hover? Aynı Şey Değildir”
.card? {
box-shadow: 0 1px 4px var(--c-shadow);
}
.card:hover? {
box-shadow: 0 4px 16px var(--c-shadow-md);
}

Bu yazım geçerlidir. Ama ikinci satırın anlamı şudur:

  • .card? -> DOM'da .card varsa base rule aktif olur
  • .card:hover? -> DOM'da .card varsa hover rule da yüklenir

Bu, "hover olunca observe et" anlamına gelmez. Hover değişimi observed tarafından ayrıca izlenmez; hover state'i yine native CSS ile çalışır.

Bu yüzden çoğu durumda daha net yazım şudur:

.card? {
box-shadow: 0 1px 4px var(--c-shadow);
}
.card:hover {
box-shadow: 0 4px 16px var(--c-shadow-md);
}

Kısa öneri:

  • .card? veya .card?! -> eleman bazen DOM'da yoksa mantıklı
  • .card:hover? veya .card:hover?! -> çoğu durumda gereksiz, kafa karıştırıcı
  • hover/focus/active state stillerini static selector olarak yazın

::before? ve ::after? Host Element Üzerinden Çalışır

Section titled “::before? ve ::after? Host Element Üzerinden Çalışır”
.tooltip? {
opacity: 0;
}
.tooltip::after? {
content: '';
border-top-color: var(--c-text);
}

Bu yazım geçerlidir. Ama anlamı şudur:

  • .tooltip? -> DOM'da .tooltip varsa base rule aktif olur
  • .tooltip::after? -> DOM'da .tooltip varsa ::after rule'u da yüklenir

Bu, pseudo-element için ayrı bir observed varlık kontrolü olduğu anlamına gelmez. ::before ve ::after gerçek DOM node olmadığı için observed host elementi baz alır.

Bu yüzden çoğu durumda daha net yazım şudur:

.tooltip? {
opacity: 0;
}
.tooltip::after {
content: '';
border-top-color: var(--c-text);
}

Kısa öneri:

  • host element bazen DOM'da yoksa .tooltip? veya .tooltip?!
  • pseudo-element kuralını çoğu durumda static bırakın
.player *?

Bu yazım geçerlidir. Ama * çok geniş bir hedef olduğu için observed tarafında gereksiz yere pahalı olabilir. Mümkünse *? yerine daha dar bir selector tercih edin:

  • .player .title?
  • .player .controls?
  • .player button?

Bu tür selector pseudo fonksiyonlarıyla observed kullanılabilir. Ama ? veya ?! parantez içindeki alt selector'a değil, her zaman dış kuyruğa yazılır.

/* doğru */
.shell:not(.is-collapsed)?
.menu:where(.is-ready, .is-open)?!
.panel:is(.wide, .stacked)?
/* yanlış */
.shell:not(.is-collapsed?)
.menu:where(.is-ready?!, .is-open)
.panel:is(.wide?, .stacked)
.lead + .item?
.lead ~ .note?!

Bu selector'lar geçerlidir. Eşleşme her zaman tam selector üzerinden doğrulanır. Ama yeniden değerlendirme token-index optimizasyonuna bağlıdır. Bu yüzden sibling ilişkisi çok sık değişiyorsa, araya başka node girmesi gibi bazı yapısal değişimler her durumda anında tekrar kontrol edilmeyebilir.

Kısa öneri:

  • sibling ilişkisi çok dinamikse static selector tercih edin
  • observed daha çok "bazen var, bazen yok" senaryolarında mantıklıdır

LimitVarsayılanKısa anlamı
maxObservedRules5.000Kaynaktaki toplam observed kural sayısı
maxObservedActiveRules1.000Aynı anda aktif olabilecek observed kural sayısı
maxObservedRuleKeysPerToken300Bir DOM token'ı için izlenebilecek maksimum kural key sayısı
maxMutationBatchTokens1.500Tek mutation batch'inde işlenebilecek token sayısı
maxObservedReevalPerTick500Tek tick'te yeniden değerlendirilebilecek observed kural sayısı

  • varsayılan politika fail-closed ise derleme hata ile durur
  • fail-soft ise derleme devam eder ve resource-limit warning'i üretilebilir
  • her limitin aşım davranışı aynı değildir; bazıları filtreleme, bazıları kırpma, bazıları runtime tarafında sessiz sınır uygulaması yapar