TV, telefon, masaüstü vb. için duyarlı yatay kaydırma görünümü oluşturmayla ilgili temel bir genel bakış.
Bu gönderide, web için minimal, duyarlı, erişilebilir ve tüm tarayıcı ve platformlarda (ör. TV'ler) çalışan yatay kaydırma deneyimleri oluşturmanın yollarıyla ilgili düşüncelerimizi paylaşmak istiyorum. Demoyu deneyin.
Video kullanmayı tercih ederseniz bu gönderinin YouTube versiyonunu kullanabilirsiniz:
Genel Bakış
Medya veya ürünlerin küçük resimlerini barındırmak için yatay kaydırma düzeni oluşturacağız. Bileşen, basit bir <ul>
listesi olarak başlar ancak CSS ile resimleri sergileyip ızgaraya yerleştirerek tatmin edici ve sorunsuz bir kaydırma deneyimine dönüştürülür. JavaScript, klavye kullanıcılarının 100'den fazla öğeyi atlamasına yardımcı olarak sabit kaydırma listesi etkileşimlerini kolaylaştırmak için eklenir.
Ayrıca, medya kaydırma çubuğunu hafif bir başlık kaydırma deneyimine dönüştürmek için deneysel bir medya sorgusu (prefers-reduced-data
) kullanılır.
Erişilebilir işaretlemeyle başlayın
Medya kaydırma çubuğu birkaç temel bileşenden, yani öğe içeren bir listeden oluşur. En basit haliyle bir liste, dünyanın her yerine ulaşabilir ve herkes tarafından net bir şekilde kullanılabilir. Bu sayfaya gelen kullanıcılar bir listeye göz atabilir ve bir öğeyi görüntülemek için bağlantıyı tıklayabilir. Bu, erişilebilir tabanımızdır.
<ul>
öğesi içeren bir liste yayınlama:
<ul class="horizontal-media-scroller">
<li></li>
<li></li>
<li></li>
...
<ul>
Liste öğelerini bir <a>
öğesiyle etkileşimli hale getirin:
<li>
<a href="#">
...
</a>
</li>
Bir resmi ve başlığını semantik olarak temsil etmek için <figure>
öğesini kullanın:
<figure>
<picture>
<img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
<figcaption>Legends</figcaption>
</figure>
<img>
web sitesindeki alt
ve loading
özelliklerine dikkat edin. Medya kaydırma çubuğu için alternatif metin, küçük resme ekstra bağlam kazandırmaya yardımcı olan bir kullanıcı deneyimi fırsatıdır veya resim yüklenmediyse yedek metin olarak veya ekran okuyucu gibi yardımcı teknolojilerden yararlanan kullanıcılar için sesli bir kullanıcı arayüzü sağlar. Uyumlu alternatif metinler için beş altın kural başlıklı makaleyi inceleyerek daha fazla bilgi edinin.
loading
özelliği, bu resim kaynağının yalnızca resim görüntü alanının içinde olduğunda getirilmesi gerektiğini belirtmek için lazy
anahtar kelimesini kabul eder. Kullanıcılar yalnızca ekrana kaydırdıkları öğelerin resimlerini indirdiği için bu özellik, büyük listeler için çok kullanışlı olabilir.
Kullanıcının renk şeması tercihini destekleme
Tarayıcınıza, sayfanızın hem açık hem de koyu renk sağlayan kullanıcı aracısı stillerini istediğini bildirmek için <meta>
etiketi olarak color-scheme
kullanın. Bu, bakış açınıza bağlı olarak ücretsiz bir koyu mod veya açık moddur:
<meta name="color-scheme" content="dark light">
Meta etiketi, mümkün olan en erken sinyali sağlar. Böylece tarayıcı, kullanıcının koyu tema tercihi varsa koyu bir varsayılan kanvas rengi seçebilir. Bu, sitenin sayfaları arasındaki gezinmelerin yüklemeler arasında beyaz bir tuval arka planıyla birlikte yanıp sönmeyeceği anlamına gelir. Yüklemeler arasında sorunsuz koyu tema, göze çok daha hoş geliyor.
Thomas Steiner'in https://web.dev/color-scheme/ adresindeki makalesinde bu konu hakkında daha fazla bilgi edinebilirsiniz.
İçerik ekle
ul > li > a > figure > picture > img
için yukarıdaki içerik yapısı göz önüne alındığında, sonraki adımda kaydırılacak resimler ve başlıklar eklemeniz gerekir. Demoyu statik yer tutucu resimler ve metinlerle doldurdum ancak dilerseniz bunu en sevdiğiniz veri kaynağından da besleyebilirsiniz.
CSS ile stil ekleme
Artık CSS'nin bu genel içerik listesini alıp bir deneyime dönüştürme zamanı geldi. Netflix, uygulama mağazaları ve daha birçok site ve uygulama, görüntü alanını kategori ve seçeneklerle doldurmak için yatay kaydırma alanları kullanır.
Kaydırma çubuğu düzenini oluşturma
Düzenlerde içeriğin kesilmesi veya metnin üç noktayla kısaltılmasından kaçınılması önemlidir. Birçok televizyonda bu gibi medya kaydırma çubuğu bulunur ancak çoğu zaman içerikler elipslerle gösterilir. Bu düzende ise bu durum söz konusu değildir. Ayrıca medya içeriğinin sütun boyutunu geçersiz kılmasına olanak tanır. Böylece 1 düzen, birçok ilginç kombinasyonu işleyebilecek kadar esnek olur.
Kapsayıcı, varsayılan boyutu özel mülk olarak sağlayarak sütun boyutunun geçersiz kılınmasına olanak tanır. Bu ızgara düzeni, sütun boyutu konusunda fikir sahibidir ve yalnızca boşluk ve yönü yönetir:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
margin: 0;
}
Özel özellik, daha sonra <picture>
öğesi tarafından temel en boy oranımızı oluşturmak için kullanılır: bir kutu:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
Sadece birkaç küçük stil kullanarak medya kaydırma çubuğunun temel özelliklerini tamamlayın:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
& > li {
display: inline-block; /* removes the list-item bullet */
}
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
overflow
ayarlandığında <ul>
öğesi, listede kaydırmaya ve klavyeyle gezinmeye izin verecek şekilde ayarlanır. Daha sonra, her doğrudan alt <li>
öğesi için ::marker
değeri kaldırılır. Bunun için yeni inline-block
görüntüleme türü alınır.
Ancak resimler henüz duyarlı değil ve kutuların içinden çıkıyor. Bazı boyutlar, sığdırma ve kenar stilleriyle ve gecikmeli yükleme sırasında arka plan degradesiyle kontrol altına alın:
img {
/* smash into whatever box it's in */
inline-size: 100%;
block-size: 100%;
/* don't squish but do cover the space */
object-fit: cover;
/* soften the edges */
border-radius: 1ex;
overflow: hidden;
/* if empty, show a gradient placeholder */
background-image:
linear-gradient(
to bottom,
hsl(0 0% 40%),
hsl(0 0% 20%)
);
}
Kaydırma dolgusu
Sayfa içeriğiyle hizalama ve uçtan uca kaydırılabilir bir yüzey alanı, uyumlu ve minimal bir bileşen için çok önemlidir.
Yazı tipimiz ve düzen çizgilerimizle uyumlu, kenardan kenara kaydırma düzeni oluşturmak için scroll-padding
ile eşleşen padding
kullanın:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}
Yatay kaydırma dolgusu hata düzeltmesi Yukarıdaki görselde, kaydırma kapsayıcısının doldurulmasının ne kadar kolay olması gerektiği gösterilmektedir. Ancak bu konuda önemli uyumluluk sorunları vardır (Chromium 91 ve sonraki sürümlerde düzeltilmiştir). Geçmişe dair biraz bilgi için buraya göz atın. Özet olarak, kaydırma görünümünde dolgu her zaman hesaba katılmamıştır.
Tarayıcıları, dolguyu kaydırma çubuğunun sonuna yerleştirecek şekilde kandırabilmek için her listenin sonundaki sayıyı hedefleyecek ve istenen dolgu miktarına eşit bir sözde öğe ekleyeceğim.
.horizontal-media-scroller > li:last-of-type figure {
position: relative;
&::after {
content: "";
position: absolute;
inline-size: var(--gap);
block-size: 100%;
inset-block-start: 0;
inset-inline-end: calc(var(--gap) * -1);
}
}
Mantıksal özellikler kullanmak, medya kaydırma çubuğunun herhangi bir yazma modunda ve doküman yönünde çalışmasını sağlar.
Kaydırarak tutturma
Taşma içeren bir kaydırma kapsayıcısı, tek satır CSS ile sabitlenen bir görüntü alanı haline gelebilir. Ardından, bu görüntü alanıyla nasıl hizalanacaklarını belirtmek alt öğelere aittir.
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block-end: calc(var(--gap) / 2);
scroll-snap-type: inline mandatory;
& figure {
scroll-snap-align: start;
}
}
Odak
Bu bileşenin ilham kaynağı, TV'lerde, uygulama mağazalarında ve diğer platformlarda büyük popülerliğidir. Birçok video oyunu platformu, birincil ana ekran düzeni olarak buna çok benzeyen bir medya kaydırma çubuğu kullanır. Odak, burada yalnızca küçük bir ekleme değil, kullanıcı deneyimi açısından büyük bir adımdır. Koltuğunuzdaki bu medya kaydırma çubuğunu bir uzaktan kumandayla kullandığınızı düşünün. Etkileşime küçük iyileştirmeler katın:
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
Bu, odak dış çizgisi stilini 7px
kutudan uzaklaştırarak güzel bir alan
kazanır. Kullanıcının hareketi azaltmayla ilgili bir hareket tercihi yoksa ofset geçişi yapılır. Bu sayede, odaklanma etkinliğine hafif bir hareket verilir.
Gezici dizin
Kaydırma içeren uzun içerik ve seçenek listelerinde gamepad ve klavye kullanıcılarına özel dikkat gösterilmelidir. Bu sorunu çözmek için kullanılan yaygın yönteme devriye dizini denir. Öğe kapsayıcısının klavyeyle odaklanıldığı ancak aynı anda yalnızca 1 alt öğenin odağı tutmasına izin verildiği durumdur. Bir seferde tek bir öğeye odaklanabildiğiniz bu deneyim, sonuna ulaşmak için Sekme tuşuna 50'den fazla kez basmak yerine, olası uzun öğe listesini atlamanıza olanak tanıyacak şekilde tasarlanmıştır.
Demo'nun ilk kaydırma çubuğunda 300 öğe var. Kullanıcıların bir sonraki bölüme ulaşmak için bunların tümünü taramasını sağlamak yerine daha iyi bir şey yapabiliriz.
Bu deneyimi oluşturmak için JavaScript'in klavye etkinliklerini ve odaklanma etkinlikleri gözlemlemesi gerekir. Bu kullanıcı deneyimini kolaylaştırmaya yardımcı olmak için npm'de küçük bir açık kaynak kitaplık oluşturdum. 3 kaydırma çubuğu için bunu nasıl yapacağınız aşağıda açıklanmıştır:
import {rovingIndex} from 'roving-ux';
rovingIndex({
element: someElement
});
Bu demo, kaydırma çubuğu içeren dokümanları sorgulayarak her biri için rovingIndex()
işlevini çağırır. Odak hedefleri doğrudan alt öğe olmadığında, liste kapsayıcısı gibi bir gezinme deneyimi elde etmek için rovingIndex()
öğesini ve hedef sorgu seçicisini iletin.
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
Bu efekt hakkında daha fazla bilgi edinmek için roving-ux açık kaynak kitaplığına bakın.
En-boy oranı
Bu yazının yazıldığından itibaren, aspect-ratio
desteği Firefox'ta bir bayrağın arkasında bulunuyor, ancak Chromium tarayıcılarda veya set üstü kutularda
kullanılabilir. Medya kaydırma çubuğu ızgara düzeni yalnızca yönü ve aralığı belirttiği için boyutlandırma, en boy oranı desteğini kontrol eden bir medya sorgusunda değişebilir.
Daha dinamik medya kaydırma çubuğuna yönelik aşamalı iyileştirme.
@supports (aspect-ratio: 1) {
.horizontal-media-scroller figure > picture {
inline-size: auto; /* for a block-size driven ratio */
aspect-ratio: 1; /* boxes by default */
@nest section:nth-child(2) & {
aspect-ratio: 16/9;
}
@nest section:nth-child(3) & {
/* double the size of the others */
block-size: calc(var(--size) * 2);
aspect-ratio: 4/3;
/* adjust size to fit more items into the viewport */
@media (width <= 480px) {
block-size: calc(var(--size) * 1.5);
}
}
}
}
Tarayıcı aspect-ratio
söz dizimini destekliyorsa medya kaydırıcısı resimleri aspect-ratio
boyutuna yükseltilir. Taslak iç içe yerleştirme söz dizimi kullanılarak her resim, ilk, ikinci veya üçüncü satır olduğuna bağlı olarak en boy oranını değiştirir. İç içe yerleştirme söz dizimi, diğer boyutlandırma mantığıyla birlikte bazı küçük görüntü alanı ayarlamaları yapılmasına da olanak tanır.
Bu CSS ile, özellik daha fazla tarayıcı motorunda bulunduğundan, yönetimi kolay ancak görsel olarak daha çekici bir düzen oluşturulur.
Azaltılmış verileri tercih eder
Bu sonraki teknik yalnızca Canary'de bir işaret altında kullanılabiliyor olsa da birkaç satır CSS ile sayfa yükleme süresinden ve veri kullanımından nasıl önemli ölçüde tasarruf edeceğimi paylaşmak istiyorum. 5. seviye prefers-reduced-data
medya sorgusu, cihazın veri tasarrufu modu gibi veri azaltılmış bir durumda olup olmadığını sormaya olanak tanır. Bu durumda, dokümanı değiştirebilir ve resimleri gizleyebilirim.
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
İçerikte gezinmeye devam edebilirsiniz ancak ağır resimler indirilmez. prefers-reduced-data
CSS'si eklenmeden önceki site:
(7 istek, 131 ms'de 100 KB kaynak)
prefers-reduced-data
CSS'si eklendikten sonra site performansı:
(71 istek, 1,07 saniyede 1,2 MB kaynak)
64 istek daha az (bu tarayıcı sekmesinin görüntü alanındaki yaklaşık 60 resim (geniş ekranda yapılan testler) anlamına gelir), sayfa yükleme hızında yaklaşık %80 artış ve kablo üzerinden aktarılan verilerin %10'u. Oldukça güçlü bir CSS.
Sonuç
Şimdi bunu nasıl yaptığımı biliyorsun, şimdi nasıl yaparsın? 🙂
Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik geliştirmenin tüm yollarını öğrenelim. Codepen'i oluşturun ya da kendi demonuzu yayınlayın ve tweet'inizi gönderin. Bu demoyu aşağıdaki Topluluk remiksleri bölümüne eklerim.
Kaynak
Topluluk remiksleri
Henüz burada görülecek bir şey yok.