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

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

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

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

Genel Bakış

FAB'lar mobil cihazlarda masaüstünden daha yaygındır ancak her iki senaryoda da yaygındır. Birincil eylemlerin görünümde kalmasını sağlarlar, böylece oldukça kullanışlı ve her yerde olurlar. Bu kullanıcı deneyimi stili, Material UI tarafından ünlendi. Kullanım ve yerleşim önerilerini burada bulabilirsiniz.

Öğeler ve stiller

Bu kontrollerin HTML'si bir kapsayıcı öğesi ve bir veya daha fazla düğme grubu içerir. Kapsayıcı, FAB'ları görüntü alanında konumlandırır ve düğmeler arasındaki boşluğu yönetir. Düğmeler mini veya varsayılan olabilir ve birincil ve ikincil işlemler arasında hoş bir çeşitlilik sunar.

FAB kapsayıcısı

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

FAB işaretlemesi

CSS'nin stile bağlanabilmesi için bir .fabs sınıfıyla başlayın. Ardından, yalnızca genel bir kapsayıcı değil, aynı zamanda adlandırılmış ve amaca yönelik olması için role="group" ve aria-label öğelerini ekleyin.

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

FAB stili

FAB'ların kullanışlı olması için her zaman görüntü alanında kalmalıdır. Bu, fixed konumu için mükemmel bir kullanım alanıdır. Bu görüntü alanı konumunda, konumun kullanıcının belge moduna (ör. sağdan sola veya soldan sağa) uygun olması için inset-block ve inset-inline kullanmayı tercih ettim. Özel mülkler, tekrarı önlemek ve görüntü 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 flex ekranı veriyorum ve düzen yönünü column-reverse olarak değiştiriyorum. Bu işlem, alt öğeleri birbirinin üzerine yığarak (sütun) görsel sıralarını da tersine çevirir. Bu, ilk odaklanabilir öğenin üst öğe yerine alt öğe olmasını sağlar. HTML dokümanı başına odağın normalde gittiği yer üst öğedir. Görsel sırayı tersine çevirmek, görme engelli kullanıcılar ile klavye kullanıcıları için deneyimi birleştirir. Birincil işlemin stili, mini düğmelerden daha büyük olduğu için görme engelli kullanıcılara bunun birincil bir işlem olduğunu gösterir ve klavye kullanıcıları, kaynaktaki ilk öğe olarak bu işleme odaklanır.

DevTools&#39;un, ızgara düzenlerinin üzerine yerleştirildiği iki fab düğmesi gösterilmektedir. Aralarındaki boşluğu şeritli bir desenle gösterir ve ayrıca hesaplanmış yüksekliklerini ve genişliklerini gösterir.

.fabs {
  

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

Ortalama place-items ile gerçekleştirilir ve gap kapsayıcıya yerleştirilmiş tüm FAB düğmeleri arasına boşluk ekler.

FAB düğmeleri

Bazı düğmelere, her şeyin üzerinde yüzüyormuş gibi görünecek şekilde stil uygulama zamanı.

Varsayılan FAB

Stil eklemek için ilk düğme varsayılan düğmedir. Bu, tüm FAB düğmelerinin temeli olacaktı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 bir fare, dokunmatik ekran ve klavye kullanıcı deneyimi sunması nedeniyle bu sürümden başlayacağız. Bu işaretlemenin en önemli özelliği, simgeyi aria-hidden="true" ekran okuyucu kullanıcılarından gizlemek ve gerekli etiket metnini <button> işaretlemesinin kendisine eklemektir. Bu durumlarda etiket eklerken, fare kullanıcılarının simgenin ne iletmeyi beklediği hakkında bilgi alabilmeleri için bir title eklemeyi de seviyorum.

<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 ayırt edici özellikleri olduğu için güçlü bir gölgeye sahip dolgulu bir yuvarlak 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);
}

Sonra renk ekleyelim. Daha önce GUI Challenges'da kullandığımız bir stratejiyi kullanacağız. Açık ve koyu renkleri statik olarak tutan, açıkça adlandırılmış bir özel özellik grubu oluşturun. Ardından, kullanıcının renklerle ilgili sistem tercihine bağlı olarak açık veya koyu değişkenlerine 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üğmenin dokunma vurgusunu kaldırın:

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

Mini FAB

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

Mini FAB işaretleme

HTML, FAB ile aynıdır ancak CSS'ye varyantta bağlantı noktası vermek için ".mini" sınıfı 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 mülkler sayesinde, tek gereken değişiklik --_size değişkeninde yapılan bir ayarlamadır.

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

Üstteki düğme alttaki düğmeden daha küçük olmak üzere üst üste yığılmış iki FAB düğmesinin ekran görüntüsü.

Erişilebilirlik

FAB'larla erişilebilirlik açısından unutulmaması gereken en önemli bölüm, sayfanın klavye akışı içinde yerleşimdir. Bu demoda yalnızca FAB bulunur. Klavye sırası ve akışı açısından rekabet edilecek bir şey olmadığından demo'nun anlamlı bir klavye akışı gösterme fırsatı yoktur. Odak için rekabet eden öğelerin bulunduğu bir senaryoda, kullanıcının FAB düğmesi akışına hangi noktada gireceği hakkında derinlemesine düşünmenizi öneririm.

Klavye etkileşimi gösterimi

Kullanıcı FAB kapsayıcısına odaklandığında, ekran okuyucu kullanıcılarını odaklandıkları öğelerin içerikleri hakkında bilgilendiren role="group" ve aria-label="floating action buttons" öğelerini ekledik. Kullanıcıların önce birincil işlemi bulabilmesi için varsayılan FAB'yi stratejik olarak ilk sıraya yerleştirdim. Daha sonra, kolay erişim için alttaki birincil düğmeyi kullanıcının parmaklarına yakın bir yerde, görsel olarak sıralamak için flex-direction: column-reverse; kullanıyorum. Varsayılan düğme görsel olarak belirgin olduğu ve klavye kullanıcıları için ilk sırada yer aldığı için bu, kullanıcılara çok benzer deneyimler sunan güzel bir avantajdır.

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

Animasyon

Kullanıcı deneyimini iyileştirmek için çeşitli animasyon türleri eklenebilir. Diğer GUI yarışmalarında olduğu gibi, azaltılmış hareket deneyimi ve tam hareket deneyimi amacıyla birkaç özel özellik oluşturacağız. Varsayılan olarak stiller, kullanıcının hareketin azaltılmasını istediğini varsayar ve ardından prefers-reduced-motion medya sorgusunu kullanarak geçiş değerini tam hareketle değiştirir.

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

Şu CSS'de üç özel özellik oluşturulur: --_motion-reduced, --_motion-ok ve --_transition. İlk ikisi, kullanıcının tercihine göre uygun geçişleri içerir ve son değişken --_transition 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ıdakiler uygulandığında box-shadow, background-color, transform ve outline-offset'te değişiklikler yapılabilir. Bu sayede kullanıcıya, etkileşiminin alındığına dair güzel bir kullanıcı arayüzü geri bildirimi sunulur.

Ardından, translateY değerini biraz ayarlayarak :active durumuna biraz daha stilde ekleyin. Bu, düğmeye güzel bir basılı efekt verir:

.fab {
  

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

Son olarak, düğmelerdeki SVG simgelerinde değişiklik yapın:

.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 ne yapardınız? 🙂

Yaklaşımlarımızı çeşitlendirelim ve web'de uygulama 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

Henüz gösterilecek bir şey yok.

Kaynaklar