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.
.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;
}
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.
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
- Github'daki kaynak kod