Kayan işlem düğmesi (FAB) bileşeni oluşturma

Renk uyarlamalı, duyarlı ve erişilebilir FAB bileşenlerinin nasıl oluşturulacağına dair temel bir genel bakış.

Bu yayında, renge uyarlanabilir, duyarlı ve erişilebilir FAB bileşenleri oluşturma konusundaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin ve kaynağı görüntüleyin.

Video tercih ediyorsanız bu yayının YouTube versiyonunu aşağıda bulabilirsiniz:

Genel Bakış

FAB'ler masaüstüne kıyasla mobil cihazlarda daha yaygındır ancak her iki senaryoda da sıklıkla kullanılır. Birincil işlemleri görünür tutarak bunları kullanışlı ve her yerde kullanılabilir hale getirirler. Bu kullanıcı deneyimi stili, Material UI ile popüler hale geldi. Kullanım ve yerleştirme önerilerini burada bulabilirsiniz.

Öğeler ve stiller

Bu kontrollerin HTML'si bir kapsayıcı öğe ve bir veya daha fazla düğme kümesi içerir. Kapsayıcı, KFE'leri görüntü alanına yerleştirir ve düğmeler arasındaki boşluğu yönetir. Düğmeler mini veya varsayılan olabilir. Bu sayede birincil ve ikincil işlemler arasında güzel bir çeşitlilik sağlanır.

FAB kapsayıcısı

Bu öğe normal bir <div> olabilir ancak görme engelli kullanıcılarımıza yardımcı olmak için bu kapsayıcının amacını ve içeriğini açıklayan bazı faydalı özelliklerle etiketleyelim.

FAB işaretlemesi

Stil için CSS'ye bağlanmak üzere .fabs sınıfıyla başlayın, ardından role="group" ve aria-label ekleyin. Böylece, yalnızca genel bir kapsayıcı değil, adlandırılmış ve amaçlı bir kapsayıcı olur.

<div class="fabs" role="group" aria-label="Floating action buttons">
  <!-- buttons will go here -->
</div>

FAB'lerin stili

FAB'lerin kullanışlı olması için her zaman görüntü alanında kalması gerekir. Bu, konum için harika bir kullanım alanıdır fixed. Bu görünüm alanı konumunda, inset-block ve inset-inline kullanmayı tercih ettim. Böylece konum, kullanıcının belge modunu (ör. sağdan sola veya soldan sağa) tamamlayacak. Özel özellikler, tekrarı önlemek ve görünüm alanının alt ve yan kenarlarından eşit mesafede olmasını sağlamak için de kullanılır:

.fabs {
  --_viewport-margin: 2.5vmin;

  position: fixed;
  z-index: var(--layer-1);

  inset-block: auto var(--_viewport-margin);
  inset-inline: auto var(--_viewport-margin);
}

Ardından, kapsayıcıya ekranı veriyorum flex ve düzen yönünü column-reverse olarak değiştiriyorum. Bu işlem, çocukları üst üste (sütun) yerleştirir ve görsel sıralarını tersine çevirir. Bu, odaklanılabilir ilk öğeyi en üstteki yerine en alttaki öğe yapar. Normalde HTML dokümanına göre odak en üstteki öğeye gider. Görsel sıranın tersine çevrilmesi, görme engelli kullanıcılar ve klavye kullanıcıları için deneyimi birleştirir. Birincil işlemin mini düğmelerden daha büyük olarak şekillendirilmesi, görme engelli kullanıcılara bunun birincil işlem olduğunu gösterir. Klavye kullanıcıları ise bunu kaynakta ilk öğe olarak odaklar.

Izgara düzenlerinin üzerinde DevTools&#39;un yer aldığı iki kayan işlem düğmesi gösteriliyor. Aradaki boşluğu çizgili bir desenle gösterir. Ayrıca, hesaplanan yükseklik ve genişliklerini de gösterir.

.fabs {
  

  display: flex;
  flex-direction: column-reverse;
  place-items: center;
  gap: var(--_viewport-margin);
}

Ortalama place-items ile yapılır ve gap, kapsayıcıya yerleştirilen tüm FAB düğmeleri arasına boşluk ekler.

FAB düğmeleri

Bazı düğmeleri her şeyin üzerinde kayıyormuş gibi görünecek şekilde stilize etme zamanı.

Varsayılan FAB

Stil verilecek ilk düğme varsayılan düğmedir. Bu, tüm FAB düğmelerinin temeli olarak kullanılır. Daha sonra, bu temel stillerde mümkün olduğunca az değişiklik yaparak alternatif bir görünüm elde eden bir varyant oluşturacağız.

FAB işaretlemesi

<button> öğesi doğru seçimdir. Mükemmel fare, dokunma ve klavye kullanıcı deneyimi sunduğu için temel olarak bu sürümle başlayacağız. Bu işaretlemenin en önemli yönü, simgeyi aria-hidden="true" ile ekran okuyucu kullanıcılarından gizlemek ve gerekli etiket metnini <button> işaretlemesine eklemektir. Bu durumlarda etiket eklerken fare kullanıcılarının simgenin ne anlatmak istediği hakkında bilgi alabilmesi için title simgesini de eklemeyi tercih ediyorum.

<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>

FAB stili

Öncelikle düğmeyi, düğmenin ilk belirleyici özellikleri olan güçlü bir gölgeye sahip dolgulu yuvarlak bir düğmeye dönüştürelim:

.fab {
  --_size: 2rem;

  padding: calc(var(--_size) / 2);
  border-radius: var(--radius-round);
  aspect-ratio: 1;
  box-shadow: var(--shadow-4);
}

Şimdi renk ekleyelim. Daha önce GUI Challenges'da kullandığımız bir stratejiyi kullanacağız. Açık ve koyu renkleri statik olarak tutan, net bir şekilde adlandırılmış bir özel özellikler grubu oluşturun. Ardından, kullanıcının renklerle ilgili sistem tercihine bağlı olarak açık veya koyu değişkenlere ayarlanacak uyarlanabilir bir özel özellik oluşturun:

.fab {
  

  /* light button and button hover */
  --_light-bg: var(--pink-6);
  --_light-bg-hover: var(--pink-7);

  /* dark button and button hover */
  --_dark-bg: var(--pink-4);
  --_dark-bg-hover: var(--pink-3);

  /* adaptive variables set to light by default */
  --_bg: var(--_light-bg);

  /* static icon colors set to the adaptive foreground variable */
  --_light-fg: white;
  --_dark-fg: black;
  --_fg: var(--_light-fg);

  /* use the adaptive properties on some styles */
  background: var(--_bg);
  color: var(--_fg);

  &:is(:active, :hover, :focus-visible) {
    --_bg: var(--_light-bg-hover);

    @media (prefers-color-scheme: dark) {
      --_bg: var(--_dark-bg-hover);
    }
  }

  /* if users prefers dark, set adaptive props to dark */
  @media (prefers-color-scheme: dark) {
    --_bg: var(--_dark-bg);
    --_fg: var(--_dark-fg);
  }
}

Ardından, SVG simgelerinin alana sığmasına yardımcı olacak bazı stiller ekleyin.

.fab {
  

  & > svg {
    inline-size: var(--_size);
    block-size: var(--_size);
    stroke-width: 3px;
  }
}

Son olarak, etkileşim için kendi görsel geri bildirimimizi eklediğimizden düğmedeki dokunma vurgusunu kaldırın:

.fab {
  -webkit-tap-highlight-color: transparent;
}

Mini FAB

Bu bölümün amacı, kayan işlem düğmesi için bir varyant oluşturmaktır. Bazı kayan işlem düğmelerini varsayılan işlemden daha küçük yaparak kullanıcının en sık gerçekleştirdiği işlemi öne çıkarabiliriz.

Mini FAB işaretlemesi

HTML, FAB ile aynıdır ancak CSS'ye varyant için bir kanca vermek üzere ".mini" sınıfını ekleriz.

<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Mini FAB stili

Özel özelliklerin kullanımı sayesinde, gereken tek değişiklik --_size değişkeninde yapılacak bir ayarlamadır.

.fab.mini {
  --_size: 1.25rem;
}

İki fab düğmesinin üst üste yerleştirildiği ve üstteki düğmenin alttaki düğmeden daha küçük olduğu bir ekran görüntüsü.

Erişilebilirlik

FAB'lerle erişilebilirlik için hatırlanması gereken en önemli nokta, sayfanın klavye akışındaki yerleşimdir. Bu demoda yalnızca FAB'ler var. Klavye sırası ve akışı açısından rekabet edilecek bir şey yok. Bu nedenle, anlamlı bir klavye akışı gösterilemiyor. Odaklanma için rekabet eden öğelerin olduğu bir senaryoda, kullanıcının bu akışta hangi noktada FAB düğmesi akışına girmesi gerektiğini derinlemesine düşünmenizi öneririm.

Klavye etkileşimi gösterimi

Kullanıcı odaklanma işlemini FAB kapsayıcısında tamamladığında, ekran okuyucu kullanıcıları odaklandıkları içerik hakkında bilgilendiren role="group" ve aria-label="floating action buttons" öğelerini eklemiş oluruz. Kullanıcıların birincil işlemi ilk olarak bulması için varsayılan FAB'ı stratejik olarak ilk sıraya yerleştirdim. Ardından, kolay erişim için birincil düğmeyi kullanıcının parmaklarına yakın olacak şekilde alt kısma görsel olarak yerleştirmek üzere flex-direction: column-reverse; kullanıyorum. Varsayılan düğme görsel olarak belirgin olduğu ve klavye kullanıcıları için de ilk seçenek olduğu için bu güzel bir kazanımdır. Böylece, klavye kullanıcıları da çok benzer deneyimler yaşayabilir.

Son olarak, simgelerinizi ekran okuyucu kullanıcılarından gizlemeyi ve düğme için bir etiket sağlamayı unutmayın. Bu işlem, <svg> üzerindeki aria-hidden="true" ve <button> üzerindeki aria-label="Some action" ile HTML'de zaten yapılmıştır.

Animasyon

Kullanıcı deneyimini iyileştirmek için çeşitli animasyon türleri eklenebilir. Diğer GUI Challenges'da olduğu gibi, azaltılmış hareket deneyimi ve tam hareket deneyimi amacını tutmak için birkaç özel özellik ayarlayacağız. Stiller, varsayılan olarak kullanıcının hareketi azaltmak istediğini varsayar. Ardından, prefers-reduced-motion medya sorgusu kullanılarak geçiş değeri tam hareketle değiştirilir.

Özel özelliklere sahip azaltılmış hareket stratejisi

Aşağıdaki CSS'de üç özel özellik oluşturulur: --_motion-reduced, --_motion-ok ve --_transition. İlk iki değişken, kullanıcının tercihine göre uygun geçişleri içerir. Son değişken --_transition ise sırasıyla --_motion-reduced veya --_motion-ok olarak ayarlanır.

.fab {
  /* box-shadow and background-color can safely be transitioned for reduced motion users */
  --_motion-reduced:
    box-shadow .2s var(--ease-3),
    background-color .3s var(--ease-3);

  /* add transform and outline-offset for users ok with motion */
  --_motion-ok:
    var(--_motion-reduced),
    transform .2s var(--ease-3),
    outline-offset 145ms var(--ease-2);

  /* default the transition styles to reduced motion */
  --_transition: var(--_motion-reduced);

  /* set the transition to our adaptive transition custom property*/
  transition: var(--_transition);

  /* if motion is ok, update the adaptive prop to the respective transition prop */
  @media (prefers-reduced-motion: no-preference) {
    --_transition: var(--_motion-ok);
  }
}

Yukarıdaki koşullar sağlandığında box-shadow, background-color, transform ve outline-offset ile ilgili değişiklikler aktarılabilir. Böylece kullanıcıya, etkileşiminin alındığına dair güzel bir kullanıcı arayüzü geri bildirimi verilir.

Ardından, :active durumuna biraz daha stil eklemek için küçük bir ayarlama yapın. translateYBu işlem, düğmeye güzel bir basılmış efekt verir:

.fab {
  

  &:active {
    @media (prefers-reduced-motion: no-preference) {
      transform: translateY(2%);
    }
  }
}

Son olarak, düğmelerdeki SVG simgelerinde yapılan değişiklikleri geçirin:

.fab {
  

  &[data-icon="plus"]:hover > svg {
    transform: rotateZ(.25turn);
  }

  & > svg {
    @media (prefers-reduced-motion: no-preference) {
      will-change: transform;
      transition: transform .5s var(--ease-squish-3);
    }
  }
}

Sonuç

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

Yaklaşımlarımızı çeşitlendirelim ve web'de içerik oluşturmanın tüm yollarını öğrenelim.

Bir demo oluşturun, bağlantıları bana tweet atın. Ben de bu bağlantıları aşağıdaki topluluk remiksleri bölümüne ekleyeyim.

Topluluk remiksleri

Henüz burada gösterilecek bir şey yok.

Kaynaklar