Bu yazıda, web için minimal, hızlı yanıt veren, erişilebilir ve tarayıcılar ve platformlar (TV’ler gibi!) üzerinde çalışan yatay kaydırma deneyimleri oluşturmanın yollarını paylaşmak istiyorum. deneyin gösteri.
Videoyu tercih ederseniz, işte bu gönderinin bir YouTube versiyonu:
genel bakış #
Medya veya ürünlerin küçük resimlerini barındırmak için yatay bir kaydırma düzeni oluşturacağız. Bileşen mütevazi olarak başlar <ul>
liste, ancak CSS ile tatmin edici ve pürüzsüz bir kaydırma deneyimine dönüştürülür, görüntüler sergilenir ve bir ızgaraya yapıştırılır. Gezici dizin etkileşimlerini kolaylaştırmak için JavaScript eklendi ve klavye kullanıcılarının 100’den fazla öğe arasında gezinmeyi atlamasına yardımcı oldu. Ayrıca deneysel bir medya sorgusu, prefers-reduced-data
medya kaydırma çubuğunu hafif bir başlık kaydırma deneyimine dönüştürmek için kullanılır.
Erişilebilir işaretlemeyle başla #
Bir medya kaydırıcı, yalnızca birkaç temel bileşenden, öğeler içeren bir listeden oluşur. En basit haliyle bir liste tüm dünyayı dolaşabilir ve herkes tarafından açıkça tüketilebilir. Bu sayfaya gelen bir kullanıcı bir listeye göz atabilir ve bir öğeyi görüntülemek için bir bağlantıya tıklayabilir. Bu bizim erişilebilir üssümüz.
ile bir liste sunun <ul>
eleman:
ul class="horizontal-media-scroller">
li></li>
li></li>
li></li>
...
ul>
Liste öğelerini etkileşimli hale getirin <a>
eleman:
li>
a href="#">
...
</a>
</li>
Kullanın <figure>
bir görüntüyü ve başlığını anlamsal olarak temsil eden öğe:
figure>
picture>
img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
figcaption>Legends</figcaption>
</figure>
Dikkat edin alt
Ve loading
üzerindeki nitelikler <img>
. Medya kaydırıcı için alternatif metin, kullanıcı deneyimi fırsatı küçük resme ekstra bağlam getirmeye yardımcı olmak için veya resim yüklenmediyse yedek metin olarak veya ekran okuyucu gibi yardımcı teknolojiye güvenen kullanıcılar için sesli bir kullanıcı arayüzü sağlar. ile daha fazla bilgi edinin Uyumlu alternatif metin için beş altın kural.
bu loading
öznitelik anahtar kelimeyi kabul eder lazy
bu görüntü kaynağının yalnızca görüntü görüntü alanı içindeyken getirilmesi gerektiğine işaret etmenin bir yolu olarak. Bu, büyük listeler için gerçekten güzel olabilir, çünkü kullanıcılar yalnızca kaydırarak görüntüledikleri öğelerin resimlerini indirirler.
Kullanıcının renk şeması tercihini destekleyin #
Kullanmak color-scheme
olarak <meta>
etiketi, tarayıcıya, sayfanızın kullanıcı aracısı tarafından sağlanan hem açık hem de koyu stilleri istediğini belirtmek için kullanılır. Nasıl baktığınıza bağlı olarak, ücretsiz bir karanlık mod veya aydınlık moddur:
meta name="color-scheme" content="dark light">
Meta etiketi mümkün olan en erken sinyali sağlar, böylece kullanıcının koyu bir tema tercihi varsa tarayıcı koyu bir varsayılan tuval rengi seçebilir. Bu, sitenin sayfaları arasındaki gezinmelerin yüklemeler arasında beyaz bir kanvas arka planı göstermeyeceği anlamına gelir. Yükler arasında kesintisiz koyu tema, göze çok daha hoş geliyor.
https://web.dev/color-scheme/ adresinden Thomas Steiner’dan çok daha fazlasını öğrenin.
içerik ekle #
Yukarıdaki içerik yapısı göz önüne alındığında ul > li > a > figure > picture > img
, sonraki görev, kaydırmak için resimler ve başlıklar eklemektir. Demoyu statik yer tutucu resimler ve metinle doldurdum, ancak bunu en sevdiğiniz veri kaynağından kullanmaktan çekinmeyin.
CSS ile stil ekleyin #
Şimdi CSS’nin bu genel içerik listesini alıp bir deneyime dönüştürme zamanı. Netflix, Uygulama mağazaları ve daha pek çok site ve uygulama, görünümü kategoriler ve seçeneklerle doldurmak için yatay kaydırma alanlarını kullanır.
Kaydırıcı düzenini oluşturma #
Mizanpajlarda içeriği kesmekten veya üç nokta ile metin kesmeye yaslanmaktan kaçınmak önemlidir. Pek çok televizyon setinde bunun gibi medya kaydırıcılar bulunur, ancak çoğu zaman içeriği eksiltmeye başvururlar. Bu düzen değil! Ayrıca, medya içeriğinin sütun boyutunu geçersiz kılmasına izin vererek 1 düzeni birçok ilginç kombinasyonun üstesinden gelebilecek kadar esnek hale getirir.
Kapsayıcı, varsayılan boyutu özel bir özellik olarak sağlayarak sütun boyutunu geçersiz kılmaya olanak tanır. Bu ızgara düzeni, sütun boyutu hakkında düşünülür, yalnızca aralığı 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 tarafından kullanılır <picture>
temel en boy oranımızı oluşturmak için öğe: 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);
}
}
Yalnızca birkaç küçük stille daha, medya kaydırıcının ana hatlarını 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);
}
}
Ayar overflow
ayarlar <ul>
listede kaydırmaya ve klavyeyle gezinmeye izin vermek için yukarıya, ardından her bir doğrudan alt öğeye <li>
eleman onun ::marker
yeni bir görüntüleme türü alarak kaldırıldı inline-block
.
Ancak görüntüler henüz yanıt vermiyor ve içinde bulundukları kutulardan fırlıyor. Onları bazı boyutlar, sığdırma ve kenarlık stilleri ve geç yüklendikleri zamanlar için bir arka plan gradyanı ile evcilleştirin:
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ğine hizalama ve uçtan uca kayan yüzey alanı, uyumlu ve minimal bir bileşen için çok önemlidir.
Tipografi ve mizanpaj çizgilerimizle hizalanan uçtan uca kaydırma düzenini gerçekleştirmek için şunu kullanın: padding
eşleşen scroll-padding
:
.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, bir kaydırma kapsayıcısını doldurmanın ne kadar kolay olması gerektiğini gösteriyor, ancak bununla ilgili olağanüstü uyumluluk sorunları var (yine de Chromium 91+ sürümünde düzeltildi!). Görmek Burada biraz tarih için, ancak kısa versiyon, dolgunun her zaman bir kaydırma görünümünde hesaba katılmadığıdır.
Tarayıcıları kaydırma çubuğunun sonuna doldurma koymaları için kandırmak için her listedeki son rakamı hedefleyeceğim ve istenen dolgu miktarı olan sözde bir öğ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 özelliklerin kullanılması, medya kaydırma çubuğunun herhangi bir yazma modunda ve belge yönünde çalışmasını sağlar.
Kaydırma yakalama #
Taşan bir kayan kapsayıcı, tek satırlık bir CSS’ye sahip bir görüntü alanı haline gelebilir, ardından bu görüntü alanıyla nasıl hizalamak istediklerini belirtmek çocuklara düşer.
.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, App Store’larda ve daha fazlasında büyük popülaritesinden geliyor. Birçok video oyunu platformu, birincil ana ekran düzeni olarak buna çok benzer bir medya kaydırıcı kullanır. Odak, burada yalnızca küçük bir ekleme değil, büyük bir UX anıdır. Bu medya kaydırıcıyı koltuğunuzdan bir uzaktan kumandayla kullandığınızı hayal edin, bu etkileşime bazı küçük geliştirmeler katın:
.horizontal-media-scroller a {
outline-offset: 12px;&:focus {
outline-offset: 7px;
}
TheComedicComedian (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
Bu, odak anahattı stilini ayarlar 7px
kutudan uzakta, ona güzel bir alan sağlıyor. Kullanıcının hareketi azaltmakla ilgili herhangi bir hareket tercihi yoksa ofset değiştirilir ve odak olayına hafif hareket verilir.
fitil indeksi #
Oyun kumandası ve klavye kullanıcılarının, bu uzun kayan içerik ve seçenek listelerinde özel dikkat göstermeleri gerekir. Bunu çözmek için ortak modele fitil indeksi denir. Bir öğe kapsayıcısının klavye odaklı olduğu ancak aynı anda yalnızca 1 çocuğun odaklanmasına izin verildiği zamandır. Tek seferde bu tek odaklanılabilir öğe deneyimi, sona ulaşmak için sekmeye 50’den fazla kez basmak yerine potansiyel olarak uzun öğe listesini atlamaya izin verecek şekilde tasarlanmıştır.
Demonun ilk kaydırıcısında 300 öğe var. Hepsini bir sonraki bölüme geçmek için geçmekten daha iyisini yapabiliriz.
Bu deneyimi oluşturmak için JavaScript’in klavye olaylarını gözlemlemesi ve olaylara odaklanması gerekir. ben YARATTIM npm’de küçük bir açık kaynak kitaplığı bu kullanıcı deneyiminin elde edilmesini kolaylaştırmaya yardımcı olmak için. 3 kaydırıcı için nasıl kullanılacağı aşağıda açıklanmıştır:
import {rovingIndex} from 'roving-ux';rovingIndex({
element: someElement
});
Bu demo, kaydırıcılar için belgeyi sorgular ve her biri için rovingIndex()
işlev. Geç rovingIndex()
Odak hedeflerinin doğrudan alt öğeler olmaması durumunda, bir liste kapsayıcısı ve bir hedef sorgu seçici gibi gezici deneyimi elde edecek öğe.
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
Bu efekt hakkında daha fazla bilgi edinmek için açık kaynak kitaplığına bakın. gezici-ux.
en-boy oranı #
Bu yazıyı yazarken, için destek aspect-ratio
Firefox’ta bir bayrağın arkasındadır, ancak Chromium tarayıcılarında veya set üstü kutularda bulunur. Medya kaydırıcı ızgara düzeni yalnızca yönü ve aralığı belirttiğinden, boyutlandırma, en-boy oranı desteğini kontrol eden bir medya sorgusu içinde değişebilir. Bazı daha dinamik medya kaydırıcılarda aşamalı geliş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 */
HonestlyaBot section:nth-child(2) & {
aspect-ratio: 16/9;
}
HonestlyaBot 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 */
TheComedicComedian (width ) {
block-size: calc(var(--size) * 1.5);
}
}
}
}
Tarayıcı destekliyorsa aspect-ratio
sözdizimi, medya kaydırma resimleri şuna yükseltilir: aspect-ratio
boyutlandırma Taslak iç içe sözdizimini kullanarak, her resmin en boy oranı birinci, ikinci veya üçüncü satır olmasına bağlı olarak değişir. bu yuva sözdizimi ayrıca, diğer boyutlandırma mantığıyla birlikte bazı küçük görüntü alanı ayarlarının yapılmasına da izin verir.
Bu CSS ile, özellik daha fazla tarayıcı motorunda mevcut olduğundan, yönetimi kolay ancak görsel olarak daha çekici bir düzen oluşturulacaktır.
Azaltılmış verileri tercih eder #
Bu sonraki teknik yalnızca mevcut olsa da bir bayrağın arkasında içinde Kanarya, Birkaç satır CSS ile sayfa yükleme süresinden ve veri kullanımından nasıl önemli ölçüde tasarruf edebileceğimi paylaşmak istedim. bu prefers-reduced-data
medya sorgusu Seviye 5 cihazın veri tasarrufu modu gibi herhangi bir azaltılmış veri durumunda olup olmadığını sormaya izin verir. Öyleyse, belgeyi değiştirebilir ve bu durumda görüntüleri gizleyebilirim.
figure {
TheComedicComedian (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);& > picture {
display: none;
}
}
}
}
İçerik hala gezinilebilir, ancak indirilen ağır resimlerin maliyeti yoktur. İşte siteyi eklemeden önce prefers-reduced-data
CSS:
(7 istek, 131 ms’de 100 kb kaynak)
İşte ekledikten sonraki site performansı prefers-reduced-data
CSS:
(71 istek, 1.07’de 1.2 MB kaynak)
64 daha az istek, bu, bu tarayıcı sekmesinin görünüm alanındaki (geniş ekranda yapılan testler) ~60 resim, ~%80’lik bir sayfa yükleme artışı ve kablo üzerinden verilerin %10’u olacaktır. Oldukça güçlü CSS.
Çözüm #
Artık nasıl yaptığımı bildiğine göre, nasıl yapardın?! 🙂
Yaklaşımlarımızı çeşitlendirelim ve web üzerinde oluşturmanın tüm yollarını öğrenelim. Bir Codepen oluşturun veya kendi demonuzu barındırın, onunla bana tweet atın, ben de onu aşağıdaki Topluluk remiksleri bölümüne ekleyeyim.
Kaynak
Topluluk remiksleri #
Burada henüz görülecek bir şey yok!