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

Renk uyumlu, 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ın olarak kullanılır. Birincil işlemleri görünür halde tutarak bunları kullanışlı ve her yerde bulunabilir hale getirirler. 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. Bu sayede birincil ve ikincil işlemler arasında hoş bir çeşitlilik elde edebilirsiniz.

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şaretleme

CSS'nin stil için bağlanacağı bir .fabs sınıfıyla başlayın, ardından role="group" ve aria-label ekleyin. Böylece kapsayıcı yalnızca genel bir kapsayıcı değil, adlandırılmış ve amaca yönelik bir kapsayıcı olur.

<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ı ekranına flex adını verip 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. Bunun nedeni, birincil işlemin stilinin küçük düğmelerden daha büyük olmasıdır. Bu durum, görme engelli kullanıcılara birincil işlemin ne olduğunu gösterir ve klavye kullanıcıları da 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 çizgili 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 işlemi 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üğmelere, her şeyin üzerinde yüzüyormuş gibi görünecek şekilde stil uygulama zamanı.

Varsayılan FAB

Stil verilecek 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şaretleme

<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 yönü, simgeyi aria-hidden="true" ile ekran okuyucu kullanıcılarından gizlemek ve gerekli etiket metnini <button> işaretlemesine eklemektir. Bu tür durumlarda etiket eklerken fare kullanıcılarının simgenin neyi anlatmak istediği hakkında bilgi alabilmesi için title simgesini de eklemeyi 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);
}

Ardından 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. FAB'lardan bazılarını varsayılan işlemden daha küçük yaparak kullanıcının en sık gerçekleştirdiği işlemi tanıtabiliriz.

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'ların erişilebilirliği için en önemli nokta, sayfanın klavye akışında yerleştirilmesidir. Bu demoda yalnızca FAB'lar vardır. Klavye sırası ve akışı açısından karşılaştırılacak bir şey yoktur. Yani 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. Ardından, birincil düğmeyi kolayca erişilebilmesi için kullanıcının parmaklarına yakın bir yerde, alt tarafta görsel olarak sıralamak üzere flex-direction: column-reverse; simgesini kullanırım. 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

Aşağıdaki CSS'de üç özel mülk 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. Böylece 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 yaptığınız değişiklikleri de taşıyı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