Bu yazıda, çoklu seçim bileşeni oluşturmanın bir yolu üzerine düşüncelerimi paylaşmak istiyorum. deneyin gösteri.
Videoyu tercih ederseniz, işte bu gönderinin bir YouTube versiyonu:
genel bakış #
Kullanıcılara genellikle öğeler sunulur, bazen sürü ve bu durumlarda listeyi azaltmak için bir yol sağlamak iyi bir fikir olabilir. aşırı seçim. Bu blog gönderisi, seçenekleri azaltmanın bir yolu olarak kullanıcı arabirimini filtrelemeyi araştırıyor. Bunu, kullanıcıların seçebileceği veya seçimini kaldırabileceği öğe niteliklerini sunarak, sonuçları azaltarak ve dolayısıyla aşırı seçim yükünü azaltarak yapar.
Etkileşimler #
Amaç, tüm kullanıcılar ve onların değişen giriş türleri için filtre seçenekleri arasında hızlı geçiş sağlamaktır. Bu, uyarlanabilir ve duyarlı bir bileşen çifti ile sağlanacaktır. Masaüstü, klavye ve ekran okuyucular için onay kutularından oluşan geleneksel bir kenar çubuğu ve <select multiple>
dokunmatik kullanıcılar için.
Yerleşik çoklu seçimi masaüstü için değil de dokunmatik için kullanma kararı işi kurtarıyor ve iş yaratıyor, ancak tüm yanıt verme deneyimini tek bir bileşende oluşturmaktan daha az kod borcuyla uygun deneyimler sunduğuna inanıyorum.
Dokunmak #
Dokunmatik bileşen yerden tasarruf sağlar ve mobilde kullanıcı etkileşiminin doğruluğuna yardımcı olur. Onay kutularından oluşan bir kenar çubuğunun tamamını daraltarak yerden tasarruf sağlar. <select>
yerleşik bindirmeli dokunma deneyimi. Sistem tarafından sağlanan geniş bir dokunma bindirme deneyimini göstererek giriş doğruluğuna yardımcı olur.
Klavye ve gamepad #
Aşağıda nasıl kullanılacağına dair bir gösteri <select multiple>
klavyeden.
Bu yerleşik çoklu seçim, biçimlendirilemez ve yalnızca çok fazla seçenek sunmaya uygun olmayan kompakt bir düzende sunulur. O küçük kutudaki seçeneklerin genişliğini nasıl gerçekten göremediğinizi görüyor musunuz? Boyutunu değiştirebilseniz de, yine de onay kutularının kenar çubuğu kadar kullanışlı değildir.
işaretleme #
Her iki bileşen de aynı pakette yer alacaktır. <form>
eleman. Bu formun sonuçları, ister onay kutuları ister çoklu seçim olsun, gözlemlenecek ve ızgarayı filtrelemek için kullanılacak, ancak bir sunucuya da gönderilebilir.
form></form>
Onay kutuları bileşeni #
Onay kutusu grupları bir <fieldset>
eleman ve verilen <legend>
. HTML bu şekilde yapılandırıldığında, ekran okuyucular ve FormData öğelerin ilişkisini otomatik olarak anlayacaktır.
form>
fieldset>
legend>New</legend>
… checkboxes …
</fieldset>
</form>
Gruplandırma yerindeyken, bir <label>
Ve <input type="checkbox">
filtrelerin her biri için. benimkini sarmayı seçtim <div>
yani CSS gap
özelliği, bunları eşit şekilde aralayabilir ve etiketler çok satırlı olduğunda hizalamayı koruyabilir.
form>
fieldset>
legend>New</legend>
div>
input type="checkbox" id="last 30 days" name="new" value="last 30 days">
label for="last 30 days">Last 30 Days</label>
</div>
div>
input type="checkbox" id="last 6 months" name="new" value="last 6 months">
label for="last 6 months">Last 6 Months</label>
</div>
</fieldset>
</form>
<select multiple>
bileşen #
Nadiren kullanılan bir özellik <select>
eleman multiple
. Öznitelik bir ile kullanıldığında <select>
öğe, kullanıcının listeden birçok öğe seçmesine izin verilir. Bu, etkileşimi bir radyo listesinden bir onay kutusu listesine değiştirmek gibidir.
form>
select multiple="true" title="Filter results by category">
…
</select>
</form>
içinde grupları etiketlemek ve oluşturmak için <select>
kullan <optgroup>
eleman ve ona bir ver label
özellik ve değer. Bu öğe ve öznitelik değeri şuna benzer: <fieldset>
Ve <legend>
elementler.
form>
select multiple="true" title="Filter results by category">
optgroup label="New">
…
</optgroup>
</select>
</form>
şimdi ekle <option>
Filtre için elemanlar.
form>
select multiple="true" title="Filter results by category">
optgroup label="New">
option value="last 30 days">Last 30 Days</option>
option value="last 6 months">Last 6 Months</option>
</optgroup>
</select>
</form>
Yardımcı teknolojiyi bilgilendirmek için sayaçlarla izleme girişi #
bu statü rolü Bu kullanıcı deneyiminde, ekran okuyucular ve diğer yardımcı teknolojiler için filtre çetelesini izlemek ve sürdürmek için teknik kullanılır. YouTube videosu özelliği gösterir. Entegrasyon, HTML ve öznitelik ile başlar role="status"
.
div role="status" class="sr-only" id="applied-filters"></div>
Bu öğe, içerikte yapılan değişiklikleri yüksek sesle okuyacaktır. İçeriği ile güncelleyebiliriz CSS sayaçları kullanıcılar onay kutuları ile etkileşime girdikçe. Bunu yapmak için önce girişlerin ve durum öğesinin üst öğesinde adı olan bir sayaç oluşturmamız gerekir.
aside {
counter-reset: filters;
}
Varsayılan olarak, sayım 0
ki bu harika, hiçbir şey :checked
bu tasarımda varsayılan olarak.
Ardından, yeni oluşturduğumuz sayacı artırmak için, <aside>
olan eleman :checked
. Kullanıcı girişlerin durumunu değiştirdikçe, filters
sayaç artacaktır.
aside :checked {
counter-increment: filters;
}
CSS artık onay kutusu kullanıcı arabiriminin genel çetelesinin farkındadır ve durum rolü öğesi boştur ve değerleri beklemektedir. CSS, çeteleyi bellekte tuttuğundan, counter()
işlev, sözde öğe içeriklerinden değere erişmeye izin verir:
aside #applied-filters::before {
content: counter(filters) " filters ";
}
Durum rolü öğesinin HTML’si artık bir ekran okuyucuya “2 filtre” duyurusu yapacak. Bu iyi bir başlangıç, ancak filtrelerin güncellediği sonuçların çetelesini paylaşmak gibi daha iyisini yapabiliriz. Sayaçların yapabileceklerinin dışında olduğu için bu işi JavaScript’ten yapacağız.
İç içe geçmiş heyecan #
Sayaç algoritması harika hissettirdi CSS yerleştirme-1, tüm mantığı tek bir bloğa koyabildiğim için. Okuma ve güncelleme için taşınabilir ve merkezi bir his verir.
aside {
counter-reset: filters;& :checked {
counter-increment: filters;
}
& #applied-filters::before {
content: counter(filters) " filters ";
}
}
Düzenler #
Bu bölüm, iki bileşen arasındaki yerleşimleri açıklamaktadır. Düzen stillerinin çoğu, masaüstü onay kutusu bileşeni içindir.
form #
Kullanıcılar için okunabilirliği ve taranabilirliği optimize etmek için, forma maksimum 30 karakterlik bir genişlik verilir ve esas olarak her filtre etiketi için bir optik çizgi genişliği ayarlanır. Form, ızgara düzenini kullanır ve gap
alan kümelerini boşaltma özelliği.
form {
display: grid;
gap: 2ch;
max-inline-size: 30ch;
}
bu <select>
eleman #
Hem etiket listesi hem de onay kutuları mobilde çok fazla yer kaplıyor. Bu nedenle, düzen, dokunma deneyimini değiştirmek için kullanıcının birincil işaretleme cihazını görmek için kontrol eder.
TheComedicComedian (pointer: coarse) {
select[multiple] {
display: block;
}
}
bir değeri coarse
kullanıcının birincil giriş cihazıyla ekranla yüksek hassasiyette etkileşim kuramayacağını belirtir. Bir mobil cihazda, işaretçi değeri genellikle coarse
birincil etkileşim dokunma olduğundan. Bir masaüstü cihazda, işaretçi değeri genellikle fine
bağlı bir fare veya başka bir yüksek hassasiyetli giriş aygıtına sahip olmak yaygın olduğu için.
alan kümeleri #
Varsayılan stil ve düzen <fieldset>
Birlikte <legend>
benzersiz:
Normalde, alt öğelerimi boşluk bırakmak için kullanırdım gap
özelliği, ancak benzersiz konumu <legend>
eşit aralıklı bir çocuk grubu oluşturmayı zorlaştırır. Yerine gap
bitişik kardeş seçici ve margin-block-start
kullanılmış.
fieldset {
padding: 2ch;& > div + div {
margin-block-start: 2ch;
}
}
Bu atlar <legend>
sadece hedefleyerek alanını ayarlamaktan <div>
çocuklar.
Filtre etiketi ve onay kutusu #
Doğrudan bir çocuğu olarak <fieldset>
ve formun maksimum genişliği içinde 30ch
, etiket metni çok uzunsa kaydırılabilir. Metni kaydırmak harika, ancak metin ve onay kutusu arasındaki yanlış hizalama değil. Flexbox bunun için idealdir.
fieldset > div {
display: flex;
gap: 2ch;
align-items: baseline;
}
animasyonlu ızgara #
Düzen animasyonu tarafından yapılır İzotop. Etkileşimli sıralama ve filtreleme için performanslı ve güçlü bir eklenti.
JavaScript #
Düzgün bir animasyonlu, etkileşimli ızgaranın düzenlenmesine yardımcı olmanın yanı sıra JavaScript, birkaç pürüzlü kenarı düzeltmek için kullanılır.
Kullanıcı girişinin normalleştirilmesi #
Bu tasarım, girdi sağlamanın iki farklı yolu olan tek bir forma sahiptir ve bunlar tefrika etmek aynısı. Yine de biraz JavaScript ile yapabiliriz normalleştirmek veri.
hizalamayı seçtim <select>
gruplanmış onay kutuları yapısına öğe veri yapısı. Bunu yapmak için bir input
olay dinleyicisi eklendi <select>
eleman, hangi noktada selectedOptions
haritalanır.
document.querySelector('select').addEventListener('input', event => {
// make selectedOptions iterable then reduce a new array object
let selectData = Array.from(event.target.selectedOptions).reduce((data, opt) => {
// parent optgroup label and option value are added to the reduce aggregator
data.push([opt.parentElement.label.toLowerCase(), opt.value])
return data
}, [])
})
Artık formu göndermek güvenlidir veya bu demo söz konusu olduğunda, Isotope’a neye göre filtre uygulayacağı konusunda talimat verin.
Durum rolü öğesini tamamlama #
Öğe, yalnızca onay kutusu etkileşimine dayalı olarak filtre sayısını sayıyor ve duyuruyor, ancak sonuçların sayısını ek olarak paylaşmanın ve aşağıdakileri sağlamanın iyi bir fikir olduğunu düşündüm: <select>
öğe seçimleri de sayılır.
<select>
yansıyan öğe seçimi counter()
#
Veri normalleştirme bölümünde, girişte zaten bir dinleyici oluşturuldu. Bu fonksiyonun sonunda seçilen filtre sayısı ve bu filtreler için sonuç sayısı bilinmektedir. Değerler bu şekilde durum rolü öğesine geçirilebilir.
let statusRoleElement = document.querySelector('#applied-filters')
statusRoleElement.style.counterSet = selectData.length
Yansıyan sonuçlar role="status"
eleman #
:checked
seçilen filtrelerin sayısını durum rolü öğesine geçirmek için yerleşik bir yol sağlar, ancak filtrelenen sonuç sayısına ilişkin görünürlükten yoksundur. JavaScript, onay kutularıyla etkileşimi izleyebilir ve ızgarayı filtreledikten sonra, textContent
gibi <select>
eleman yaptı.
document
.querySelector('aside form')
.addEventListener('input', e => {
// isotope demo code
let filterResults = IsotopeGrid.getFilteredItemElements().length
document.querySelector('#applied-filters').textContent = `giving ${filterResults} results`
})
Tamamen bu çalışma, “25 sonuç veren 2 filtre” duyurusunu tamamlar.
Artık mükemmel yardımcı teknoloji deneyimimiz, nasıl etkileşimde bulunurlarsa bulunsunlar tüm kullanıcılara sunulacak.
Çözüm #
Artık nasıl yaptığımı bildiğine göre, nasıl yapardın‽ 🙂
Yaklaşımlarımızı çeşitlendirelim ve web üzerinde oluşturmanın tüm yollarını öğrenelim. Bir demo oluşturun, beni tweetle bağlantılar ve onu aşağıdaki topluluk remiksleri bölümüne ekleyeceğim!
Topluluk remiksleri #
Burada henüz görülecek bir şey yok!