Codelab: Sidenav bileşeni oluşturma

Bu codelab'de, web'de duyarlı bir dışa doğru kaydırmalı gezinme düzeni bileşeninin nasıl oluşturulacağı öğretilmektedir. Bileşeni, ilerledikçe oluşturacağız. Önce HTML, ardından CSS, ardından JavaScript'i kullanacağız.

Bu bileşeni oluşturmak için seçilen CSS web platformu özellikleri hakkında bilgi edinmek için Sidenav bileşeni oluşturma adlı blog yayınıma göz atın.

Kurulum

  1. Projeyi düzenlenebilir hale getirmek için Düzenlenecek remiks'i tıklayın.
  2. app/index.html adlı kişiyi aç.

HTML

İlk olarak HTML kurulumuyla ilgili temel bilgileri edinin. Böylece üzerinde çalışabileceğiniz içerik ve bazı kutular elde edersiniz.

Aşağıdaki HTML'yi <body> etiketine bırakın.

<aside></aside>
<main></main>

<aside>, gezinme menüsünü birincil sayfa içeriğini barındıran <main> için tamamlayıcı bir öğe olarak tutar.

Daha sonra, bu anlamsal öğeleri sayfa içeriğinin geri kalanıyla dolduracağız.

<aside> öğesinin içine bir gezinme öğesi, birkaç gezinme bağlantıları ve bir kapatma bağlantısı ekleyin.

<aside>
  <nav>
    <h4>My</h4>
    <a href="#">Dashboard</a>
    <a href="#">Profile</a>
    <a href="#">Preferences</a>
    <a href="#">Archive</a>

    <h4>Settings</h4>
    <a href="#">Accessibility</a>
    <a href="#">Theme</a>
    <a href="#">Admin</a>
  </nav>

  <a href="#"></a>
</aside>

Bağlantılar <nav> öğelerinde mükemmel, <nav> öğeleri ise <aside> kenar çubuklarında mükemmel görünür. Yine de iyileştirmek için yapabileceğimiz daha fazla şey var.

Ana içerik öğesinde, düzen içeriğini anlamsal olarak tutmak için bir üstbilgi ve makale ekleyin.

<main>
  <header>
    <a href="#sidenav-open" class="hamburger">
      <svg viewBox="0 0 50 40">
        <line x1="0" x2="100%" y1="10%" y2="10%" />
        <line x1="0" x2="100%" y1="50%" y2="50%" />
        <line x1="0" x2="100%" y1="90%" y2="90%" />
      </svg>
    </a>
    <h1>Site Title</h1>
  </header>

  <article>
    {put some placeholder content here}
  </article>
</main>

Başlıkta menü açma bağlantısı var. Kenarda ise kapat düğmesi vardır. Yakında öğeleri görüntü alanı boyutuna göre gösterecek ve gizleyeceğiz.

<article> öğesine bir yer tutucu cümle yapıştırdık. "" öğesini kendi öğelerinizle değiştirin veya aşağıda sağlanan lorem'i yapıştırın:

<h2>Totam Header</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum consectetur, necessitatibus velit officia ut impedit veritatis temporibus soluta? Totam odit cupiditate facilis nisi sunt hic necessitatibus voluptatem nihil doloribus! Enim.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead Totam Odit</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

Bu içerik ve uzunluğu, görüntü alanı yüksekliğinizi aştığında sayfanın kaydırılabilir olmasına neden olur.

Şimdiye kadar gezinme, bağlantılar ve yan gezinme bölmesini kapatma yolu içeren bir kenara öğe eklediniz. Ayrıca bir üstbilgi, yan taraftaki gezinme bölmesini açma yöntemi ve ana öğeye bir makale eklediniz. Bu açık, anlamsal ve zaten zamana meydan okuyan bir metin, ancak herkes için daha anlaşılır ve net olmasını sağlayabiliriz. Yan gezinme bölmesindeki açık bağlantı daha açık bir şekilde işaretlenebilir.

Başlık açma bağlantısı öğesine title ve aria-label özelliklerini ekleyin:

<a href="#sidenav-open" class="hamburger">
<a href="#sidenav-open" title="Open Menu" aria-label="Open Menu" class="hamburger">

Açık SVG simgesi de daha net bir şekilde işaretlenebilir. Açık bağlantı öğesinin içindeki SVG'ye aşağıdaki özellikleri ekleyin:

<svg viewBox="0 0 50 40">
<svg viewBox="0 0 50 40" role="presentation" focusable="false" aria-label="trigram for heaven symbol">

Yan gezinme bölmesindeki kapat bağlantısı daha açık bir şekilde işaretlenebilirdi. Sidenav close bağlantı öğesine title ve aria-label özelliklerini ekleyin:

<a href="#"></a>
<a href="#" title="Close Menu" aria-label="Close Menu"></a>

CSS

Öğelerin düzenlenme zamanı. Ana içerik ve yan taraftaki gezinme çubuğu, <body> etiketinin doğrudan alt öğeleri olduğu için iyi bir başlangıç noktası bu olabilir.

<body> öğesinin alt öğeleri göstermesi için aşağıdaki CSS'yi css/sidenav.css öğesine ekleyin.

body {
  display: grid;
  grid: [stack] 1fr / min-content [stack] 1fr;

  @media (max-width: 540px) {
    & > :matches(aside, main) {
      grid-area: stack;
    }
  }
}

Bu düzenin özünde şöyle deniyor: Her şeyi içeren bir stack adlı satır ve bu satırda 2 sütun oluşturun. Bu satırın ikincisine stack adı da verilir. 1. sütun minimum içerik ihtiyaçlarına göre boyutlandırılmalıdır. Gerisini 2. sütun kullanabilir. Ardından, 540px veya daha küçük bir kısıtlanmış görüntü alanında, yan gezinme ve ana içerik öğelerini aynı satır ve sütuna yerleştirin. Bu, öğelerin 1x1 boyutunda birbirlerinin üstünde olmasını sağlar.

Temel olarak bu duyarlı yığma işlevselliğiyle artık kenar gezinme çubuğunun görünürlüğünü ve geçiş stilini değiştirmek için URL çubuğunun durumundan yararlanabiliriz.

<aside> öğesini app/index.html uygulamasında tekrar güncelleyin:

<aside>
<aside id="sidenav-open">

Bu, CSS'nin bir öğeyi ve URL karmasını birlikte eşleştirmesini sağlar. Bu, :target kullanımı için önemlidir. Artık öğenin kimliği, <a> etiketleriyle ayarlayacağımız URL karmasıyla eşleşebilir.

Buna ek olarak, daha kolay JavaScript hedeflemesi için yan taraftaki gezinme çubuğunu kontrol eden temel öğelerin kimliklerini ekleyin. İlk olarak, yan taraftaki gezinme açma bağlantısına bir kimlik ekleyin:

<a href="#sidenav-open" class="hamburger" title="Open Menu" aria-label="Open Menu">
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">

Daha sonra, yan taraftaki gezinme kapatma bağlantısına bir kimlik ekleyin:

<a href="#" title="Close Menu" aria-label="Close Menu"></a>
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>

Bu işlem, <body> duyarlı yığın düzenini kapatır ve bizi URL çubuğuna bağlar. Devam edelim!

<aside> cihazının da düzenli bir düzeni var. 2 alt öğesi vardır. Bir <nav> kağıt benzeri, kayan bir bileşendir ve URL'yi ayarlayan kapanış <a> bağlantı öğesi # değerine sahip olmalıdır. Bağlantı, kağıdın dışarı kaydırılan gezinme bölmesinde görünmez; böylece insanlar görsel bileşeni "tıklayarak" kapatabilir.

css/sidenav.css için şu CSS'yi ekleyin:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;
}

Oran ve adların burada güzel bir dokunuş olduğunu düşündüm. Izgaranın parlayıp tasarımcıya daha fazla kontrol kazandırabileceğini düşünüyorum.

Ardından, koşullu olarak ana içeriği yer paylaşımlı olarak yerleştirmem ve herhangi bir belge kaydırma işlemiyle konumumu korumam gerekir. Bu, position: sticky ve bazı overscroll-behavior için harika bir fırsat.

Kenar gezinme bölmesi için aşağıdaki stilleri ekleyin:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;

  @media (max-width: 540px) {
    position: sticky;
    top: 0;
    max-height: 100vh;
    overflow: hidden auto;
    overscroll-behavior: contain;

    visibility: hidden; /* not keyboard accessible when closed */
  }
}

Bu stiller, yan gezinme çubuğunun görüntü alanı yüksekliği olmasını, dikey olarak kaydırılmasını ve kaydırmayı içermesini sağlar. Çok önemli bir nokta da öğeyi gizler. Varsayılan olarak, görüntü alanı 540px veya daha küçük olduğunda yan taraftaki gezinme bölmesini gizleyin. Ama elbette!

#sidenav-open öğesine bir :target sözde seçicisi ekleyin:

#sidenav-open {

  @media (max-width: 540px) {

    &:target {
      visibility: visible;
    }
  }
}

Bu öğenin kimliği ile URL çubuğu aynı olduğunda visibility öğesini visible olarak ayarlayın. Devam edin ve sayfayı kaydırdıktan sonra yan menüyü açın veya yan gezinme çubuğu açıkken sayfayı kaydırmayı deneyin. Ne düşünüyorsunuz?

app/sidenav.css öğesinin altına aşağıdaki CSS'yi ekleyin:

#sidenav-button,
#sidenav-close {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  touch-action: manipulation;

  @media (min-width: 540px) {
    display: none;
  }
}

Bu stiller, aç ve kapat düğmelerimizi hedefler, dokunma ve dokunma stillerini belirtir ve ayrıca görüntü alanları 540px veya daha büyük olduğunda bunları gizler.

Biraz renk katmak için, erişilebilirlik kurallarına uygun CSS dönüşümleri ekleyelim. css/sidenav.css için şu CSS'yi ekleyin:

#sidenav-open {
  --easeOutExpo: cubic-bezier(0.16, 1, 0.3, 1);
  --duration: .6s;

  ...

  @media (max-width: 540px) {
    ...

    transform: translateX(-110vw);
    will-change: transform;
    transition:
      transform var(--duration) var(--easeOutExpo),
      visibility 0s linear var(--duration);

    &:target {
      visibility: visible;
      transform: translateX(0);
      transition: transform var(--duration) var(--easeOutExpo);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    --duration: 1ms;
  }
}
"Tercih edilen azaltılmış hareket" medya sorgusuna dayalı olarak uygulanan süre içeren ve içermeyen etkileşimin demosu.

Biraz JavaScript kodu ekleyin

Escape tuşu menüyü kapatır. Bu JS'yi js/index.js hesabına ekle:

const sidenav = document.querySelector('#sidenav-open');

sidenav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    document.location.hash = '';
  }
});

Bu, sidenav öğesindeki bir önemli etkinliği dinler. Escape ise URL karmasını boş olarak ayarlar ve yan gezinme geçişi devre dışı bırakılır.

UX JS'nin bir sonraki aşaması odak yönetimidir. Açılış ve kapanışı kolaylaştırmak istiyorum. Bu yüzden yan taraftaki gezinme bölmesi bir tür geçişi bitirene kadar bekliyorum, ardından içeride mi yoksa dışta mı olduğunu belirlemek için URL karmasıyla karşılaştırmalı olarak kontrol ediyorum. Daha sonra, düğmeye odaklanmasını az önce basılan düğmeye tamamlayıcı olarak ayarlamak için JavaScript kullanıyorum.

js/index.js öğesine aşağıdaki JavaScript'i ekleyin:

const closenav = document.querySelector('#sidenav-close');
const opennav = document.querySelector('#sidenav-button');

sidenav.addEventListener('transitionend', e => {
  if (e.propertyName !== 'transform') {
    return;
  }

  const isOpen = document.location.hash === '#sidenav-open';

  isOpen
    ? closenav.focus()
    : opennav.focus();
});

Deneyin

  • Siteyi önizlemek için Uygulamayı Göster'e, ardından Tam Ekran'a tam ekran basın.

Sonuç

Bileşenle ilgili ihtiyaçlarımla ilgili özet bilgi vermek istedik. Bunun üzerine inşa edebilir, URL yerine JavaScript durumuyla yürütebilir ve genel olarak kendinize özel hale getirebilirsiniz. Daima konuşulacak başka şeyler veya dikkat edilmesi gereken daha fazla kullanım alanı vardır.

Bu bileşene uyguladığım ve düzenle ilgili olmayan stillere göz atmak için css/brandnav.css öğesini açın. Odaklandığım özellik grubu için bunun önemli olduğunu hissetmemiştim ve stilleri düzenden ayırmanın, kopyalayıp yapıştırmayı teşvik edeceğini umuyordum. Orada daha çok şey öğrenebilirsin!

Kaydırılabilir duyarlı yan gezinme bileşenleri nasıl oluşturulur? Mesela iki taraf için de 1'den fazla mı? Çözümünüzü bir YouTube videosunda öne çıkarmak isterim. Kodunuzu tweet'leyerek veya YouTube'da yorum yaparak herkese yardımcı olabilirsiniz.