CSS scroll-state()

Kapsayıcı sorguları gibidir ancak takılı, sabitlenmiş ve taşkın sorgular için kullanılır.

Yayınlanma tarihi: 15 Ocak 2025

Chrome 133, kaydırma durumu kapsayıcı sorgularını tanıtarak kapsayıcı sorgularını temel alır. Yapışkan konumlandırma, kaydırma sabitleme noktaları ve kaydırılabilir öğeler için tarayıcı tarafından yönetilen durum artık CSS'den sorgulanabilir ve uyarlanabilir.

Genel Bakış

Kaydırma durumu sorgularından önce, bir öğenin takılıp takılmadığını, sabitlenip sabitlenmediğini veya kaydırılıp kaydırılmayacağını anlamak için JavaScript'i kullanmanız gerekir. Artık bu bilgileri öğrenmek ve buna göre uyum sağlamak için standartlar kanalında daha yüksek performanslı bir yöntem mevcut. Ayrıca, CSS'de kaydırmayla tetiklenen animasyonların kilidini açan, animasyon tetiklemenin yeni bir yolu da vardır.

Chrome 133'ten kullanılabilen durum sorgularına genel bir bakış aşağıda verilmiştir:

Sıkışma durumu:
Bir öğe kenara yapıştırıldığında stil değişikliklerini tetikleyin.
Sabitlenmiş durum:
Bir öğe bir eksene sabitlendiğinde stil değişikliklerini tetikleyin.
Kaydırılabilir durum:
Bir öğe taştığında stil değişikliklerini tetikleyin.

İyi haber şu ki, kapsayıcı sorgularından öğrendiğiniz her şey kaydırma durumu sorgularıyla çalışırken size yardımcı olacaktır.

Kaydırma odaklı animasyonlar ve kaydırma durumu kapsayıcı sorguları arasında keşfedilmemiş alanlar da var. Kaydırma odaklı animasyonların mı yoksa kaydırma tetiklemesi yapılan kaydırma durumu animasyonlarının mı en iyi performansı sağlayacağını öğrenmek için zamanlama ve bağlamla ilgili denemeler yapmamız gerekiyor. Aşağıdaki video ve demoda, yapışkan olarak tetiklenen bir animasyonun kaydırma odaklı bir animasyonla karşılaştırması gösterilmektedir.

(sol) scroll-state() tarafından tetiklenen animasyon, (sağ) kaydırma tarafından yönlendirilen animasyon
https://codepen.io/web-dot-dev/pen/emOrBaV

İlk kaydırma durumu sorgusu

İlk adım, container-type mülkü için yeni bir değer kullanarak kapsayıcıyı tanımlamaktır. Kapsayıcı sorgusunda olduğu gibi, sorgulamak istediğiniz öğe, container-type ve isteğe bağlı olarak bir container-name verdiğiniz öğedir. Kaydırma durumu sorgularıyla, sabitlenen, takılan veya taşkın olan öğeye container-type: scroll-state değerini verirsiniz.

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;
}

İkinci adım, kapsayıcı sorgularında olduğu gibi, bu kapsayıcının duruma yanıt verecek alt öğesini seçmektir. Bu öğe, üzerinde container-type bulunan öğeyle aynı olamaz.

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  > nav {
    @container scroll-state(stuck: top) {
      background: Highlight;
      color: HighlightText;
    }
  }
}

Üçüncü adım, özelliği denemektir. Aşağıdaki CSS örneğinde, .stuck-top öğesi 0 noktasında üste yapışır olduğunda arka plan kırmızı renkte biçimlendirilir. CSS'ye daha önce yazacağımız birkaç satır ve tarayıcı durumunu proxy yapan ek bir kapsayıcı öğe ekleyerek bileşenlerimiz çevreleri hakkında çok daha akıllı hale gelir.

https://codepen.io/web-dot-dev/pen/ByBxpwR

Progresif Geliştirme

@supports at-kuralı ve iç içe yerleştirme, yalnızca birkaç ek kod satırında aşamalı geliştirme veya koşullu özellik kullanımı eklemenize olanak tanır:

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  @supports (container-type: scroll-state) {
    > nav {
      @container scroll-state(stuck: top) {
        background: Highlight;
        color: HighlightText;
      }
    }
  }
}

Ayrıca, kaydırma durumu sorgularıyla sayfadaki öğeleri animasyonlu hale getirirseniz hareketinizin etrafında @media (prefers-reduced-motion: no-preference) {} kullanmayı unutmayın.

Kullanım Alanları

Değişiklik Yok

Bu bölümün adı "Sorunlu durumlar" olabilir mi? Bu, yapışkan durum kullanım alanlarından oluşan küçük bir koleksiyonun yanı sıra geliştirilmesi gereken fikirlerin yer aldığı bir bonus bölümdür.

@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}

Tam söz dizimi listesi

Sıkıştığınızda gölge ekleme

Takılı kalmış bir sorgunun en yaygın kullanım alanlarından biri, takılı kaldıklarında box-shadow eklemek isteyen gezinme çubuklarıdır. Bu sayede, üzerine geldikleri içeriğin üzerinde yüzüyor gibi görünebilirler.

https://codepen.io/web-dot-dev/pen/GgKdryj
.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  > nav {
    transition: box-shadow .3s ease;

    @container scroll-state(stuck: top) {
      box-shadow: var(--shadow-5);
    }
  }
}

Mevcut takılı başlığı etkinleştirme

Kullanıcı arayüzünde sıkışmayla ilgili yaygın bir geri bildirim senaryosu da şu anda takılı olan öğenin vurgulanmasıdır. Alfabetik olarak sıralanmış bir grup listesinde bu özellik, deneyim açısından son derece yararlı ve destekleyici olabilir.

https://codepen.io/web-dot-dev/pen/pvzVRaK
.sticky-slide {
  dt {
    container-type: scroll-state;
    position: sticky;
    inset-block-start: 0;
    inset-inline: 0;

    > header {
      transition: 
        background .3s ease,
        box-shadow .5s ease;

      @container scroll-state(stuck: top) {
        background: hsl(265 100% 27%);
        box-shadow: 0 5px 5px #0003;
      }
    }
  }
}

Başlıkların liste öğelerinin yanında olduğu başka bir varyantı burada görebilirsiniz. Çok sayıda olasılık var.

https://codepen.io/web-dot-dev/pen/azoGpGg

Fikir taşması

Kaydırma durumu sorgularıyla demoya biraz renk katmanıza veya JavaScript'lerini kaldırmanıza ilham verebilecek yapışkan demoların listesi aşağıda verilmiştir. Beğendiğiniz bir tane oluşturmayı denemenizi öneririm. Bu, söz dizimi ve fikirlerin akılda kalmasına yardımcı olur 😏.

Fotoğrafladıklarınız

Sabitlenmiş durum sorgularıyla, JavaScript ve Snap Etkinlikleri'nin sorumluluğunun bir kısmını kaldırabilir ve işlemeyi CSS'ye taşıyabiliriz.

@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}

Tam söz dizimi listesi

İlk kaydırma durumu sorgusu bölümünü atladıysanız küçük bir hatırlatma: Sabitleme sorgusunun kapsayıcısı, üzerinde scroll-snap-align bulunan öğedir ve uyum sağlayabilen öğe, bu öğenin alt öğesi olmalıdır. Bu, bu özelliği ayarlamak için üç öğeye ihtiyaç duyulduğu anlamına gelir:

a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
    ⤷ a child of the snap target that can query the container for snap state

Kırpılan öğeyi görsel olarak geliştirme

Ortaya sabitlenmiş bir kaydırma çubuğunun, ortada sabitlenmiş öğeyi vurgulaması veya öne çıkarması yaygın bir durumdur. Bu referans örneğinde, not anahtar kelimesi kullanılmıştır. Böylece, sabitlenmemiş tüm referansların opaklığı düşük olurken sabitlenen referanslar doğal sunum durumunda kalır.

https://codepen.io/web-dot-dev/pen/NPKMdBX
.demo {
  overflow: auto hidden;
  scroll-snap-type: x mandatory;

  > article {
    container-type: scroll-state;
    scroll-snap-align: center;

    @supports (container-type: scroll-state) {
      > * {
        transition: opacity .5s ease;

        @container not scroll-state(snapped: x) {
          opacity: .25;
        }
      }
    }
  }
}

Kırpılan öğenin altyazısını gösterme

Bu, kaydırma durumu sorgularının kaydırma tetiklemesi animasyonunu nasıl etkinleştirdiğine dair iyi bir örnektir. Ayrıca, CSS'de azaltılmış harekete saygı duymanın ne zaman değerli olduğuna dair iyi bir örnektir.

https://codepen.io/web-dot-dev/pen/XJrqpBG
.demo {
  overflow-x: auto;
  scroll-behavior-x: contain;
  scroll-snap-type: x mandatory;

  > .card {
    container-type: scroll-state;
    scroll-snap-align: center;

    @supports (container-type: scroll-state) {
      @media (prefers-reduced-motion: no-preference) {
        figcaption {
          transform: translateY(100%);

          @container scroll-state(snapped: x) {
            transform: translateY(0);
          }
        }
      }
    }
  }
}

Slayt öğelerinde animasyon oluşturma

Konuşma yaparken slayt gösterisi veya sununun öğelerini animasyonlu olarak göstermek oldukça yaygın bir uygulamadır. Bunun için bir kesişim gözlemcisi yazmak oldukça can sıkıcıydı. Bu gözlemcinin tek yaptığı, slaytta bir sınıf ayarlamaktı. Artık JavaScript'e ihtiyacımız yok.

https://codepen.io/web-dot-dev/pen/dPbeNqY
html {
  scroll-snap-type: y mandatory;
}

section {
  container-type: scroll-state;
  scroll-snap-align: start;
  scroll-snap-stop: always;

  @supports (container-type: scroll-state) {
    @media (prefers-reduced-motion: no-preference) {
      > h1 {
        transition: opacity .5s ease, transform .5s var(--ease-spring-3);
        transition-delay: .5s;
        opacity: 0;
        transform: scale(1.25);

        @container scroll-state(snapped: block) {
          opacity: 1;
          transform: scale(1);
        }
      }
    }
  }
}

Sabitlenmiş tüm CSS durum sorgularının scrollsnapchange yerine scrollsnapchanging gibi davrandığını fark edebilirsiniz. Bu sayede, sabitlenen öğeyle ilgili görsel geri bildirim sağlamak için mümkün olan en erken kanca elde edersiniz. Çok istekliyse JavaScript etkinliğini kullanabilirsiniz.

Kaydırılabilir

Kaydırılabilir durum sorgusu, bir kaydırma alanının gerçekten kaydırılabilir olduğu durumlar için görsel kolaylıklar göstermede çok yararlı olacaktır. Kaydırma durumu sorguları kullanılmadan önce bu bilgiyi öğrenmek zordu.

@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}

Tam söz dizimi listesi

Kaydırma işlemini gölgelerle gösterme

Buna benzer bir efekt elde etmek için background-attachment: local kullanan Lea Verou'nun ünlü CSS hilesi ve bunu kaydırma odaklı animasyon ile yapmanın bir yolu vardır. Her tekniğin avantajları ve dezavantajları vardır. Bu tekniklerin her birinin ne zaman ve nerede en uygun olduğunu keşfetmemiz gerekir.

Aşağıdaki örnekte, kaydırma çubuğunu kaplayan tek bir yapışkan öğe kullanılmaktadır. Üstteki ve alttaki gradyanın opaklığı, bağlamsal kaydırma durumu sorgusu geçerli olduğunda @property ile animasyonlu olarak ayarlanır: @container scroll-state(scrollable: top).

Ayrıca, hem size hem de scroll-state kapsayıcısı olan ilk kapsayıcı olduğunu unutmayın.

https://codepen.io/web-dot-dev/pen/OPLZWBj
.scroll-container {
  container-type: scroll-state size;
  overflow: auto;

  &::after {
    content: " ";

    background: var(--_shadow-top), var(--_shadow-bottom);
    transition: 
      --_scroll-shadow-color-1-opacity .5s ease,
      --_scroll-shadow-color-2-opacity .5s ease;

    @container scroll-state(scrollable: top) {
      --_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
    }

    @container scroll-state(scrollable: bottom) {
      --_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
    }
  }
}

Ok istemi

Bazen bir ok göstermek, kullanıcıların bir alanın kaydırılabilir olduğunu keşfetmesine yardımcı olabilir. Bu düğmeler, kaydırma işleminin gerçekleşebileceği yönü gösterir ve artık gerekli olmadığında kaybolur. Bunu aşağıdaki kodla yapabilirsiniz.

https://codepen.io/web-dot-dev/pen/OPLZWBj
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
  translate: 0 calc(100% + 10px);
}

@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
  translate: 0 calc(100% + 10px);
  rotate: .5turn;
}

Başa dön

Kaydırma durumuyla ilgili popüler bir diğer etkileşim de "en üste kaydır" kolaylık düğmesidir. Aşağıdaki kod, yukarı kaydırılacak bir yer olmadığında en üste kaydır düğmesinin kaybolmasına neden olur.

Bu çözüm biraz ters olsa da CSS miktarını azaltmanıza olanak tanır. Düğmenin doğal dinlenme yeri görünür durumdadır. Bu nedenle, artık yukarı kaydıracak yer kalmadığında düğmeyi gizlemesini söylemeniz gerekir.

https://codepen.io/web-dot-dev/pen/OPLZWBj
@container not scroll-state(scrollable: top) {
  translate: 0 calc(100% + 10px);
}

Devam eden çalışma

Daha fazla bilgi edinmek istiyorsanız spesifikasyon ayrıntılarından bu konuyu ele alan diğer harika makalelere kadar çeşitli kaynaklara göz atın: