Duyarlı ve erişilebilir bir geçiş bileşeni oluşturmaya ilişkin temel bir genel bakış.
Bu yayında, anahtar bileşenlerini oluşturmanın bir yolu üzerine düşünmek 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 boole açık ve kapalı durumlarını açık bir şekilde temsil eder.
Bu demo, işlevlerinin çoğunda <input type="checkbox" role="switch">
kullanılmaktadır. Bu da, CSS veya JavaScript'in tam olarak işlevsel ve erişilebilir olması gerekmemesi gibi bir avantaja sahiptir. CSS'nin yüklenmesi sağdan sola diller, dikeylik, animasyon ve daha fazlasını destekler. JavaScript'in yüklenmesi anahtarı sürüklenebilir ve somut hale getirir.
Özel özellikler
Aşağıdaki değişkenler, anahtarın çeşitli parçalarını ve bunların seçeneklerini temsil eder. Üst düzey sınıf olan .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 azaltılmış hareket tercihi kullanıcı medya sorgusu, şu Medya Sorguları'ndaki taslak spesifikasyona dayanarak PostCSS eklentisi ile özel bir mülke yerleştirilebilir:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Markup
<input type="checkbox" role="switch">
öğemi bir <label>
ile sarmalamayı seçtim, onay kutusu ve etiket ilişkilendirmesinin belirsizliğini önlemek için ilişkilerini paket hâline getirdim. Ayrıca kullanıcıya, girişi açıp kapatmak için etiketle etkileşim kurma olanağı verdim.
<label for="switch" class="gui-switch">
Label text
<input type="checkbox" role="switch" id="switch">
</label>
<input type="checkbox">
, önceden oluşturulmuş bir API ve state ile birlikte gelir. Tarayıcı, checked
özelliğini ve oninput
ile onchanged
gibi giriş etkinliklerini yönetir.
Düzenler
Flexbox, grid ve özel özellikler, bu bileşenin stillerini korumak açısından kritik öneme sahiptir. Değerleri merkezileştirir, belirsiz hesaplamalara veya alanlara adlar verir ve kolay bileşen özelleştirmeleri için küçük bir özel özellik API'si sağlar.
.gui-switch
Anahtarın üst düzey düzeni flexbox'tır. .gui-switch
sınıfı, çocukların düzenlerini hesaplamak için kullandığı gizli ve herkese açık özel özellikleri 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ştirmek gibidir.
Örneğin, etiketleri bir anahtarın üstüne veya altına yerleştirmek ya da flex-direction
öğesini değiştirmek için:
<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
öğesi kaldırılıp bunun yerine kendi boyutu sağlanarak geçiş kanalı 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, başparmak tarafından talep edilmesi için tek tek hücre ızgara izleme alanı da oluşturur.
Küçük resim
appearance: none
stili, tarayıcının sağladığı görsel onay işaretini de kaldırır. Bu bileşen, bu görsel göstergeyi değiştirmek için girişte bir sözde öğe ve :checked
sözde sınıf kullanır.
Baş parmak, input[type="checkbox"]
öğesine eklenmiş yapay bir öğedir ve kılavuz alanını track
belirterek kanalın altında değil üstüne üst kısımda yer alır:
.gui-switch > input::before {
content: "";
grid-area: track;
inline-size: var(--thumb-size);
block-size: var(--thumb-size);
}
Stiller
Özel özellikler, renk şemalarına, sağdan sola dillere ve hareket tercihlerine uyum sağlayan çok yönlü bir anahtar bileşeni sağlar.
Dokunma etkileşim stilleri
Mobil cihazlarda tarayıcılar, etiketlere ve girişlere dokunarak vurgulama vurgulamaları ve metin seçimi özellikleri ekler. Bu sorunlar, geçiş için gereken stil ve görsel etkileşim geri bildirimini olumsuz etkiledi. Birkaç satır CSS ile bu efektleri kaldırıp kendi cursor: pointer
stilimi ekleyebilirim:
.gui-switch {
cursor: pointer;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
Değerli görsel etkileşim geri bildirimleri olabileceğinden bu stilleri kaldırmanız her zaman tavsiye edilmez. Bunları kaldırırsanız özel alternatifler sağlamayı unutmayın.
Parça
Bu öğenin stilleri çoğunlukla şekli ve rengiyle ilgilidir. Öğeye, basamakla aracılığıyla üst .gui-switch
öğesinden erişir.
.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ş kanalı için çok çeşitli özelleştirme seçenekleri dört özel özellikten gelir. appearance: none
tüm tarayıcılarda onay kutusundaki kenarlıkları kaldırmadığı için border: none
eklendi.
Küçük resim
Baş parmak öğesi zaten sağ track
konumunda ancak daire stillerine ihtiyaç duyuyor:
.gui-switch > input::before {
background: var(--thumb-color);
border-radius: 50%;
}
Etkileşim
Fareyle üzerine gelerek vurgulamaları ve başparmak konumu değişikliklerini gösterecek etkileşimlere hazırlanmak için özel özellikleri kullanın. Hareket veya fareyle üzerine gelme vurgulama stilleri değiştirilmeden önce kullanıcının 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 özellikler, başparmağın kanalda konumlandırılması için tek bir kaynak mekanizması sağlar. Elimizde, başparmakların belirli uzaklıkta kopyasının ve kanalın içinde doğru şekilde ilerlemesini sağlamak için hesaplamalarda kullanacağımız parça ve başparmak boyutları bulunmaktadır:
0%
ve 100%
.
input
öğesi --thumb-position
konum değişkeninin sahibidir ve baş parmak sözde öğesi, bunu bir translateX
konumu olarak kullanır:
.gui-switch > input {
--thumb-position: 0%;
}
.gui-switch > input::before {
transform: translateX(var(--thumb-position));
}
Artık --thumb-position
öğesini CSS'den ve onay kutusu öğelerinde sağlanan sözde sınıflardan değiştirebiliriz. Bu öğede önceden transition: transform
var(--thumb-transition-duration) ease
öğesini koşullu olarak ayarladığımızdan şu değişiklikler değiştirildiğinde animasyon gösterilebilir:
/* 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)
);
}
Bence bu ayrıştırılmış düzenleme iyi sonuç verdi. Baş parmak öğesi yalnızca tek bir stille, bir translateX
konumuyla ilgilidir. Giriş, tüm karmaşıklık ve hesaplamaları
yönetebilir.
Dikey
Destek, input
öğesine CSS dönüşümleriyle rotasyon ekleyen -vertical
adlı bir değiştirici sınıfıyla gerçekleştirildi.
3D döndürülmüş bir öğe, bileşenin toplam yüksekliğini değiştirmez. Bu durum, blok düzenine yol açabilir. --track-size
ve --track-padding
değişkenlerini kullanarak bunu 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
Bir CSS arkadaşım olan Elad Schecter ile birlikte, tek bir değişkeni çevirerek sağdan sola yazılan dilleri işleyen CSS dönüştürmelerini kullanan, dışa doğru kaydırılan yan menünün prototipini oluşturduk. CSS'de mantıksal özellik dönüşümü olmadığı ve hiçbir zaman olmayacağı için bunu yaptık. Elad, yüzdeleri ters çevirmek, böylece mantıksal dönüşümler için kendi özel mantığımızın tek bir konum olarak yönetilmesini sağlamak üzere özel bir özellik değeri kullanmayı düşünmüştü. Bu geçişte de aynı tekniği kullandım ve bence çok işe yaradı:
.gui-switch {
--isLTR: 1;
&:dir(rtl) {
--isLTR: -1;
}
}
--isLTR
adlı özel bir özellik başlangıçta 1
değerini alır. Diğer bir deyişle, düzenimiz varsayılan olarak soldan sağa olduğundan
true
değerine sahiptir. Daha sonra :dir()
CSS sözde sınıfı kullanılarak, bileşen sağdan sola bir düzen içinde olduğunda değer -1
olarak ayarlanır.
Bir dönüşümün içindeki calc()
içinde kullanarak --isLTR
işlemini gerçekleştirin:
.gui-switch.-vertical > input {
transform: rotate(-90deg);
transform: rotate(calc(90deg * var(--isLTR) * -1));
}
Şimdi dikey anahtarın döndürülmesi, sağdan sola düzen için gereken zıt kenar konumunu hesaba katar.
Baş parmak sözde öğedeki translateX
dönüşümlerinin de karşı taraf gereksinimini hesaba katacak şekilde 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üşümleri 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"]
, içinde bulunabileceği çeşitli durumlar işlenmeden tamamlanmış olmaz: :checked
, :disabled
, :indeterminate
ve :hover
. :focus
bilinçli bir şekilde yalnız bırakıldı, yalnızca belirli uzaklıktaki bir düzenleme yapı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 eyalet, on
durumunu temsil eder. Bu durumda, giriş "iz" arka planı etkin renge ve baş parmak konumu "son"a 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, aynı zamanda öğeyi sabit hale getirmelidir.Etkileşim değişmezliği tarayıcıdan bağımsızdır, ancak appearance: none
kullanımı nedeniyle görsel durumların 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%);
}}
}
}
Bu durum, hem devre dışı hem de işaretlenmiş durumda koyu ve açık temalara ihtiyaç duyduğu için yanıltıcıdır. Stil kombinasyonlarının sağladığı bakım yükünü azaltmak amacıyla, bu durumlar için stil açısından minimum stiller seçtim.
Belirsiz
Genellikle unutulan bir durum olan :indeterminate
, bir onay kutusunun işaretli olmadığı veya işaretsiz olduğu bir durumdur. Bu eğlenceli bir durumdur, davetkar ve mütevazıdır. Boole durumlarının durumlar arasında gizli olabileceğine dair iyi bir hatırlatma.
Belirsiz için onay kutusu ayarlamak karmaşıktır, bunu yalnızca JavaScript ayarlayabilir:
<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>
Eyalet mütevazı ve davetkar olduğu için geçişin baş parmağını ortaya koymayı uygun hissettim:
.gui-switch > input:indeterminate {
--thumb-position: calc(
calc(calc(var(--track-size) / 2) - calc(var(--thumb-size) / 2))
* var(--isLTR)
);
}
Üzerine gelme
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ön vermelidir. Bu anahtar, etiketin veya girişin üzerine geldiğinizde başparmağı yarı şeffaf bir halkayla vurgular. Ardından bu fareyle üzerine gelme animasyonu, etkileşimli başparmak öğesine yön sağlar.
"Vurgula" efekti box-shadow
ile tamamlandı. Fareyle devre dışı bırakılmış bir girişin üzerine geldiğinizde --highlight-size
boyutunu artırın. Kullanıcı hareket konusunda bir sıkıntı yaşıyorsa box-shadow
öğesinin geçişini yapıp büyüttüğünü görüyoruz. Hareketten memnun değilse vurgu anında görünür:
.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
Bir anahtar arayüzü, fiziksel bir arayüzü, özellikle de parça içindeki bir daireyi taklit etme girişimi nedeniyle bana sıra dışı gelebilir. iOS, anahtarlarıyla bunu doğru yaptı. Bunları bir yandan diğer yana sürükleyebilirsiniz. Bu seçeneğin olması çok tatmin edici. Öte yandan, bir sürükleme hareketi denendiğinde hiçbir şey olmazsa kullanıcı arayüzü öğesi etkin değilmiş gibi hissedebilir.
Sürüklenebilir küçük resimler
Sözde baş parmak öğesi, konumunu .gui-switch > input
kapsamlı var(--thumb-position)
öğesinden alır. JavaScript, baş parmak konumunu dinamik bir şekilde güncellemek ve işaretçi hareketini izliyormuş gibi göstermek için girişe bir satır içi stil değeri sağlayabilir. İşaretçi serbest bırakıldığında satır içi stilleri kaldırın ve --thumb-position
özel özelliğini kullanarak sürüklemenin kapalı mı yoksa açık mı olduğunu belirleyin. Bu, çözümün bel kemiğidir. İşaretçi etkinlikleri, CSS özel özelliklerini değiştirmek için işaretçi konumlarını koşullu olarak izler.
Bu komut dosyası gösterilmeden önce bileşen zaten% 100 işlevsel durumda olduğundan, girişi açıp kapatmak için bir etiketi tıklamak gibi mevcut davranışı sürdürmek için epey çalışma gerekiyor. JavaScript'imiz, mevcut özellikleri yitirip yeni özellikler eklememelidir.
touch-action
Sürükleme, özel bir hareket olduğundan touch-action
avantajları için mükemmel bir adaydır. Bu geçiş durumunda, yatay bir hareket komut dosyamız tarafından veya dikey anahtar varyantı için yakalanan dikey bir hareket olmalıdır. touch-action
ile tarayıcıya bu öğe üzerinde hangi hareketleri kullanacağını söyleyebiliriz. Böylece, komut dosyası bir hareketi rekabet olmadan işleyebilir.
Aşağıdaki CSS, tarayıcıya bir işaretçi hareketi bu geçiş yolunun içinden başladığında, dikey hareketleri ele alacağını ve yatay hareketlerle hiçbir şey yapmayacağını bildirir:
.gui-switch > input {
touch-action: pan-y;
}
İstenen sonuç, sayfayı kaydırmayan veya kaydırmayan yatay bir harekettir. İşaretçiler girişin içinden dikey olarak başlayabilir 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 hesaplanan sayı değerlerinin yakalanması gerekir. Aşağıdaki JavaScript işlevleri, bir CSS özelliği verildiğinde hesaplanan piksel değerlerini 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()
öğesinin ikinci bir bağımsız değişkeni, bir hedef sözde öğeyi nasıl kabul ettiğine dikkat edin. JavaScript'in, sözde öğelerden bile bu kadar çok öğe okuyabilmesi oldukça düzenlidir.
dragging
Bu, sürükleme mantığı için önemli bir andır ve işlev etkinlik işleyicisinde belirtilmesi 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
, bu komut dosyasının bir işaretçiyle birlikte konumlandırdığı
küçük daire. switches
nesnesi, anahtarların .gui-switch
olduğu bir Map()
öğesidir ve değerlerin, komut dosyasını verimli hale getiren önbelleğe alınmış sınırlar ve boyutlardır. Sağdan sola yönü, CSS ile aynı özel özellik (--isLTR
) kullanılarak işlenir ve bu özelliği, mantığı tersine çevirerek RTL'yi desteklemeye devam etmek için kullanabilir. event.offsetX
, başparmağı konumlandırmak için yararlı bir delta değeri içerdiğinden de değerlidir.
state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
CSS'nin bu son satırı, küçük öğe tarafından kullanılan özel özelliği ayarlar. Aksi takdirde, bu değer ataması zaman içinde geçiş yapar ancak önceki bir işaretçi etkinliğinde --thumb-transition-duration
yavaşça geçebilecek etkileşimi geçici olarak 0s
olarak ayarlar.
dragEnd
Kullanıcının anahtarın uzağa sürükleyip bırakmasına izin verilmesi için global bir pencere etkinliğinin kaydedilmesi gerekir:
window.addEventListener('pointerup', event => {
if (!state.activethumb) return
dragEnd(event)
})
Kullanıcının rahatça sürükleme özgürlüğüne sahip olması ve arayüzün bunu karşılayacak kadar akıllı olması bence çok önemli. Bu geçişle bunu halletmek fazla uzun sürmedi, ancak geliştirme sürecinde dikkatle düşünülmesi 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ş kontrol edilen özelliğinin ayarlanması ve tüm hareket etkinliklerini kaldırma zamanı. Onay kutusu state.activethumb.checked = determineChecked()
ile değiştirildi.
determineChecked()
dragEnd
tarafından çağrılan bu işlev, baş parmak akımının parkurunun sınırları içinde nerede olduğunu belirler ve yolun yarısına eşitse veya yolun yarısına eşitse true 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
}
Ekstra düşünceler
Sürükleme hareketi, seçilen ilk HTML yapısı nedeniyle bir miktar kod borcuna neden olur ve en önemlisi, girişin bir etiket içine sarmalanmasıdır. Üst öğe olan etiket, girişten sonra tıklama etkileşimlerini alır. dragEnd
etkinliğinin sonunda padRelease()
işlevinin garip bir ses işlevi olduğunu fark etmiş olabilirsiniz.
const padRelease = () => {
state.recentlyDragged = true
setTimeout(_ => {
state.recentlyDragged = false
}, 300)
}
Bunun nedeni, kullanıcının gerçekleştirdiği etkileşimin işaretini kaldıracağı veya bu etkileşimi kontrol edeceği için daha sonra bu tıklamayı alan etiketin hesaba katılmasıdır.
Bunu tekrar yaparsam kullanıcı deneyimi yeni sürüme geçiş sırasında JavaScript ile DOM'yi ayarlamayı düşünebilirim. Örneğin, etiket tıklamalarını kendi kendine işleyen ve yerleşik davranışla mücadele etmeyen bir öğe oluşturabilirim.
Bu tür JavaScript kullanmayı çok sevmedim. Koşullu etkinlik balonlarını yönetmek istemiyorum:
const preventBubbles = event => {
if (state.recentlyDragged)
event.preventDefault() && event.stopPropagation()
}
Sonuç
Bu ufak tefek geçiş bileşeni, şimdiye kadarki tüm GUI Meydan Okumaları arasında en fazla sonucu alan bileşen oldu. Nasıl yaptığımı artık bildiğine göre siz de nasıl yapardınız? 🙂
Yaklaşımlarımızı çeşitlendirelim ve web'de geliştirme yapmanın tüm yollarını öğrenelim. Bir demo oluşturun, bana tweet atın bağlantıları, aşağıdaki topluluk remiksleri bölümüne ekleyeceğim.
Topluluk remiksleri
- @KonstantinRouda özel bir öğeyle: demo ve kod.
- @jhvanderschee ve bir düğme: Codepen.
Kaynaklar
.gui-switch
kaynak kodunu GitHub'da bulun.