Bir alt öğede CSS değişkenini geçersiz kılmak, üst öğesinden devralınan bileşik özel özelliği yeniden oluşturmaz. Üst öğe, iç içe başvuruyu zaten çözümlemiştir. Alt öğenin değerini kullanmak için bileşiği o alt öğede tanımlayın veya son özelliği orada bir araya getirin.

Bu kılavuz, bu davranışı açıklar ve Mac’te Chrome’da uygulanabilir bir masaüstü alıştırması sunar. Amaç, paylaşılan varsayılanları korurken bir bileşenin kenarlığının yerel renk geçersiz kılmasını izlemesini sağlamaktır.

Devralınan bileşik neden üst öğenin rengini koruyor?

Şu CSS parçasını ele alalım. Bu parça, bir .sample-board öğesinin içinde .sample-tile öğesi bulunduğunu varsayar:

.sample-board {
  --sample-color: teal;
  --sample-border: 6px solid var(--sample-color);
}

.sample-tile {
  --sample-color: darkorange;
  border: var(--sample-border);
}

Alt öğenin kenarlığı turkuaz kalır. CSS Variables belirtimi, özel özelliklerin iç içe var() işlevlerini devralmadan önce, hesaplanmış değer aşamasında çözümlendiğini belirtir. Sonuç olarak alt öğe, 6px solid teal eşdeğeri bir bileşiği devralır; --sample-color değerini alt öğeninkiyle değiştirecek bir ifade devralmaz. CSS Custom Properties for Cascading Variables Module Level 1.

Burada birbirinden ayrı iki özellik vardır. Alt öğede --sample-color ayarlamak, bu özelliğin yerel değerini değiştirir. Ayrıca --sample-border için yeni bir değer tanımlamaz. MDN’nin özel özelliklere ilişkin başvuru kaynağı, kaydedilmemiş sıradan özel özelliklerin devralındığını ve hesaplanmış değerlerinde değişkenlerin yerlerine konduğunu açıklar. Özel özellikler: CSS değişkenleri.

Bu örnekteki işlem sırası şöyledir:

  1. Üst öğe, --sample-color değerini teal olarak hesaplar.
  2. --sample-border, bu rengi yerine koyarak 6px solid teal sonucunu üretir.
  3. Alt öğe bu bileşiği devralır ve kendi renk belirtecini ayrı olarak darkorange değerine ayarlar.
  4. Alt öğenin border bildirimi, devralınan turkuaz bileşiği kullanır.

Bu, üst öğenin kalıcı bir anlık görüntüsü değildir. Üst öğenin rengi değişirse bileşiği güncellenebilir ve yeniden devralınabilir. Sınır, iç içe başvurunun çözümlendiği öğedir: alt öğenin geçersiz kılması bu hesaplamayı yukarı yönde etkilemez. CSS Variables: resolving dependencies.

Mac’te Chrome’da davranışı yeniden oluşturma

Mevcut sayfa stillerinin araya girmemesi için boş bir sayfa kullanın. Yeni bir Chrome sekmesi açın, adres çubuğuna about:blank yazın, ardından Command + Option + J tuşlarına basarak Console’u açın. Google, Mac için bu kısayolu DevTools kılavuzunda belgeliyor. Chrome DevTools’u açma.

Aşağıdaki eksiksiz tarayıcı konsolu programı, etiketli üç soyut şekil ve bunların stil sayfasını oluşturur. Kitaplık, görsel, ağ isteği veya mevcut sayfa öğesi gerektirmez. Boş sayfada bloğun tamamını bir kez çalıştırın. Aşağıdaki beklenen sonuçlar, belgelenmiş CSS kurallarından çıkarılmıştır; tarayıcıda ölçülmüş sonuçlar olarak sunulmamaktadır.

(() => {
  const board = document.createElement("section");
  board.className = "sample-board";

  const style = document.createElement("style");
  style.textContent = `
    .sample-board {
      --sample-color: teal;
      --sample-border: 6px solid var(--sample-color);
      display: flex;
      flex-wrap: wrap;
      gap: 24px;
      padding: 32px;
      font: 16px system-ui;
    }

    .sample-board .sample-tile {
      --sample-color: darkorange;
      display: grid;
      place-items: center;
      width: 120px;
      height: 80px;
      border: var(--sample-border);
      border-radius: 24px;
      background: white;
      color: black;
    }

    .sample-board .sample-local {
      --sample-border: 6px solid var(--sample-color);
    }

    .sample-board .sample-direct {
      border: 6px solid var(--sample-color);
    }
  `;

  const samples = [
    ["Inherited", "sample-inherited"],
    ["Local", "sample-local"],
    ["Direct", "sample-direct"]
  ];

  const tiles = samples.map(([label, className]) => {
    const tile = document.createElement("div");
    tile.className = `sample-tile ${className}`;
    tile.textContent = label;
    board.append(tile);
    return tile;
  });

  document.head.append(style);
  document.body.append(board);

  function report(stage) {
    console.log(stage);
    console.table(tiles.map((tile) => {
      const computed = getComputedStyle(tile);
      return {
        sample: tile.textContent,
        localColor: computed
          .getPropertyValue("--sample-color").trim(),
        composite: computed
          .getPropertyValue("--sample-border").trim(),
        paintedBorder: computed.borderTopColor
      };
    }));
  }

  report("Initial values");
  board.style.setProperty("--sample-color", "rebeccapurple");
  report("After changing the parent color");
})();

Program iki tablo yazdırır. Beklenen kenarlık renkleri şöyledir:

Örnek Başlangıçta Üst öğe değiştikten sonra Neden
Inherited Turkuaz Mor Üst öğenin hesaplanmış bileşiğini kullanır
Local Turuncu Turuncu Bileşiği alt öğede tanımlar
Direct Turuncu Turuncu Yerel rengi doğrudan border içinde yerine koyar

Üç alt öğenin de yerel renk belirteci darkorange olarak kalır. Yararlı tanılama örneği Direct’tir: devralınan bileşiği hâlâ üst öğenin rengini içerir, ancak kenarlık bildirimi bileşiği kullanmadığı için çizilen kenarlık yerel belirteci kullanır.

getComputedStyle(), etkin stil sayfaları uygulandıktan sonra çözümlenmiş özellik değerlerini okur. Böylece yalnızca yazılmış ifadeyi değil, bir öğenin gerçekte ne aldığını ortaya çıkarabilir. Renk serileştirmesi, özgün renk adı yerine rgb() değeri olarak görünebilir. Window: getComputedStyle() method.

Alıştırmayı temizlemek için boş sekmeyi yeniden yükleyin. Kendi sayfanızda seçtiğiniz CSS düzeltmesini stil sayfasına ekleyin; konsoldaki değişiklikler tanılama için kullanışlıdır ancak kaynak dosyalarınızı düzenlemez.

Hangi düzeltmeyi seçmelisiniz?

Bileşiği bileşen sınırında tanımlayın

Local örneği, yeniden kullanılabilir kenarlık belirtecini korur ve tarifini geçersiz kılmayı sağlayan öğede tanımlar. Programdaki ilgili CSS parçası şöyledir:

.sample-board .sample-local {
  --sample-color: darkorange;
  --sample-border: 6px solid var(--sample-color);
  border: var(--sample-border);
}

Birden fazla bildirimin aynı bir araya getirilmiş değere ihtiyaç duyduğu durumlarda bu deseni seçin. Temel varsayılanları bir üst öğeye, bileşik bildirimi ise özelleştirmenin sahibi olan bileşene koyun. Özel özellikler belirli öğelerde tanımlanabilir ve alt öğelerine devralınabilir; :root içinde bulunmaları gerekmez. CSS özel özelliklerini kullanma.

Ağacın daha alt kısımlarında da yerleşim önemini korur. Bir torun öğe temel değeri yeniden geçersiz kılarsa, bu bileşenden devralınan bileşik yine bu bileşenin hesaplamasını yansıtır. Farklı bir sonuç oluşturması gereken her alt öğe sınırında tarifi yeniden tanımlayın.

Kullanıldığı yerde son özelliği bir araya getirin

Direct örneği, kenarlık bildirimindeki ara belirteci kaldırır. Bu CSS parçası temel kuralı gösterir:

.sample-board .sample-direct {
  --sample-color: darkorange;
  border: 6px solid var(--sample-color);
}

Birleştirmeye yalnızca tek bir bildirim ihtiyaç duyduğunda bunu seçin. Ayrı genişlik, stil ve renk belirteçlerini yine paylaşabilir, ardından bunları bileşenin border bildiriminde bir araya getirebilirsiniz. MDN, var() işlevinin başka bir özelliğin değerinin tamamını veya bir bölümünü yerine koyabildiğini belgeliyor. CSS özel özelliklerini kullanma.

Bileşiğin tamamı herkese açık özelleştirme noktasıysa onu geçersiz kılın

Bazen bileşende amaçlanan özelleştirme, kenarlığın tamamıdır. Bu durumda yalnızca önceki girdisini değiştirmek yerine --sample-border için 6px solid darkorange gibi yerel bir değer sağlayın.

Bileşen sözleşmesini seçerken şu karar yardımını kullanın:

Amaçlanan özelleştirme Uygun desen
Tek bir yerel renk tek bir kenarlığı kontrol eder Doğrudan border içinde bir araya getirin
Birden fazla bildirim aynı bir araya getirilmiş değeri paylaşır Bileşiği bileşende tanımlayın
Çağıran taraf kenarlığın tamamını sağlar Bileşiğin kendisini geçersiz kılın
Alt öğeler üst öğenin bir araya getirdiği değeri aynen kullanmalıdır Devralınan bileşiği koruyun

Özgüllük, yedek değer veya devralma anahtar sözcükleri neden bileşiği yeniden oluşturmaz?

Önce temel değer geçersiz kılmasının gerçekten uygulandığını doğrulayın. Alt öğenin çözümlenmiş --sample-color değeri zaten darkorange ise aynı bildirimi daha özgül hâle getirmek, ayrı ve devralınmış --sample-border değerini değiştirmez. Her iki özelliğin de zaten bir değeri vardır; sorun, bileşiğin nerede oluşturulduğudur.

Benzer şekilde, --sample-border: inherit üst öğenin hesaplanmış değerini alır. Sıradan devralma, üst öğenin yazılmış bildirimini alt öğenin bağlamında yeniden çalıştırmak yerine hesaplanmış değerleri aktarır. Devralma.

var(--sample-border, 6px solid darkorange) gibi bir yedek değer de geçerli, devralınmış turkuaz kenarlığı değiştirmeden bırakır. var() yedek değeri, kullanılabilir bir değeri olmayan özel bir özelliği ele alır; bu değeri alt öğenin tercih edilen girdileriyle karşılaştırmaz. var() CSS function.

Geçersiz değerleri bu devralma sorunundan ayrı tutun. Örneğin, kaydedilmemiş bir belirteç 12px içerebilir ve özel özellik değeri olarak var olabilir; ancak border-color içinde yerine konduğunda geçersiz bir sonuç üretebilir. Bu var() çağrısındaki yedek değer, genel amaçlı bir tür denetimi alternatifi değildir. MDN, özel özellik yerine koymasının neden hesaplanmış değer aşamasında geçersiz hâle gelen bildirimler oluşturabileceğini açıklar. CSS özel özelliklerini kullanma.

Değişkeni @property ile kaydetmek bu sorunu çözer mi?

@property, özel bir özelliğin sözdizimini, başlangıç değerini ve devralma davranışını belirtmenizi sağlar. Üst öğenin devralınmış bileşiğini, alt öğenin geçersiz kılınmış girdilerini kullanarak yeniden değerlendirmez. Temel özelliği inherits: false ile kaydetmek, o temel değerin nasıl alındığını değiştirir; bileşiği bu şekilde kaydetmekse normal devralmayı durdurur. İkisi de eksik yerel tarifi sağlamaz. @property CSS at-rule.

Kaydetmenin uyumluluk sınırı da farklıdır. MDN, sıradan özel özelliklerin Nisan 2017’den beri tarayıcılarda yaygın olarak kullanılabildiğini; @property özelliğinin ise Temmuz 2024’te Baseline kullanılabilirliğine ulaştığını ve eski tarayıcılarda bulunmayabileceğini belirtiyor. Gösterilen iki düzeltme de kayıt gerektirmez. Özel özellikler: CSS değişkenleri, @property CSS at-rule.

Stil sayfanızda aynı sorunu nasıl tanılarsınız?

Görünümü hatalı olan öğede alıştırmadaki üç sütunlu karşılaştırmayı kullanın:

  1. --sample-color gibi temel belirteci okuyun.
  2. --sample-border gibi bileşik belirteci okuyun.
  3. border-top-color gibi çizilen özelliği okuyun.
  4. Bileşik bildirimin geçerli olduğu öğeyi bulun.
  5. Bildirimi hedeflenen özelleştirme sınırına taşıyın veya orada tekrarlayın ya da son özellikte doğrudan birleştirin.

Chrome’da ilgili kuralları bulmak için şekle sağ tıklayın ve Inspect seçeneğini belirleyin. DevTools, Elements bölümünde öğeyi seçer; Styles sekmesi de öğeye uygulanan CSS kurallarını gösterir. Chrome DevTools’u açma.

Temel belirteçte istenen yerel değer görünüyor ancak bileşik hâlâ üst öğenin değerini içeriyorsa önce bileşik bildiriminin tanımlandığı yeri inceleyin. Tarifi, girdilerinin okunması gereken yerde tanımlayın; ardından hem çözümlenmiş belirteci hem de çizilen sonucu doğrulayın. Böylece bileşenin açık ve öngörülebilir bir özelleştirme sınırı olur.

Kaynaklar