Duyarlı ve erişilebilir bir anahtar bileşeni oluşturmaya dair temel bilgiler.
Bu yayında, anahtar bileşenlerini oluşturmanın bir yolu hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.
Videoyu tercih ediyorsanız bu yayının YouTube sürümünü burada bulabilirsiniz:
Genel Bakış
Anahtar, onay kutusuna benzer şekilde çalışır ancak açık ve kapalı boole durumlarını açıkça gösterir.
Bu demo, işlevlerinin büyük bir kısmı için <input type="checkbox" role="switch">
kullanır. Bu sayede, tam işlevsel ve erişilebilir olması için CSS veya JavaScript'e ihtiyaç duymaz. CSS'nin yüklenmesi, sağdan sola yazılan diller, dikeylik, animasyon ve daha fazlası için destek sağlar. JavaScript'i yüklemek, anahtarı sürüklenebilir ve somut hale getirir.
Özel özellikler
Aşağıdaki değişkenler, anahtarın çeşitli bölümlerini ve seçeneklerini temsil eder. Üst düzey sınıf olarak .gui-switch
, bileşen alt öğeleri genelinde kullanılan özel özellikleri ve merkezi özelleştirme için giriş noktalarını içerir.
Parça
Uzunluk (--track-size
), dolgu ve iki renk:
.gui-switch {
--track-size: calc(var(--thumb-size) * 2);
--track-padding: 2px;
--track-inactive: hsl(80 0% 80%);
--track-active: hsl(80 60% 45%);
--track-color-inactive: var(--track-inactive);
--track-color-active: var(--track-active);
@media (prefers-color-scheme: dark) {
--track-inactive: hsl(80 0% 35%);
--track-active: hsl(80 60% 60%);
}
}
Küçük resim
Boyut, arka plan rengi ve etkileşim vurgu renkleri:
.gui-switch {
--thumb-size: 2rem;
--thumb: hsl(0 0% 100%);
--thumb-highlight: hsl(0 0% 0% / 25%);
--thumb-color: var(--thumb);
--thumb-color-highlight: var(--thumb-highlight);
@media (prefers-color-scheme: dark) {
--thumb: hsl(0 0% 5%);
--thumb-highlight: hsl(0 0% 100% / 25%);
}
}
Azaltılmış hareket
Net bir takma ad eklemek ve tekrarı azaltmak için, PostCSS eklentisi ile özel bir mülke azaltılmış hareket tercihi kullanıcı medya sorgusu eklenebilir. Bu işlem, Media Queries 5'teki taslak spesifikasyonu temel alınarak yapılır:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Brüt kar
<input type="checkbox" role="switch">
öğemi bir <label>
ile sarmalayarak onay kutusu ve etiket ilişkisi belirsizliğini önlemek için ilişkilendirmelerini bir araya getirdim. Ayrıca kullanıcıya girişi değiştirmek için etiketle etkileşim kurma olanağı tanıdım.
<label for="switch" class="gui-switch">
Label text
<input type="checkbox" role="switch" id="switch">
</label>
<input type="checkbox">
, API ve durum ile önceden oluşturulmuş olarak gelir. Tarayıcı, checked
mülkünü ve oninput
ile onchanged
gibi giriş etkinliklerini yönetir.
Düzenler
Flexbox, grid ve özel özellikler, bu bileşenin stillerini korumak için çok önemlidir. Değerleri merkezileştirir, aksi takdirde belirsiz olan hesaplamalara veya alanlara ad verir ve kolay bileşen özelleştirmeleri için küçük bir özel mülk API'si etkinleştirir.
.gui-switch
Geçiş için üst düzey düzen, flexbox'tur. .gui-switch
sınıfı, çocukların düzenleri hesaplamak için kullandığı özel ve herkese açık özel mülkleri içerir.
.gui-switch {
display: flex;
align-items: center;
gap: 2ch;
justify-content: space-between;
}
Flexbox düzenini genişletmek ve değiştirmek, herhangi bir flexbox düzenini değiştirmeye benzer.
Örneğin, bir anahtarın üzerine veya altına etiket koymak ya da flex-direction
:
<label for="light-switch" class="gui-switch" style="flex-direction: column">
Default
<input type="checkbox" role="switch" id="light-switch">
</label>
Parça
Onay kutusu girişi, normal appearance: checkbox
boyutu kaldırılarak ve kendi boyutu sağlanarak anahtar yolu olarak biçimlendirilir:
.gui-switch > input {
appearance: none;
inline-size: var(--track-size);
block-size: var(--thumb-size);
padding: var(--track-padding);
flex-shrink: 0;
display: grid;
align-items: center;
grid: [track] 1fr / [track] 1fr;
}
Parça, küçük resim için tek tek tek hücreli bir ızgara parça alanı da oluşturur.
Küçük resim
appearance: none
stili, tarayıcı tarafından sağlanan görsel onay işaretini de kaldırır. Bu bileşen, bu görsel göstergenin yerini almak için girişte bir sözde öğe ve :checked
sözde sınıf kullanır.
Başparmak, input[type="checkbox"]
öğesine bağlı bir sözde öğe alt öğesidir ve track
ızgara alanını talep ederek kanalın altında değil üstünde yığın oluşturur:
.gui-switch > input::before {
content: "";
grid-area: track;
inline-size: var(--thumb-size);
block-size: var(--thumb-size);
}
Stiller
Özel mülkler, renk şemalarına, sağdan sola yazılan dillere ve hareket tercihlerine uyum sağlayan çok yönlü bir anahtar bileşeni sağlar.
Dokunmatik etkileşim stilleri
Mobil cihazlarda tarayıcılar, etiketlere ve girişlere dokunma vurguları ve metin seçim özellikleri ekler. Bu sorunlar, bu geçiş için gereken stil ve görsel etkileşim geri bildirimini olumsuz yönde etkiledi. Birkaç satır CSS ile bu efektleri kaldırabilir ve kendi cursor: pointer
stilimi ekleyebilirim:
.gui-switch {
cursor: pointer;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
Bu stiller, görsel etkileşimle ilgili değerli geri bildirimler olabileceğinden her zaman kaldırılmaları önerilmez. Kaldırırsanız özel alternatifler sunduğunuzdan emin olun.
Parça
Bu öğenin stilleri çoğunlukla şekli ve rengi ile ilgilidir. Bu bilgilere dönüşüm yoluyla üst öğe .gui-switch
'ten erişilir.
.gui-switch > input {
appearance: none;
border: none;
outline-offset: 5px;
box-sizing: content-box;
padding: var(--track-padding);
background: var(--track-color-inactive);
inline-size: var(--track-size);
block-size: var(--thumb-size);
border-radius: var(--track-size);
}
Geçiş yolu için dört özel mülkten çok çeşitli özelleştirme seçenekleri elde edilebilir. appearance: none
tüm tarayıcılarda onay kutusunun kenarlıklarını kaldırmadığı için border: none
eklenir.
Küçük resim
Küçük resim öğesi zaten sağ tarafta track
ancak daire stillerine ihtiyacı var:
.gui-switch > input::before {
background: var(--thumb-color);
border-radius: 50%;
}
Etkileşim
Fareyle üzerine gelmeyle vurgulanan öğeleri ve başparmak konumu değişikliklerini gösterecek etkileşimlere hazırlanmak için özel mülkleri kullanın. Hareket veya fareyle üzerine gelmeyle vurgulama stillerini değiştirmeden önce kullanıcı tercihi de kontrol edilir.
.gui-switch > input::before {
box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);
@media (--motionOK) { & {
transition:
transform var(--thumb-transition-duration) ease,
box-shadow .25s ease;
}}
}
Başparmak konumu
Özel mülkler, başparmağı parçaya yerleştirmek için tek bir kaynak mekanizması sağlar. Başparmak kaydırma çubuğunun kaydırma çubuğunun içinde ve doğru şekilde kaydırılmasını sağlamak için hesaplamalarda kullanacağımız kaydırma çubuğu ve başparmak boyutları (0%
ve 100%
) mevcuttur.
input
öğesi --thumb-position
konum değişkenine sahiptir ve başparmak sözde öğesi bunu translateX
konumu olarak kullanır:
.gui-switch > input {
--thumb-position: 0%;
}
.gui-switch > input::before {
transform: translateX(var(--thumb-position));
}
Artık CSS'deki --thumb-position
ve onay kutusu öğelerinde sağlanan sözde sınıfları değiştirebiliriz. transition: transform
var(--thumb-transition-duration) ease
öğesini bu öğede daha önce koşullu olarak ayarladığımız için aşağıdaki değişiklikler değiştirildiğinde animasyonlu olabilir:
/* positioned at the end of the track: track length - 100% (thumb width) */
.gui-switch > input:checked {
--thumb-position: calc(var(--track-size) - 100%);
}
/* positioned in the center of the track: half the track - half the thumb */
.gui-switch > input:indeterminate {
--thumb-position: calc(
(var(--track-size) / 2) - (var(--thumb-size) / 2)
);
}
Bu ayrı orkestrasyon iyi sonuç verdi. Küçük resim öğesi yalnızca bir stil (translateX
konumu) ile ilgilidir. Giriş, tüm karmaşıklığı ve hesaplamaları yönetebilir.
Sektör
Destek, input
öğesine CSS dönüşümleriyle dönme ekleyen bir değiştirici sınıf -vertical
ile sağlandı.
3D döndürülmüş bir öğe, bileşenin genel yüksekliğini değiştirmez. Bu da blok düzenini bozabilir. --track-size
ve --track-padding
değişkenlerini kullanarak bu durumu hesaba katın. Dikey bir düğmenin düzende beklendiği gibi akması için gereken minimum alan miktarını hesaplayın:
.gui-switch.-vertical {
min-block-size: calc(var(--track-size) + calc(var(--track-padding) * 2));
& > input {
transform: rotate(-90deg);
}
}
(RTL) sağdan sola
CSS uzmanı bir arkadaşım olan Elad Schecter ile birlikte, tek bir değişkeni değiştirerek sağdan sola yazılan dilleri işleyen CSS dönüşümlerini kullanarak kaydırılabilir bir yan menü prototipini oluşturduk. Bunu, CSS'de mantıksal özellik dönüştürme olmadığı ve hiçbir zaman olmayabileceği için yaptık. Elad, mantıksal dönüşümler için kendi özel mantığımızın tek bir konumda yönetilmesine olanak tanımak amacıyla yüzdeleri tersine çevirmek için özel bir mülk değeri kullanma fikrini ortaya attı. Bu geçişte aynı tekniği kullandım ve çok başarılı olduğunu düşünüyorum:
.gui-switch {
--isLTR: 1;
&:dir(rtl) {
--isLTR: -1;
}
}
--isLTR
adlı özel mülk başlangıçta 1
değerini alır. Bu, düzenimiz varsayılan olarak soldan sağa olduğundan true
olduğu anlamına gelir. Ardından, CSS sözde sınıfı :dir()
kullanılarak bileşen sağdan sola bir düzen içinde olduğunda değer -1
olarak ayarlanır.
Bir dönüştürme işleminin içindeki calc()
içinde kullanarak --isLTR
'ü harekete geçirin:
.gui-switch.-vertical > input {
transform: rotate(-90deg);
transform: rotate(calc(90deg * var(--isLTR) * -1));
}
Artık dikey anahtarın dönüşü, sağdan sola düzenin gerektirdiği karşı taraf konumunu hesaba katıyor.
Başparmak sözde öğesindeki translateX
dönüştürmelerinin de karşı taraf koşulunu hesaba katmak için güncellenmesi gerekir:
.gui-switch > input:checked {
--thumb-position: calc(var(--track-size) - 100%);
--thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}
.gui-switch > input:indeterminate {
--thumb-position: calc(
(var(--track-size) / 2) - (var(--thumb-size) / 2)
);
--thumb-position: calc(
((var(--track-size) / 2) - (var(--thumb-size) / 2))
* var(--isLTR)
);
}
Bu yaklaşım, mantıksal CSS dönüştürme işlemleri gibi bir kavramla ilgili tüm ihtiyaçları çözmek için işe yaramasa da birçok kullanım alanı için bazı DRY ilkeleri sunar.
Eyaletler
Yerleşik input[type="checkbox"]
'ü kullanmak için :checked
, :disabled
, :indeterminate
ve :hover
gibi çeşitli durumları ele almanız gerekir. :focus
, yalnızca ofsetinde ayarlama yapılarak kasıtlı olarak olduğu gibi bırakıldı. Odak halkası Firefox ve Safari'de harika görünüyordu:
Kontrol edildi
<label for="switch-checked" class="gui-switch">
Default
<input type="checkbox" role="switch" id="switch-checked" checked="true">
</label>
Bu durum, on
durumunu temsil eder. Bu durumda, giriş "parça" arka planı etkin renge, başparmak konumu ise "sona" ayarlanır.
.gui-switch > input:checked {
background: var(--track-color-active);
--thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}
Devre dışı
<label for="switch-disabled" class="gui-switch">
Default
<input type="checkbox" role="switch" id="switch-disabled" disabled="true">
</label>
:disabled
düğmesi yalnızca görsel olarak farklı görünmekle kalmaz, öğeyi de değiştirilemez hale getirir.Etkileşimin değiştirilemezliği tarayıcıdan bağımsızdır ancak görsel durumların appearance: none
kullanılması nedeniyle stillere ihtiyacı vardır.
.gui-switch > input:disabled {
cursor: not-allowed;
--thumb-color: transparent;
&::before {
cursor: not-allowed;
box-shadow: inset 0 0 0 2px hsl(0 0% 100% / 50%);
@media (prefers-color-scheme: dark) { & {
box-shadow: inset 0 0 0 2px hsl(0 0% 0% / 50%);
}}
}
}
Hem devre dışı hem de işaretli duruma sahip koyu ve açık temalara ihtiyaç duyduğundan bu durum biraz karmaşıktır. Stil kombinasyonlarının bakım yükünü hafifletmek için bu eyaletler için stil açısından minimal stiller seçtim.
Belirsiz
Genellikle unutulan bir durum da :indeterminate
'dir. Bu durumda onay kutusunun işareti kaldırılmamış veya işaretlenmemiştir. Bu eyalet eğlenceli, davetkar ve mütevazı bir yerdir. Boole durumlarının, durumlar arasında gizli geçişler olabileceğini hatırlatmak isteriz.
Onay kutusunu belirsiz olarak ayarlamak zordur. Bu ayarı yalnızca JavaScript yapabilir:
<label for="switch-indeterminate" class="gui-switch">
Indeterminate
<input type="checkbox" role="switch" id="switch-indeterminate">
<script>document.getElementById('switch-indeterminate').indeterminate = true</script>
</label>
Bu eyalet benim için mütevazı ve davetkar olduğundan, anahtar başparmağı konumunu ortada yerleştirmek uygun geldi:
.gui-switch > input:indeterminate {
--thumb-position: calc(
calc(calc(var(--track-size) / 2) - calc(var(--thumb-size) / 2))
* var(--isLTR)
);
}
İmleçle üzerine gelin
Fareyle üzerine gelme etkileşimleri, bağlı kullanıcı arayüzü için görsel destek sağlamalı ve etkileşimli kullanıcı arayüzüne yönlendirme sağlamalıdır. Bu anahtar, fareyle etiketin veya girişin üzerine gelindiğinde başparmağı yarı şeffaf bir halkayla vurgular. Bu fareyle üzerine gelme animasyonu, etkileşimli küçük resim öğesine yönlendirme sağlar.
"Vurgula" efekti box-shadow
ile yapılır. Fareyle devre dışı bırakılmamış bir girişin üzerine geldiğinizde --highlight-size
boyutunu artırın. Kullanıcı hareketi kabul ediyorsa box-shadow
'ü büyüterek geçiş yaparız. Kullanıcı hareketi kabul etmiyorsa öne çıkan anlar anında gösterilir:
.gui-switch > input::before {
box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);
@media (--motionOK) { & {
transition:
transform var(--thumb-transition-duration) ease,
box-shadow .25s ease;
}}
}
.gui-switch > input:not(:disabled):hover::before {
--highlight-size: .5rem;
}
JavaScript
Anahtar arayüzü, fiziksel bir arayüzü taklit etmeye çalışırken (özellikle de bir kanalın içinde daire olan bu tür) bana tuhaf gelebilir. iOS, anahtarlarıyla bu konuda doğru bir iş çıkarmış. Anahtarları yana doğru sürükleyebilirsiniz ve bu seçeneğe sahip olmak çok tatmin edici. Buna karşılık, sürükleme hareketi denendiğinde hiçbir şey olmuyorsa kullanıcı arayüzü öğesi etkin değilmiş gibi hissedilebilir.
Sürüklenebilir başparmaklar
Başparmak sözde öğesi, konumunu .gui-switch > input
kapsüllenen var(--thumb-position)
öğesinden alır. JavaScript, başparmak konumunu dinamik olarak güncellemek için girişte satır içi stil değeri sağlayarak işaretçi hareketini takip ediyormuş gibi görünmesini sağlayabilir. İşaretçi bırakıldığında satır içi stilleri kaldırın ve özel --thumb-position
mülkünü kullanarak sürüklemenin kapalıya mı yoksa açık konuma mı daha yakın olduğunu belirleyin. Bu, çözümün omurgasıdır; CSS özel özelliklerini değiştirmek için işaretçi konumlarını koşullu olarak izleyen işaretçi etkinlikleri.
Bileşen, bu komut dosyası gösterilmeden önce zaten% 100 çalışıyordu. Bu nedenle, girişi değiştirmek için bir etiketi tıklamak gibi mevcut davranışı korumak oldukça fazla çalışma gerektirir. JavaScript'imiz, mevcut özellikler pahasına özellik eklememelidir.
touch-action
Özel bir hareket olan sürükleme, touch-action
avantajları için mükemmel bir adaydır. Bu anahtar durumunda, yatay hareket komut dosyası tarafından ele alınmalı veya dikey anahtar varyantı için dikey hareket yakalanmalıdır. touch-action
ile tarayıcıya bu öğede hangi hareketlerin ele alınacağını söyleyebiliriz. Böylece komut dosyası, hareketi herhangi bir rekabet olmadan ele alabilir.
Aşağıdaki CSS, tarayıcıya bir işaretçi hareketi bu geçiş parçasından başladığında dikey hareketleri işlemesini, yatay hareketlerle hiçbir şey yapmamasını söyler:
.gui-switch > input {
touch-action: pan-y;
}
İstenilen sonuç, sayfayı kaydırmayan veya kaydırmayan yatay bir harekettir. İşaretçi, girişten başlayarak dikey olarak kaydırabilir ve sayfayı kaydırabilir ancak yatay olanlar özel olarak işlenir.
Piksel değeri stili yardımcı programları
Kurulum sırasında ve sürükleme sırasında, öğelerden çeşitli hesaplanmış sayı değerlerinin alınması gerekir. Aşağıdaki JavaScript işlevleri, bir CSS özelliğine göre hesaplanmış piksel değerleri döndürür. Kurulum komut dosyasında şu şekilde kullanılır: getStyle(checkbox, 'padding-left')
.
const getStyle = (element, prop) => {
return parseInt(window.getComputedStyle(element).getPropertyValue(prop));
}
const getPseudoStyle = (element, prop) => {
return parseInt(window.getComputedStyle(element, ':before').getPropertyValue(prop));
}
export {
getStyle,
getPseudoStyle,
}
window.getComputedStyle()
işlevinin ikinci bir bağımsız değişkeni (hedef sözde öğe) nasıl kabul ettiğine dikkat edin. JavaScript'in öğelerden ve hatta sözde öğelerden bu kadar çok değer okuyabilmesi oldukça güzel.
dragging
Bu, sürükleme mantığı için temel bir andır ve işlev etkinliği işleyicisinden dikkat edilmesi gereken birkaç nokta vardır:
const dragging = event => {
if (!state.activethumb) return
let {thumbsize, bounds, padding} = switches.get(state.activethumb.parentElement)
let directionality = getStyle(state.activethumb, '--isLTR')
let track = (directionality === -1)
? (state.activethumb.clientWidth * -1) + thumbsize + padding
: 0
let pos = Math.round(event.offsetX - thumbsize / 2)
if (pos < bounds.lower) pos = 0
if (pos > bounds.upper) pos = bounds.upper
state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
}
Komut dosyası kahramanı state.activethumb
'tir. Bu komut dosyasının bir işaretçiyle birlikte yerleştirdiği küçük dairedir. switches
nesnesi, anahtarların .gui-switch
olduğu ve değerlerin komut dosyasını verimli tutan önbelleğe alınmış sınırlar ve boyutlar olduğu bir Map()
'tır. Sağdan sola akış, CSS'nin kullandığı özel mülk --isLTR
ile yönetilir ve mantığı tersine çevirmek ve RTL'yi desteklemeye devam etmek için kullanılabilir. Başparmak konumlandırması için yararlı bir delta değeri içerdiğinden event.offsetX
de değerlidir.
state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
Bu son CSS satırı, küçük resim öğesi tarafından kullanılan özel özelliği ayarlar. Bu değer atama işlemi normalde zaman içinde geçiş yapar ancak önceki bir işaretçi etkinliği --thumb-transition-duration
değerini geçici olarak 0s
olarak ayarlayarak yavaş bir etkileşimi ortadan kaldırır.
dragEnd
Kullanıcının anahtarı çok uzak bir yere sürükleyip bırakmasına izin vermek için küresel bir pencere etkinliği kaydedilmesi gerekir:
window.addEventListener('pointerup', event => {
if (!state.activethumb) return
dragEnd(event)
})
Kullanıcının serbestçe sürükleme özgürlüğüne sahip olması ve arayüzün bunu hesaba katacak kadar akıllı olması çok önemli. Bu geçişle ilgili sorunu çözmek çok fazla zaman almadı ancak geliştirme sürecinde dikkatli bir şekilde ele alınması gerekiyordu.
const dragEnd = event => {
if (!state.activethumb) return
state.activethumb.checked = determineChecked()
if (state.activethumb.indeterminate)
state.activethumb.indeterminate = false
state.activethumb.style.removeProperty('--thumb-transition-duration')
state.activethumb.style.removeProperty('--thumb-position')
state.activethumb.removeEventListener('pointermove', dragging)
state.activethumb = null
padRelease()
}
Öğeyle etkileşim tamamlandı. Giriş kontrollü mülkünü ayarlama ve tüm hareket etkinliklerini kaldırma zamanı. Onay kutusu state.activethumb.checked = determineChecked()
ile değiştirilir.
determineChecked()
dragEnd
tarafından çağrılan bu işlev, başparmak akışının kendi kanalının sınırları içinde nerede olduğunu belirler ve kanalın yarısına eşit veya daha fazlaysa doğru değerini döndürür:
const determineChecked = () => {
let {bounds} = switches.get(state.activethumb.parentElement)
let curpos =
Math.abs(
parseInt(
state.activethumb.style.getPropertyValue('--thumb-position')))
if (!curpos) {
curpos = state.activethumb.checked
? bounds.lower
: bounds.upper
}
return curpos >= bounds.middle
}
Ek düşünceler
Seçilen ilk HTML yapısı nedeniyle sürükleme hareketi biraz kod borcuna neden oldu. Bu yapının en önemli özelliği, girişin bir etikete sarmalanmasıydı. Ebeveyn öğe olan etiket, girişten sonra tıklama etkileşimlerini alır. dragEnd
etkinliğinin sonunda, padRelease()
işlevinin garip bir şekilde seslendirildiğini fark etmiş olabilirsiniz.
const padRelease = () => {
state.recentlyDragged = true
setTimeout(_ => {
state.recentlyDragged = false
}, 300)
}
Bu, kullanıcının gerçekleştirdiği etkileşimin işaretini kaldıracağı veya işaretleyeceği için etiketin bu sonraki tıklamayı aldığını hesaba katmaktır.
Bunu tekrar yapacak olsaydım, etiket tıklamalarını kendi başına yöneten ve yerleşik davranışla çakışmayan bir öğe oluşturmak için kullanıcı deneyimi yükseltme sırasında DOM'u JavaScript ile ayarlama seçeneğini değerlendirebilirdim.
Bu tür JavaScript'i yazmak en sevmediğim şeylerden biridir. Koşullu etkinlik kabartmayı yönetmek istemiyorum:
const preventBubbles = event => {
if (state.recentlyDragged)
event.preventDefault() && event.stopPropagation()
}
Sonuç
Bu küçük anahtar bileşeni, bugüne kadarki tüm GUI yarışmalarında en çok çalışma gerektiren bileşen oldu. 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
- @KonstantinRouda, özel öğe: demo ve code.
- @jhvanderschee düğmesi: Codepen.
Kaynaklar
.gui-switch
Kaynak kodunu GitHub'da bulun.