Ayarlar bileşeni oluşturma

Kaydırma çubukları ve onay kutularından oluşan bir ayar bileşeninin nasıl oluşturulacağına dair temel bir genel bakış.

Bu yayında, web için duyarlı, birden fazla cihaz girişini destekleyen ve tarayıcılar arasında çalışan bir Ayarlar bileşeni oluşturma konusundaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.

Demo

Video izlemeyi tercih ediyorsanız veya geliştirdiğimiz ürünün kullanıcı arayüzü/kullanıcı deneyimi önizlemesini görmek istiyorsanız YouTube'daki daha kısa olan bu kılavuzu inceleyebilirsiniz:

Genel Bakış

Bu bileşenin özelliklerini aşağıdaki bölümlere ayırdım:

  1. Düzenler
  2. Renk
  3. Özel aralık girişi
  4. Özel onay kutusu girişi
  5. Erişilebilirlikle ilgili dikkat edilmesi gereken noktalar
  6. JavaScript

Düzenler

Bu, tamamen CSS Grid kullanılan ilk GUI Challenge demosudur. Izgara için Chrome Geliştirici Araçları ile vurgulanan her bir ızgarayı aşağıda görebilirsiniz:

Ayarlar düzenini oluşturan tüm kutuları gösteren renkli ana hatlar ve boşluk aralığı yer paylaşımları

Just for gap

En yaygın düzen:

foo {
  display: grid;
  gap: var(--something);
}

Bu düzene "yalnızca boşluk için" diyorum çünkü yalnızca bloklar arasında boşluk eklemek için ızgara kullanıyor.

Bu stratejiyi kullanan beş düzen vardır. Bunların tümü aşağıda gösterilmiştir:

Ana hatlarla vurgulanan ve boşlukları doldurulan dikey ızgara düzenleri

Her giriş grubunu (.fieldset-item) içeren fieldset öğesi, öğeler arasında ince kenarlıklar oluşturmak için gap: 1px kullanıyor. Sınır sorunu yok.

Doldurulan boşluk
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Kenarlık hilesi
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

Doğal ızgara sarmalama

En karmaşık düzen, <main> ile <form> arasındaki mantıksal düzen sistemi olan makro düzen oldu.

Sarmalanan içeriği ortalama

Hem flexbox hem de grid, align-items veya align-content için özellikler sunar. Sarmalama öğeleriyle çalışırken content düzen hizalamaları, alanı alt öğeler arasında bir grup olarak dağıtır.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

Ana öğe, alt öğelerin hem bir hem de iki sütunlu düzenlerde dikey ve yatay olarak ortalanması için place-content: center hizalama kısayolunu kullanıyor.

Yukarıdaki videoda, kaydırma gerçekleşmesine rağmen "içeriğin" nasıl ortalanmış olarak kaldığını izleyin.

Otomatik sığdırma minmax'ini tekrarlama

<form>, her bölüm için uyarlanabilir bir tablo düzeni kullanır. Bu düzen, kullanılabilir alana göre bir veya iki sütun arasında geçiş yapar.

form {
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
  align-items: flex-start;
  max-width: 89vw;
}

Bu ızgarada, duyarlı düzene özel bir dokunuş katmak için row-gap (--space-xl) ve column-gap (--space-xxl) için farklı değerler kullanılıyor. Sütunlar üst üste geldiğinde büyük bir boşluk olmasını isteriz ancak bu boşluk, geniş ekrandaki kadar büyük olmamalıdır.

grid-template-columns özelliği 3 CSS işlevi kullanır: repeat(), minmax() ve min(). Una Kravets'in bu konuyla ilgili harika bir düzen blog yayını var. Bu yayında RAM olarak adlandırılıyor.

Una'nın düzeniyle karşılaştırırsanız bizim düzenimizde 3 özel ekleme vardır:

  • Ek bir min() işlevi iletiyoruz.
  • align-items: flex-start değerini belirtiriz.
  • max-width: 89vw tarzı var.

Evan Minto, blogundaki Intrinsically Responsive CSS Grid with minmax() and min() (minmax() ve min() ile Doğal Olarak Duyarlı CSS Izgarası) başlıklı yazısında ek min() işlevini ayrıntılı bir şekilde açıklıyor. Bu yazıyı okumanızı öneririm. flex-start hizalama düzeltmesi, varsayılan esnetme efektini kaldırır. Böylece bu düzenin alt öğelerinin eşit yüksekliklere sahip olması gerekmez, doğal ve içsel yüksekliklere sahip olabilirler. Bu YouTube videosunda, hizalama eklemesiyle ilgili kısa bir özet yer alıyor.

max-width: 89vw, bu yayında küçük bir döküme değer. Stil uygulanmış ve uygulanmamış düzeni göstereyim:

Neler oluyor? max-width belirtildiğinde, auto-fit düzen algoritmasının alana kaç tekrar sığdırabileceğini bilmesi için bağlam, açık boyutlandırma veya kesin boyutlandırma sağlar. Alan "tam genişlikte" gibi görünse de CSS ızgara spesifikasyonuna göre kesin bir boyut veya maksimum boyut sağlanmalıdır. Maksimum boyut belirttim.

Peki, neden 89vw? Çünkü düzenim için "işe yaradı". Chrome ekibinden birkaç kişiyle birlikte, 100vw gibi daha makul bir değerin neden yeterli olmadığını ve bunun aslında bir hata olup olmadığını araştırıyoruz.

Boşluk

Bu düzendeki uyumun büyük bir kısmı, sınırlı bir boşluk paletinden (tam olarak 7) kaynaklanır.

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

Bunların kullanımı; grid, CSS @nest ve @media'nın 5. seviye söz dizimi ile çok iyi uyum sağlar. Aşağıda, tamamen <main> düzen stili grubuna ait bir örnek verilmiştir.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);

  @media (width >= 540px) {
    & {
      padding: var(--space-lg);
    }
  }

  @media (width >= 800px) {
    & {
      padding: var(--space-xl);
    }
  }
}

Ortalanmış içeriğe sahip, varsayılan olarak orta düzeyde dolgulu bir tablo (mobil cihazlardaki gibi). Ancak görüntü alanı genişledikçe dolguyu artırarak yayılır. 2021 CSS is looking pretty good!

"Yalnızca boşluk için" adlı önceki düzeni hatırlıyor musunuz? Bu bileşende nasıl göründüklerinin daha eksiksiz bir versiyonunu burada bulabilirsiniz:

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

Renk

Renklerin kontrollü kullanımı, bu tasarımın hem etkileyici hem de minimal olmasını sağladı. Ben şöyle yapıyorum:

:root {
  --surface1: lch(10 0 0);
  --surface2: lch(15 0 0);
  --surface3: lch(20 0 0);
  --surface4: lch(25 0 0);

  --text1: lch(95 0 0);
  --text2: lch(75 0 0);
}

Yüzey ve metin renklerimi surface-dark ve surface-darker gibi adlar yerine sayılarla adlandırıyorum. Çünkü medya sorgusunda bunları ters çevireceğim ve açık ile koyu anlamlı olmayacak.

Bunları aşağıdaki gibi bir tercih medya sorgusunda çeviriyorum:

:root {
  ...

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --surface2: lch(100 0 0);
      --surface3: lch(98 0 0);
      --surface4: lch(85 0 0);

      --text1: lch(20 0 0);
      --text2: lch(40 0 0);
    }
  }
}

Renk söz dizimi ayrıntılarına girmeden önce genel resme ve stratejiye hızlıca göz atmak önemlidir. Ancak biraz acele ettiğim için biraz geriye dönelim.

LCH?

Renk teorisi konusuna çok fazla girmeden LCH, rengi matematikle (ör. 255) nasıl ölçtüğümüze değil, rengi nasıl algıladığımıza hitap eden insan odaklı bir söz dizimidir. Bu durum, insanların daha kolay yazabilmesi ve diğer insanların bu düzenlemelere uyum sağlayabilmesi açısından belirgin bir avantaj sağlar.

pod.link/csspodcast web sayfasının ekran görüntüsü, Color 2: Perception bölümü açık
CSS Podcast'te algısal renk (ve daha fazlası) hakkında bilgi edinin.

Bugün bu demoda, açık ve koyu mod için değiştirdiğim söz dizimine ve değerlere odaklanalım. 1 yüzey ve 1 metin rengini inceleyelim:

:root {
  --surface1: lch(10 0 0);
  --text1:    lch(95 0 0);

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --text1:    lch(40 0 0);
    }
  }
}

--surface1: lch(10 0 0), 10% açıklık, 0 kroma ve 0 renk tonuna karşılık gelir: çok koyu, renksiz bir gri. Ardından, açık mod için medya sorgusunda açıklık, 90% ile --surface1: lch(90 0 0); olarak değiştirilir. Stratejinin özü bu. İki tema arasında yalnızca açıklığı değiştirerek başlayın. Tasarımın gerektirdiği veya erişilebilirliği koruyabilecek kontrast oranlarını koruyun.

lch() ile ilgili avantaj, açıklığın insan odaklı olmasıdır. Bu nedenle, % oranında bir değişiklik yapıldığında, algısal ve tutarlı olarak % oranında farklı olacağını biliriz. Örneğin, hsl() o kadar güvenilir değildir.

İlgileniyorsanız renk uzayları ve lch() hakkında daha fazla bilgi edinebilirsiniz. Yakında geliyor.

CSS şu anda bu renklere hiçbir şekilde erişemez. Tekrar edelim: Modern monitörlerin çoğunda renklerin üçte birine erişimimiz yok. Bunlar sıradan renkler değil, ekranın gösterebileceği en canlı renklerdir. Monitör donanımı, CSS spesifikasyonlarından ve tarayıcı uygulamalarından daha hızlı geliştiği için web sitelerimiz soluk görünüyor.

Lea Verou

Renk şemasıyla uyarlanabilir form kontrolleri

Şu anda Safari ve Chromium gibi birçok tarayıcıda koyu tema kontrolleri bulunur ancak tasarımınızın bunları kullandığını CSS veya HTML'de belirtmeniz gerekir.

Yukarıda, DevTools'un Stiller panelinden özelliğin etkisi gösterilmektedir. Demoda HTML etiketi kullanılıyor. Bu, bence genellikle daha iyi bir konum:

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

Thomas Steiner'ın bu color-scheme makalesinde konuyla ilgili her şeyi öğrenebilirsiniz. Koyu renkli onay kutusu girişlerinden çok daha fazlasını elde edebilirsiniz.

CSS accent-color

Son zamanlarda form öğelerinde accent-color ile ilgili etkinlikler oldu. Bu, tarayıcıların giriş öğesinde kullanılan ton rengini değiştirebilen tek bir CSS stilidir. GitHub'da daha fazla bilgi edinebilirsiniz. Bu bileşen için stillerime ekledim. Tarayıcılar destekledikçe onay kutularım, pembe ve mor çarpıcı renklerle temaya daha uygun hale gelecek.

input[type="checkbox"] {
  accent-color: var(--brand);
}

Linux'ta Chromium'dan pembe onay kutularının ekran görüntüsü

Sabit renk geçişleri ve focus-within ile çarpıcı renkler

Renkler, az kullanıldığında daha çok dikkat çeker. Ben de bu etkiyi renkli kullanıcı arayüzü etkileşimleriyle yaratmayı seviyorum.

Yukarıdaki videoda, etkileşime kişilik kazandırmaya yardımcı olan birçok kullanıcı arayüzü geri bildirimi ve etkileşimi katmanı vardır:

  • Bağlam vurgulanıyor.
  • Değerin aralıkta "ne kadar dolu" olduğuna dair kullanıcı arayüzü geri bildirimi sağlama.
  • Bir alanın giriş kabul ettiğine dair kullanıcı arayüzü geri bildirimi sağlama

CSS, bir öğeyle etkileşim kurulduğunda geri bildirim sağlamak için çeşitli öğelerin görünümünü değiştirmek üzere :focus-within sözde sınıfını kullanır. .fieldset-item öğesini inceleyelim. Bu çok ilginç bir konu:

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

Bu öğenin alt öğelerinden birinde focus-within olduğunda:

  1. .fieldset-item arka planına daha yüksek kontrastlı bir yüzey rengi atanır.
  2. İç içe yerleştirilmiş svg, daha yüksek kontrast için beyaz renkle doldurulur.
  3. İç içe yerleştirilmiş <picture> clip-path tam bir daireye dönüşür ve arka plan parlak sabit geçişle doldurulur.

Özel aralık

Aşağıdaki HTML giriş öğesini kullanarak görünümünü nasıl özelleştirdiğimi göstereceğim:

<input type="range">

Bu öğenin özelleştirmemiz gereken 3 bölümü vardır:

  1. Aralık öğesi/kapsayıcısı
  2. İzleme
  3. Başparmak

Aralık öğesi stilleri

input[type="range"] {
  /* style setting variables */
  --track-height: .5ex;
  --track-fill: 0%;
  --thumb-size: 3ex;
  --thumb-offset: -1.25ex;
  --thumb-highlight-size: 0px;

  appearance: none;         /* clear styles, make way for mine */
  display: block;
  inline-size: 100%;        /* fill container */
  margin: 1ex 0;            /* ensure thumb isn't colliding with sibling content */
  background: transparent;  /* bg is in the track */
  outline-offset: 5px;      /* focus styles have space */
}

CSS'nin ilk birkaç satırı, stillerin özel kısımlarıdır. Bunları net bir şekilde etiketlemenin faydalı olacağını umuyorum. Geri kalan stiller, bileşenin zor kısımlarını oluşturmak için tutarlı bir temel sağlamak amacıyla çoğunlukla sıfırlama stilleridir.

Stilleri takip edin

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none; /* clear styles, make way for mine */
  block-size: var(--track-height);
  border-radius: 5ex;
  background:
    /* hard stop gradient:
        - half transparent (where colorful fill we be)
        - half dark track fill
        - 1st background image is on top
    */
    linear-gradient(
      to right,
      transparent var(--track-fill),
      var(--surface1) 0%
    ),
    /* colorful fill effect, behind track surface fill */
    var(--brand-bg-gradient) fixed;
}

Bunun püf noktası, canlı dolgu rengini "ortaya çıkarmaktır". Bu işlem, üstteki sert duraklı gradyanla yapılır. Gradyan, dolgu yüzdesine kadar şeffaftır ve sonrasında doldurulmamış parça yüzey rengini kullanır. Doldurulmamış yüzeyin arkasında, şeffaflıkla ortaya çıkmayı bekleyen tam genişlikte bir renk vardır.

İz dolgu stili

Tasarımım, dolgu stilini korumak için JavaScript gerektiriyor. Yalnızca CSS stratejileri de var ancak bunlar, kaydırma çubuğu öğesinin kaydırma çubuğuyla aynı yükseklikte olmasını gerektiriyor ve bu sınırlar içinde bir uyum bulamadım.

/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')

/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
  const max = slider.getAttribute('max') || 10;
  const percent = slider.value / max * 100;

  return `${parseInt(percent)}%`;
};

/* on page load, set the fill amount */
sliders.forEach(slider => {
  slider.style.setProperty('--track-fill', rangeToPercent(slider));

  /* when a slider changes, update the fill prop */
  slider.addEventListener('input', e => {
    e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
  })
})

Bence bu, görsel açıdan güzel bir yükseltme. Kaydırma çubuğu JavaScript olmadan da sorunsuz çalışır. --track-fill özelliği zorunlu değildir. Bu özellik yoksa dolgu stili olmaz. JavaScript kullanılabiliyorsa özel niteliği doldurun ve kullanıcı değişikliklerini de gözlemleyerek özel niteliği değerle senkronize edin.

CSS-Tricks'te Ana Tudor tarafından yazılan bu makalede, yalnızca CSS kullanılarak çubuk dolgusunun nasıl yapılacağı gösteriliyor. Ayrıca range öğesini de çok ilham verici buldum.

Küçük resim stilleri

input[type="range"]::-webkit-slider-thumb {
  appearance: none; /* clear styles, make way for mine */
  cursor: ew-resize; /* cursor style to support drag direction */
  border: 3px solid var(--surface3);
  block-size: var(--thumb-size);
  inline-size: var(--thumb-size);
  margin-top: var(--thumb-offset);
  border-radius: 50%;
  background: var(--brand-bg-gradient) fixed;
}

Bu stillerin çoğu güzel bir daire oluşturmak için kullanılır. Burada da küçük resimlerin, parçaların ve ilişkili SVG öğelerinin dinamik renklerini birleştiren sabit arka plan gradyanını görüyorsunuz. Fareyle üzerine gelindiğinde vurgulama için kullanılan box-shadow tekniğini ayırmak amacıyla etkileşim stillerini ayırdım:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

::-webkit-slider-thumb {
  …

  /* shadow spread is initally 0 */
  box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);

  /* if motion is OK, transition the box-shadow change */
  @media (--motionOK) {
    & {
      transition: box-shadow .1s ease;
    }
  }

  /* on hover/active state of parent, increase size prop */
  @nest input[type="range"]:is(:hover,:active) & {
    --thumb-highlight-size: 10px;
  }
}

Hedef, kullanıcı geri bildirimleri için yönetimi kolay ve animasyonlu bir görsel vurgu oluşturmaktı. Kutu gölgesi kullanarak efektle düzen tetiklemeyi önleyebilirim. Bunu, bulanık olmayan ve kaydırma düğmesi öğesinin dairesel şekline uyan bir gölge oluşturarak yapıyorum. Ardından, fareyle üzerine gelindiğinde yayılma boyutunu değiştirip geçiş efekti ekliyorum.

Keşke onay kutularında da vurgu efekti bu kadar kolay olsaydı…

Tarayıcılar arası seçiciler

Tarayıcılar arası tutarlılık sağlamak için bu -webkit- ve -moz- seçicilere ihtiyacım olduğunu fark ettim:

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

Özel onay kutusu

Aşağıdaki HTML giriş öğesini kullanarak görünümünü nasıl özelleştirdiğimi göstereceğim:

<input type="checkbox">

Bu öğenin özelleştirmemiz gereken 3 bölümü vardır:

  1. Onay kutusu öğesi
  2. İlişkili etiketler
  3. Vurgulama efekti

Onay kutusu öğesi

input[type="checkbox"] {
  inline-size: var(--space-sm);   /* increase width */
  block-size: var(--space-sm);    /* increase height */
  outline-offset: 5px;            /* focus style enhancement */
  accent-color: var(--brand);     /* tint the input */
  position: relative;             /* prepare for an absolute pseudo element */
  transform-style: preserve-3d;   /* create a 3d z-space stacking context */
  margin: 0;
  cursor: pointer;
}

transform-style ve position stilleri, vurguyu biçimlendirmek için daha sonra tanıtacağımız sözde öğeye hazırlanır. Aksi takdirde, çoğunlukla benim kişisel görüşlerimi yansıtan küçük stil değişiklikleri yapıyorum. İmlecin işaretçi olmasını seviyorum, ana hat ofsetlerini seviyorum, varsayılan onay kutuları çok küçük ve accent-color destekleniyorsa bu onay kutularını marka renk şemasına getirin.

Onay kutusu etiketleri

Onay kutuları için etiket sağlamak iki nedenden dolayı önemlidir. İlki, onay kutusu değerinin ne için kullanıldığını belirtmek, yani "ne için açık veya kapalı?" sorusunu yanıtlamaktır. İkincisi ise kullanıcı deneyimiyle ilgilidir. Web kullanıcıları, onay kutularıyla ilişkili etiketler aracılığıyla etkileşim kurmaya alışmıştır.

giriş
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
etiket
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

Etiketinize, kimliğe göre bir onay kutusunu işaret eden bir for özelliği ekleyin: <label for="text-notifications">. Onay kutunuzda, fare veya ekran okuyucu gibi farklı araç ve teknolojilerle bulunabilmesi için hem adı hem de kimliği iki katına çıkarın: <input type="checkbox" id="text-notifications" name="text-notifications">. :hover, :active ve daha fazlası bağlantıyla birlikte ücretsiz olarak sunulur ve formunuzla etkileşim kurma yollarını artırır.

Onay kutusu vurgulama

Arayüzlerimin tutarlı olmasını istiyorum. Kaydırma çubuğu öğesinde, onay kutusuyla birlikte kullanmak istediğim güzel bir küçük resim vurgusu var. Küçük resim, gölgeyi büyütüp küçültmek için box-shadow ve spread özelliğini kullanabildi. Ancak bu efekt burada çalışmaz çünkü onay kutularımız kare şeklindedir ve kare şeklinde olmalıdır.

Aynı görsel efekti bir sözde öğe ve çok sayıda karmaşık CSS ile elde edebildim:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

input[type="checkbox"]::before {
  --thumb-scale: .01;                        /* initial scale of highlight */
  --thumb-highlight-size: var(--space-xl);

  content: "";
  inline-size: var(--thumb-highlight-size);
  block-size: var(--thumb-highlight-size);
  clip-path: circle(50%);                     /* circle shape */
  position: absolute;                         /* this is why position relative on parent */
  top: 50%;                                   /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
  left: 50%;
  background: var(--thumb-highlight-color);
  transform-origin: center center;            /* goal is a centered scaling circle */
  transform:                                  /* order here matters!! */
    translateX(-50%)                          /* counter balances left: 50% */
    translateY(-50%)                          /* counter balances top: 50% */
    translateZ(-1px)                          /* PUTS IT BEHIND THE CHECKBOX */
    scale(var(--thumb-scale))                 /* value we toggle for animation */
  ;
  will-change: transform;

  @media (--motionOK) {                       /* transition only if motion is OK */
    & {
      transition: transform .2s ease;
    }
  }
}

/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
  --thumb-scale: 1;
}

Daire şeklinde bir sözde öğe oluşturmak kolay bir iş olsa da bu öğeyi bağlı olduğu öğenin arkasına yerleştirmek daha zordu. Düzeltmeden önceki ve sonraki hâli:

Bu kesinlikle bir mikro etkileşim ancak görsel tutarlılığı korumak benim için önemli. Animasyon ölçeklendirme tekniği, diğer yerlerde kullandığımız teknikle aynıdır. Özel bir özelliği yeni bir değere ayarladık ve CSS'nin bu özelliği hareket tercihlerine göre geçirmesine izin verdik. Buradaki temel özellik translateZ(-1px). Üst öğe 3D bir alan oluşturdu ve bu sözde öğe alt öğesi, kendisini z-uzayında biraz geriye yerleştirerek bu alandan yararlandı.

Erişilebilirlik

YouTube videosunda, bu ayar bileşeni için fare, klavye ve ekran okuyucu etkileşimleri çok iyi bir şekilde gösteriliyor. Burada bazı ayrıntılara değineceğim.

HTML öğesi seçenekleri

<form>
<header>
<fieldset>
<picture>
<label>
<input>

Bunların her biri, kullanıcının tarama aracıyla ilgili ipuçları ve püf noktaları içerir. Bazı öğeler etkileşim ipuçları sağlar, bazıları etkileşimi bağlar ve bazıları da ekran okuyucunun gezindiği erişilebilirlik ağacını şekillendirmeye yardımcı olur.

HTML özellikleri

Ekran okuyucular için gerekli olmayan öğeleri gizleyebiliriz. Bu örnekte, kaydırma çubuğunun yanındaki simgeyi gizleyebiliriz:

<picture aria-hidden="true">

Yukarıdaki videoda, Mac OS'te ekran okuyucu akışı gösterilmektedir. Giriş odağının bir kaydırma çubuğundan diğerine nasıl doğrudan geçtiğine dikkat edin. Bunun nedeni, bir sonraki kaydırıcıya giden yolda bir durak olabilecek simgeyi gizlemiş olmamızdır. Bu özellik olmadan, kullanıcının durması, dinlemesi ve göremediği resmi geçmesi gerekir.

SVG bir dizi matematiksel işlemden oluşur. Fareyle üzerine gelindiğinde gösterilecek bir başlık ve matematiksel işlemlerin ne oluşturduğuna dair okunabilir bir yorum için <title> öğesi ekleyelim:

<svg viewBox="0 0 24 24">
  <title>A note icon</title>
  <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>

Bunun dışında, formun fare, klavye, video oyunu kumandaları ve ekran okuyucularda gerçekten iyi test edilmesi için yeterince açıkça işaretlenmiş HTML kullandık.

JavaScript

Çubuk dolgu renginin JavaScript'ten nasıl yönetildiğini daha önce ele almıştık. Şimdi <form> ile ilgili JavaScript'e bakalım:

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

Formla her etkileşimde bulunulduğunda ve form değiştirildiğinde, konsol formu bir nesne olarak tabloya kaydeder. Böylece, sunucuya gönderilmeden önce kolayca incelenebilir.

Form verilerinin bir tabloda gösterildiği console.table() sonuçlarının ekran görüntüsü

Sonuç

Benim nasıl yaptığımı öğrendiniz. Peki siz nasıl yapardınız? Bu da eğlenceli bir bileşen mimarisi oluşturur. En sevdiği çerçevede yuvalar içeren ilk sürümü kim yapacak? 🙂

Yaklaşımlarımızı çeşitlendirelim ve web'de geliştirme yapmanın tüm yollarını öğrenelim. Bir demo oluşturun, bağlantıları bana tweetleyin. Ben de bunları aşağıdaki Topluluk remiksleri bölümüne ekleyeyim.

Topluluk remiksleri

  • Onay kutusu etiketlerinin fareyle üzerine gelme alanıyla ilgili stili için @tomayac'a teşekkürler. Bu sürümde öğeler arasında fareyle üzerine gelme boşluğu yoktur: demo ve kaynak.