Yalnızca CSS Erişilebilir Açılır Gezinme Menüsü

Bu teknik şunları kullanarak araştırır:

  • CSS ile Animasyon transition ve transform
  • Kullanmak :focus-within sözde sınıf
  • Konumlandırma için CSS ızgarası
  • dinamik merkezleme tekniği
  • Açılır menüler için erişilebilirlik konuları

“Vurgu niyeti” kavramıyla uğraşırken saçınızı çektiyseniz, o zaman bu yükseltme tam size göre!

Çok ileri gitmeden önce, tekniğimiz %100 yalnızca CSS kullanırken, daha kapsamlı erişilebilir bir deneyim için biraz Javascript eklemeye ihtiyaç var. Ayrıca bir çoklu dolgu bu işi yapmak için önemli bir özellik için gerekli – :focus-withinen güvenilir destek için. Ancak, görsel efektleri gerçekleştirmek için bir veya daha fazla jQuery eklentisine ihtiyaç duyduğumuz günlerden bu yana hala büyük ölçüde geliştik.

Erişilebilirlik güncellemesi – 18/08/20: Çok teşekkürler Michael Fairchild Deque (ve mükemmel kaynağın yaratıcısı) a11ysupport.io) orijinal çözümü çeşitli yardımcı teknolojilerde test etmek için. Yalnızca CSS yöntemi, WCAG 2.1’i tam olarak karşılamak için biraz Javascript’e ihtiyaç duyar. Özellikle, karşılamak için menüyü kapatmak için fare olmayan/sekme olmayan bir yol sunmak için javascript kullanılmalıdır (escape tuşunu düşünün) başarı kriterleri 1.4.13. Michael işaret etti bu WAI-ARIA Yazma Uygulamaları demosu gerekli Javascript özellikleri hakkında daha fazla bilgi sağlar. Bunlar, nihai üretim çözümünüz için şiddetle tavsiye edilen ilavelerdir.


Sass kullanmadıysanız, anlamak için beş dakikanızı ayırabilirsiniz. Sass’ın yuvalama sözdizimi verilen kod örneklerini en kolay şekilde anlamak için.

Devam ettikçe bunu geliştireceğiz, ancak işte başlangıç ​​yapımız:

<nav aria-label="Main Navigation">
<ul>
<li><a href="#">About</a></li>
<li class="dropdown">
<button
type="button"
class="dropdown__title"
aria-expanded="false"
aria-controls="sweets-dropdown"
>

Sweets
</button>
<ul class="dropdown__menu" id="sweets-dropdown">
<li><a href="#">Donuts</a></li>
<li><a href="#">Cupcakes</a></li>
<li><a href="#">Chocolate</a></li>
<li><a href="#">Bonbons</a></li>
</ul>
</li>
<li><a href="#">Order</a></li>
</ul>
</nav>

Bakan button bir dakika için, bu, gezinme bağlantıları için anlamsal standarttır. Bu yapı, sayfanızın herhangi bir yerinde yaşamak için esnektir, bu nedenle ana gezinme olduğu kadar kolayca kenar çubuğunuzdaki bir içindekiler tablosu olabilir.

Kapının hemen dışında, özellikle erişilebilirlik için birkaç özellik uyguladık:

  1. aria-label üzerinde <nav> Bir sayfada önemli noktalara göre gezinmek için yardımcı teknoloji kullanıldığında amacının belirlenmesine yardımcı olmak için
  2. kullanımı button açılır listenin açılmasını tetiklemek için odaklanabilir, keşfedilebilir bir öğe olarak
  3. aria-controls üzerinde .dropdown__title kimliğine bağlanan .dropdown__menu yardımcı teknoloji menüsüyle ilişkilendirmek için
  4. aria-expanded üzerinde button Bu makalenin başında belirtilen demoda belirtildiği gibi nihai çözümünüzde Javascript aracılığıyla değiştirilmesi gereken

Michael tarafından belirtildiği gibi, bir button öğe ayrıca Dragon Naturally Speaking kullanıcılarının menüyü açmak için ‘tıkla düğmesi’ gibi bir şey söylemesine izin verir.

(Çoğunlukla) varsayılan başlangıç ​​görünümümüz aşağıdaki gibidir:

varsayılan bağlantı listesi

İlk Gezinme Stilleri

İlk olarak, bazı konteyner stilleri vereceğiz. nav ve bir ızgara kapsayıcı olarak tanımlayın. Ardından, varsayılan liste stillerini nav ul ve nav ul li.

nav {
background-color: #eee;
padding: 0 1rem;
display: grid;
place-items: center;

ul {
list-style: none;
margin: 0;
padding: 0;
display: grid;

li {
padding: 0;
}
}
}

liste stilleri kaldırılmış gezinme listesi

Hiyerarşik tanımı kaybettik, ancak aşağıdakilerle geri getirmeye başlayabiliriz:

nav {

> ul {
grid-auto-flow: column;

> li {
margin: 0 0.5rem;
}
}
}

Alt birleştirici seçiciyi kullanarak > üst düzey olduğunu tanımladık ul hangisinin doğrudan çocuğu nav değiştirmeli grid-auto-flow ile column bu da onu etkin bir şekilde günceller. x-axis. Daha sonra üst seviyeye marj ekliyoruz li biraz daha fazla tanım için öğeler. Şimdi, gelecekteki açılır öğeler “Tatlılar” menüsünün altında görünüyor ve daha açık bir şekilde onun alt öğeleri:

doğrudan alt stiller içeren gezinme listesi

Ardından, tüm bağlantıların yanı sıra ilk olarak bir stil dokunuşu ekleyeceğiz. .dropdown__titleardından yalnızca üst düzey bağlantılara ek olarak .dropdown__title. Burası aynı zamanda, miras alınan yerel tarayıcı stillerini de temizlediğimiz yerdir. button elementler.


.dropdown__title {
background-color: transparent;
border: none;
font-family: inherit;
}

nav {
> ul {
> li {
a,
.dropdown__title
{
text-decoration: none;
text-align: center;
display: inline-block;
color: blue;
font-size: 1.125rem;
}


> a,
.dropdown__title
{
padding: 1rem 0.5rem;
}
}
}
}

güncellenmiş bağlantı stilleri

Şimdiye kadar eleman seçicilere güveniyoruz, ancak belirli bir gezinme listesinde birden fazla olabileceğinden, açılır menü için sınıf seçicileri getireceğiz.

İlk önce stili oluşturacağız .dropdown__menu ve biz konumlandırma ve animasyon üzerinde çalışırken onu daha net bir şekilde tanımlamaya yardımcı olacak bağlantıları:

.dropdown {
position: relative;

.dropdown__menu {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0.15em 0.25em rgba(black, 0.25);
padding: 0.5em 0;
min-width: 15ch;

a {
color: #444;
display: block;
padding: 0.5em;
}
}
}

açılır __menü stilleri

Açık olan konulardan biri, .dropdown__menu etkiliyor nav griden görebileceğiniz konteyner nav açılır menü çevresinde arka plan mevcut.

ekleyerek bunu düzeltmeye başlayabiliriz. position: absolute için .dropdown__menu bu onu normal belge akışından çıkarır:

mutlak konumlu menü

Ana liste öğesinin soluna ve altına hizalandığını görebilirsiniz. Tasarımınıza bağlı olarak, bu istenen konum olabilir.

Menüyü liste öğesinin ortasına hizalamak için bir merkezleme hilesi çıkaracağız:

.dropdown__menu {

position: absolute;


top: calc(100% - 0.25rem);
left: 50%;
transform: translateX(-50%);
}

Bu merkezleme tekniğinin büyüsü, menünün herhangi bir genişlikte veya hatta dinamik bir genişlikte olabilmesi ve uygun şekilde ortalanmasıdır.

ortalanmış açılır menü__menü stilleri

Menüyü açmak için kullanmak istediğimiz iki ana tetikleyici var: :hover ve :focus.

Bununla birlikte, geleneksel :focus açılır listenin açık durumunu sürdürmez. İlk tetik odağı kaybettiğinde, klavye odağı hala açılır menüde hareket edebilir, ancak görsel olarak menü kaybolur.

adında yaklaşan bir sözde sınıf var :focus-within ve bunun yalnızca CSS’ye yönelik bir açılır menü olmasını mümkün kılmak için tam da ihtiyacımız olan şey bu. Girişte belirtildiği gibi, bir gerektirir çoklu dolgu IE < Edge 79'u desteklemeniz gerekiyorsa (siz yapıyorsunuz… şimdilik).

MDN’denitalikler benim yararlanacağımız kısmı göstermek için bana ait:

bu :focus-within CSS sözde sınıfı, odaklanmış bir öğeyi temsil eder veya odaklanmış bir öğe içeriyor. Başka bir deyişle, kendisi tarafından eşleştirilen bir öğeyi temsil eder. :focus sözde sınıf veya eşleşen bir soyundan gelen var :focus.

Varsayılan olarak açılır menüyü gizle

Açılır menüyü açığa çıkarmadan önce onu gizlememiz gerekiyor, bu yüzden gizli stilleri varsayılan durum olarak kullanacağız.

İlk içgüdün olabilir display: none ancak bu, geçişi zarafetle canlandırmamızı engelliyor.

Ardından, basitçe deneyebilirsiniz opacity: 0 bu, onu gözle görülür şekilde gizler, ancak öğenin hala hesaplanmış yüksekliğe sahip olması nedeniyle “hayalet bağlantılar” bırakır.

Bunun yerine, bir kombinasyonunu kullanacağız. opacity, transformve visibilty:

.dropdown__menu {
transform: rotateX(-90deg) translateX(-50%);
transform-origin: top center;
opacity: 0.3;
}

Daha sonra biraz daha yumuşak bir etki sağlamak için opaklık ekliyoruz, ancak 0’a kadar değil.

Ve güncelliyoruz transform dahil edilecek özellik rotateX(-90deg), bu da menüyü 3B alanda 90 derece “geriye” döndürecektir. Bu, yüksekliği etkili bir şekilde ortadan kaldırır ve ortaya çıkarmada ilginç bir geçiş sağlar. Ayrıca şunu fark edeceksiniz: transform-origin yatay ve dikey merkezin varsayılanına karşı dönüşümün uygulandığı noktayı güncellemek için eklediğimiz özellik.

Ayrıca, tanışmak için başarı kriterleri 1.3.2, bağlantılar görsel olarak görüntüleninceye kadar ekran okuyucu kullanıcılarından gizlenmelidir. Bu davranışı aşağıdakileri dahil ederek sağlarız: visibility: hidden (Bu ipucu için Michael’a tekrar teşekkürler!).

Açıklamayı yapmadan önce, bir eklememiz gerekiyor. transition Emlak. ana konuya ekliyoruz .dropdown__menu “ileri” ve “geri” olarak da adlandırılan odak/vurgulu üzerinde ve dışında geçerli olacak şekilde kuralı.

.dropdown__menu {
transition: 280ms all ease-out;
}

Tüm bu önceki kurulumlarla, hem vurgulu hem de odaktaki açılır menüyü ortaya çıkarmak, aşağıdaki gibi kısa ve öz bir şekilde gerçekleştirilebilir:

.dropdown {

&:hover,
&:focus-within
{
.dropdown__menu {
opacity: 1;
transform: rotateX(0) translateX(-50%);
visibility: visible;
}
}
}

İlk önce ters çeviriyoruz visibilty (veya diğer özellikler çalışmaz) ve ardından rotateX 0’a sıfırlayarak ve ardından opacity sonuna kadar 1 tam görünürlük için.

İşte sonuç:

odak ve fareyle üzerine gelindiğinde ortaya çıkma demosu

bu rotateX özellik, arkadan sallanan menünün görünümünü sağlar ve opacity sadece genel olarak biraz daha yumuşak geçiş yapar.

Bir kez daha, tam erişilebilirlik için Javascript’in her zaman tetiklemeyen klavye yardımcı teknoloji olaylarını tam olarak işlemesi gerektiğine dair bir not :focus. Bu, bazı gören klavye kullanıcılarının açılır bağlantıları keşfedebileceği, ancak :focus olay yayıldığında, açılır menünün gerçekten açıldığını görmezler. Görüntüle w3c demosu Javascript’i bu çözüme dahil etmenin nasıl tamamlanacağı hakkında.

Bir süredir bu web işindeyseniz, aşağıdakilerin sizi harekete geçireceğini umuyorum 🤯

Açılır menülerle savaşmaya ilk başladığımda, onları öncelikle IE7 için oluşturuyordum. Büyük bir projede, birkaç ekip üyesi “menü üzerinde geziniyorsam/fareyle geziniyorsam menünün görünmesini durdurabilir misin?” satırında bir şey sordu. Pek çok Googling’den sonra nihayet bulduğum çözüm (peşinde olduğum şeyi elde etmek için doğru ifadeyi bulmaya çalışmak dahil) şuydu: hoverIntent jQuery eklentisi.

Bunu ayarlamam gerekiyordu çünkü kullandığımız için transition özelliği, çok hafif bir gecikme de ekleyebiliriz. Genel amaçlar için bu, “arabadan geçme” fareyle üzerine gelmeler için açılır menü animasyonunun tetiklenmesini önleyecektir.

Tüm geçiş özelliklerini bir satırda tanımlarken sıra önemlidir ve sıradaki ikinci sayısal değer gecikme değeri olarak alınacaktır:

.dropdown__menu {
// ... existing styles
transition: 280ms all 120ms ease-out;
}

Sonuçlara göz atın:

fareyle üzerine gelindiğinde geçiş gecikmesinin demosu

Menüyü açma niyeti olarak gevşek bir şekilde çıkarabileceğimiz menüyü tetiklemek oldukça yavaş bir geçiş gerektirir. Gecikme, menüyü açmadan önce bilinçli olarak fark edilmeyecek kadar kısa, bu yüzden bir kazanç!

Özellikle daha yıkıcı olacak bir “mega menü” başlatacaksa, bunu geliştirmek için Javascript kullanmayı hala seçebilirsiniz, ancak bu yine de oldukça keyifli.

Fareyle üzerine gelme niyeti bir şeydir, ancak gerçekten bu menünün ek seçeneklere sahip olduğu konusunda kullanıcıya ek bir ipucuna ihtiyacımız var. Son derece yaygın bir kural, yerel bir seçim öğesinin göstergesini taklit eden bir “şapka” veya “aşağı ok”tur.

Bunu eklemek için güncelleyeceğiz .dropdown__title stiller. olarak tanımlayacağız inline-flex kapsayıcı ve ardından bir :after aşağı ok oluşturmak için kenarlık hilesini kullanan öğe. bir çizgi kullanıyoruz translateY() metnimizle optik olarak hizalamak için:

.dropdown {

.dropdown__title {
display: inline-flex;
align-items: center;

&:after {
content: "";
border: 0.35rem solid transparent;
border-top-color: rgba(blue, 0.45);
margin-left: 0.25em;
transform: translateY(0.15em);
}
}
}

açılır şapka göstergesi

Sonunda Javascript ile geliştirmeniz gerekebilecek başka bir yer.

Yalnızca CSS’de kalması ve uygulama dışı web siteleri için kabul edilebilir olması için başvuruda bulunmanız gerekir. tabindex="-1" gövdede, menünün dışındaki herhangi bir tıklamanın odağı ondan kaldırmasına ve kapanmasına izin verir.

Bu biraz gergin – ve kullanıcılar için biraz sinir bozucu olabilir – bu nedenle, özellikle aşağıdakileri tanımlarsanız, kaydırmada gizlemek için Javascript ile bunu geliştirmek isteyebilirsiniz. nav kullanmak position: sticky ve kullanıcıyla birlikte kaydırın.

Menüyü bağlantı öğesine daha görsel olarak bağlamak için bir ok, tüm gezinme bağlantılarında özel odak durumları ve position: sticky üzerinde nav:

Stephanie Eckles (@5t3ph)

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.