İçerik haritası bileşeni oluşturma

Kullanıcıların sitenizde gezinmesi için duyarlı ve erişilebilir bir içerik haritası bileşeni oluşturmaya dair temel bir genel bakış.

Bu yayında, içerik haritası bileşenlerini oluşturmanın bir yolu hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.

Demo

Videoyu tercih ediyorsanız bu yayının YouTube sürümünü burada bulabilirsiniz:

Genel Bakış

İçerik haritası bileşeni, kullanıcının site hiyerarşisindeki yerini gösterir. Bu terim, karanlık ormanda arkalarına ekmek kırıntıları bırakan ve geriye doğru izleyerek eve giden Hansel ile Gretel masalından gelir.

Bu gönderideki içerik haritaları standart değildir. içerik haritaları, içerik haritasına benzerler. Eşdüzey öğeye sahip olup ek işlevler sunarlar. <select> ile sayfaların doğrudan gezinme imkânına ulaşmasını sağlayarak çok katmanlı erişim yapmasını sağlar.

Arka plan kullanıcı deneyimi

Yukarıdaki bileşen demo videosunda yer tutucu kategorileri, video oyunlarının türleridir. Bu patika, aşağıda gösterildiği gibi home » rpg » indie » on sale yolunda gidilerek oluşturulur.

Bu içerik haritası bileşeni, kullanıcıların bu bilgi hiyerarşisinde gezinmesine, dallara atlamasına ve sayfaları hızlı ve doğru bir şekilde seçmesine olanak tanımalıdır.

Bilgi mimarisi

Koleksiyonlar ve öğeler açısından düşünmenin faydalı olduğunu düşünüyorum.

Koleksiyonlar

Koleksiyon, aralarından seçim yapabileceğiniz bir seçenek dizisidir. Bu makalenin içerik haritası prototipinin ana sayfasında FPS, RPG, dövüş, zindan oyunu, spor ve bulmaca koleksiyonları yer alıyor.

Öğe sayısı

Video oyunları öğedir. Belirli bir koleksiyon, başka bir koleksiyonu temsil ediyorsa öğe olarak da kabul edilebilir. Örneğin, RPG bir öğe ve geçerli bir koleksiyonudur. Öğe olduğunda kullanıcı ilgili koleksiyon sayfasındadır. Örneğin, RPG sayfasında bulunuyor. Burada, RPG oyunlarının bir listesi yer alıyor. AAA, Bağımsız ve Self Yayınlanan ek alt kategorileri var.

Bilgisayar bilimi terimleriyle bu içerik haritası bileşeni bir çok boyutlu dizi temsil eder:

const rawBreadcrumbData = {
  "FPS": {...},
  "RPG": {
    "AAA": {...},
    "indie": {
      "new": {...},
      "on sale": {...},
      "under 5": {...},
    },
    "self published": {...},
  },
  "brawler": {...},
  "dungeon crawler": {...},
  "sports": {...},
  "puzzle": {...},
}

Uygulamanız veya web siteniz, özel bilgi mimarisi (IA) ile çok boyutlu bir diziyi içeriyor. Umarım koleksiyon sonuca sayfa ve hiyerarşi geçişi de içerik haritalarınıza dahil edilebilir.

Düzenler

Brüt kar

İyi bileşenler uygun HTML ile başlar. Bu bölümde, proje yönetimiyle ilgili işaretleme seçeneklerini ve bunların genel bileşeni nasıl etkilediğini açıklayacağız.

Koyu ve açık renk şeması

<meta name="color-scheme" content="dark light">

Yukarıdaki color-scheme meta etiketi snippet, tarayıcıya bu sayfanın açık ve koyu renkli tarayıcı istediğini bildirir stillerini ayarlayın. Örnek içerik haritaları bu renk şemaları için herhangi bir CSS içermez Bu nedenle, hesapta görüntülenen yeri gösteren bağlantılar tarayıcı tarafından sağlanan varsayılan renkleri kullanır.

<nav class="breadcrumbs" role="navigation"></nav>

Bilgi edinmek için <nav> öğe yardımcı olur. Bu dönüşüm için dolaylı ARIA gezinme. Test sırasında, role özelliğine sahip olmanın bir web sitesi öğeyle etkileşime geçtiğini belirten bir bildirim aldınız. bu yüzden onu eklemeyi seçtim.

Simgeler

Bir simge bir sayfada tekrarlandığında SVG <use> öğesi, path öğesini bir kez tanımlayıp simgenin tüm örnekleri için kullanabileceğiniz anlamına gelir. Bu, aynı yol bilgilerinin tekrarlanmasını önler. Böylece, daha büyük belgeler oluşur ve yol tutarsızlığı olasılığı ortaya çıkar.

Bu tekniği kullanmak için sayfaya gizli bir SVG öğesi ekleyin ve simgeleri benzersiz bir kimliğe sahip bir <symbol> öğesine sarmalayın:

<svg style="display: none;">

  <symbol id="icon-home">
    <title>A home icon</title>
    <path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
  </symbol>

  <symbol id="icon-dropdown-arrow">
    <title>A down arrow</title>
    <path d="M19 9l-7 7-7-7"/>
  </symbol>

</svg>

Tarayıcı, SVG HTML'yi okur, simge bilgilerini belleğe yerleştirir ve simgenin ek kullanımları için kimliğe referans veren sayfanın geri kalanına devam eder. Örneğin:

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-home" />
</svg>

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-dropdown-arrow" />
</svg>

Oluşturulan bir SVG kullanım öğesini gösteren DevTools.

Bir kez tanımlayın, sayfa performansı üzerinde minimum etki ve esnek stil ile istediğiniz kadar kullanın. SVG öğesine aria-hidden="true" eklendiğini fark edin. Simgeler, yalnızca içeriği duyan, göz atan ve gizlenen bir kullanıcının gereksiz gürültü eklemelerini engeller.

Geleneksel içerik haritası ile bu bileşendeki içerik haritaları arasındaki fark burada ortaya çıkar. Normalde bu yalnızca bir <a> bağlantısı olurdu ancak gizlenmiş bir seçimle gezinme kullanıcı deneyimi ekledim. .crumb sınıfı, bağlantının ve simgesinin düzenlenmesinden sorumludur. .crumbicon sınıfı ise simgeyi ve seçili öğeyi birlikte yığmaktan sorumludur. İşlevleri bölünmüş düğmeye çok benzediği için bu bağlantıyı sayfa gezinme için bölünmüş bağlantı olarak adlandırdık.

<span class="crumb">
  <a href="#sub-collection-b">Category B</a>
  <span class="crumbicon">
    <svg>...</svg>
    <select class="disguised-select" title="Navigate to another category">
      <option>Category A</option>
      <option selected>Category B</option>
      <option>Category C</option>
    </select>
  </span>
</span>

Bağlantı ve bazı seçenekler, basit bir içerik haritasına daha fazla işlevsellik katan özel bir şey değildir. <select> öğesine title eklemek ekran açısından faydalı Okuyucu kullanıcıları'nı kullanarak, düğmenin hareketleri hakkında bilgi verebilirler. Ancak o diğer herkese de aynı yardımı sağlıyorsa bunun en önemli iPad'e dokunun. Bir özellik, birçok kullanıcıya düğme bağlamı sağlar.

Fareyle üzerine gelinen görünmez seçili öğenin ve bağlama dayalı ipucu metninin gösterildiği ekran görüntüsü.

Ayırıcı süslemeleri

<span class="crumb-separator" aria-hidden="true">→</span>

Ayırıcılar isteğe bağlıdır, yalnızca bir tanesi eklemek de çok işe yarar (Videodaki üçüncü örneğe bakın.) bölümüne bakın). Ardından, ekran okuyucunun okuması gerekmediği için her birine aria-hidden="true" değeri veririm.

Aşağıda açıklanan gap özelliği, bu öğelerin aralığını kolaylaştırır.

Stiller

Renk, sistem renklerini kullandığından stiller için çoğunlukla boşluklar ve yığınlardan oluşur.

Düzen yönü ve akışı

İçerik haritası gezinme hizalamasını, flexbox yer paylaşımı özelliğiyle gösteren DevTools.

Birincil gezinme öğesi nav.breadcrumbs, alt öğelerin kullanabileceği kapsamlı bir özel mülk ayarlar ve aksi takdirde yatay, dikey olarak hizalanmış bir düzen oluşturur. Bu sayede kırıntılar, bölücüler ve simgeler hizalanır.

.breadcrumbs {
  --nav-gap: 2ch;

  display: flex;
  align-items: center;
  gap: var(--nav-gap);
  padding: calc(var(--nav-gap) / 2);
}

Flexbox yer paylaşımlarıyla dikey olarak gösterilen bir içerik haritası.

Her .crumb ayrıca bazı öğeler için yatay olarak dikey olarak hizalanan bir düzen boşluk ekler, ancak özel olarak bağlantı alt öğelerini hedefler ve stili belirtir white-space: nowrap. Çok kelimeli içerik haritası yollarının birden fazla satıra sığdırılmasını istemediğimiz için bu, içerik haritası yolları için çok önemlidir. Bu gönderinin ilerleyen bölümlerinde, bu white-space özelliğinde yatay taşma neden oldu.

.crumb {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--nav-gap) / 4);

  & > a {
    white-space: nowrap;

    &[aria-current="page"] {
      font-weight: bold;
    }
  }
}

aria-current="page", mevcut sayfa bağlantısının öne çıkmasına yardımcı olmak için eklendi oluşturuyoruz. Ekran okuyucu kullanıcıları, bağlantının sorunsuz bir şekilde öğeyi, gören kullanıcılara yardımcı olacak şekilde görsel olarak biçimlendirdik. benzer bir deneyim yaşarsınız.

.crumbicon bileşeni, bir SVG simgesini "yakında" görünmez" <select> öğesi.

Satır ve sütunun adının stack olduğu bir düğmenin üzerine yerleştirilmiş Grid DevTools gösterilmektedir.

.crumbicon {
  --crumbicon-size: 3ch;

  display: grid;
  grid: [stack] var(--crumbicon-size) / [stack] var(--crumbicon-size);
  place-items: center;

  & > * {
    grid-area: stack;
  }
}

<select> öğesi DOM'da en son sırada yer aldığı için yığının en üstündedir ve etkileşimlidir. Öğenin kullanılabilir kalması için opacity: .01 stili ekleyin. Sonuç olarak, simgenin şekline mükemmel şekilde uyan bir seçim kutusu elde edersiniz. Bu, yerleşik işlevleri korurken <select> öğesinin görünümünü özelleştirmenin iyi bir yoludur.

.disguised-select {
  inline-size: 100%;
  block-size: 100%;
  opacity: .01;
  font-size: min(100%, 16px); /* Defaults to 16px; fixes iOS zoom */
}

Taşma

Kırıntılar çok uzun bir yolu temsil edebilmelidir. Yalnızca YouTube'da şeylerin yatay olarak kaydırılması gerektiğini fark ettim. içerik haritası bileşeni iyi bir şekilde nitelikli.

.breadcrumbs {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: calc(var(--nav-gap) / 2);

  & > .crumb:last-of-type {
    scroll-snap-align: end;
  }

  @supports (-webkit-hyphens:none) { & {
    scroll-snap-type: none;
  }}
}

Taşma stilleri aşağıdaki kullanıcı deneyimini ayarlamıştır:

  • Aşırı kaydırma sınırlaması olan yatay kaydırma.
  • Yatay kaydırma dolgusu.
  • Son harita üzerinde bir tutturma noktası. Bu, sayfa yüklendiğinde ilk kırıntı sabitlenip görüntüde yüklenir.
  • Yatay düzenlemede sorun yaşayan, tutturma noktasını Safari'den kaldırır. kombinasyonlarını kullanabilirsiniz.

Medya sorguları

Daha küçük ekran görüntüleri için yapabileceğiniz ince ayarlardan biri, "Ana Sayfa" etiketini gizleyerek yalnızca simgeyi bırakmaktır:

@media (width <= 480px) {
  .breadcrumbs .home-label {
    display: none;
  }
}

Karşılaştırma için ana sayfa etiketi olan ve olmayan içerik haritalarının yan yana görünümü.

Erişilebilirlik

Hareket

Bu bileşende çok fazla hareket yoktur. Bunun yerine, prefers-reduced-motion kontrolündeyken istenmeyen hareketi engelleyebiliriz.

@media (prefers-reduced-motion: no-preference) {
  .crumbicon {
    transition: box-shadow .2s ease;
  }
}

Diğer stillerin hiçbirinin değiştirilmesi gerekmez, fareyle üzerine gelme ve odaklama efektleri mükemmeldir ve transition olmadan da anlamlıdır, ancak hareket kabul edilirse, geçiş olabilir.

JavaScript

Öncelikle, sitenizde veya uygulamanızda kullandığınız yönlendiricinin türüne bakılmaksızın, kullanıcı ekmek kırıntılarını değiştirdiğinde URL'nin güncellenmesi ve kullanıcıya uygun sayfanın gösterilmesi gerekir. İkinci olarak, kullanıcı deneyimini normalleştirmek için kullanıcılar <select>seçeneklerine göz atarken beklenmedik gezinmelerin yapılmadığından emin olun.

JavaScript tarafından ele alınacak iki kritik kullanıcı deneyimi önlemi: değiştirilmiş ve istekli <select> değişiklik etkinliği etkinleşme önleyicisi.

<select> öğesinin kullanılması nedeniyle etkinliğin erkenden engellenmesi gerekir. Windows Edge'de ve muhtemelen diğer tarayıcılarda da changed Etkinlik, kullanıcı klavyeyle seçeneklere göz atarken tetiklenir. Kullanıcı, fareyle üzerine gelme veya odaklanma gibi seçenekleri yalnızca sözde seçtiğinden ve seçimi enter veya click ile onaylamadığından bu seçeneği istekli olarak nitelendiriyorum. İstekli etkinliği, bu bileşen kategorisi değişikliği özelliğine erişilememesine neden olur. seçim kutusunu açmak ve bir öğeye göz atmak, etkinliği tetikler ve sayfayı değiştirebilmelisiniz.

Daha iyi bir <select> değiştirilmiş etkinlik

const crumbs = document.querySelectorAll('.breadcrumbs select')
const allowedKeys = new Set(['Tab', 'Enter', ' '])
const preventedKeys = new Set(['ArrowUp', 'ArrowDown'])

// watch crumbs for changes,
// ensures it's a full value change, not a user exploring options via keyboard
crumbs.forEach(nav => {
  let ignoreChange = false

  nav.addEventListener('change', e => {
    if (ignoreChange) return
    // it's actually changed!
  })

  nav.addEventListener('keydown', ({ key }) => {
    if (preventedKeys.has(key))
      ignoreChange = true
    else if (allowedKeys.has(key))
      ignoreChange = false
  })
})

Bunun için strateji, her <select> öğesinde klavye aşağı etkinliklerini izlemek ve basılan tuşun gezinme onayı (Tab veya Enter) mı yoksa mekansal gezinme (ArrowUp veya ArrowDown) mi olduğunu belirlemektir. Bu belirlemeyle bileşen, <select> öğesinin etkinliği tetiklendiğinde beklemeye veya devam etmeye karar verebilir.

Sonuç

Bunu nasıl yaptığımı öğrendiğinize göre, siz ne yapardınız? 🙂

Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik geliştirmenin tüm yollarını öğrenelim. Bir demo oluşturun, bağlantılarını bana tweetleyin. Ardından, aşağıdaki topluluk remiksleri bölümüne ekleyeceğim.

Topluluk remiksleri