Kaydırma çubukları ve onay kutularından oluşan bir ayar bileşeninin nasıl oluşturulacağına dair temel bir genel bakış.
Bu yayında, web için duyarlı, birden fazla cihaz girişini destekleyen ve tarayıcılar arasında çalışan bir Ayarlar bileşeni oluşturma konusundaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.
Video izlemeyi tercih ediyorsanız veya geliştirdiğimiz ürünün kullanıcı arayüzü/kullanıcı deneyimi önizlemesini görmek istiyorsanız YouTube'daki daha kısa olan bu kılavuzu inceleyebilirsiniz:
Genel Bakış
Bu bileşenin özelliklerini aşağıdaki bölümlere ayırdım:
- Düzenler
- Renk
- Özel aralık girişi
- Özel onay kutusu girişi
- Erişilebilirlikle ilgili dikkat edilmesi gereken noktalar
- JavaScript
Düzenler
Bu, tamamen CSS Grid kullanılan ilk GUI Challenge demosudur. Izgara için Chrome Geliştirici Araçları ile vurgulanan her bir ızgarayı aşağıda görebilirsiniz:

Just for gap
En yaygın düzen:
foo {
display: grid;
gap: var(--something);
}
Bu düzene "yalnızca boşluk için" diyorum çünkü yalnızca bloklar arasında boşluk eklemek için ızgara kullanıyor.
Bu stratejiyi kullanan beş düzen vardır. Bunların tümü aşağıda gösterilmiştir:

Her giriş grubunu (.fieldset-item) içeren fieldset öğesi, öğeler arasında ince kenarlıklar oluşturmak için gap: 1px kullanıyor. Sınır sorunu yok.
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
Doğal ızgara sarmalama
En karmaşık düzen, <main> ile <form> arasındaki mantıksal düzen sistemi olan makro düzen oldu.
Sarmalanan içeriği ortalama
Hem flexbox hem de grid, align-items veya align-content için özellikler sunar. Sarmalama öğeleriyle çalışırken content düzen hizalamaları, alanı alt öğeler arasında bir grup olarak dağıtır.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
Ana öğe, alt öğelerin hem bir hem de iki sütunlu düzenlerde dikey ve yatay olarak ortalanması için place-content: center hizalama kısayolunu kullanıyor.
Yukarıdaki videoda, kaydırma gerçekleşmesine rağmen "içeriğin" nasıl ortalanmış olarak kaldığını izleyin.
Otomatik sığdırma minmax'ini tekrarlama
<form>, her bölüm için uyarlanabilir bir tablo düzeni kullanır.
Bu düzen, kullanılabilir alana göre bir veya iki sütun arasında geçiş yapar.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
Bu ızgarada, duyarlı düzene özel bir dokunuş katmak için row-gap (--space-xl) ve column-gap (--space-xxl) için farklı değerler kullanılıyor. Sütunlar üst üste geldiğinde büyük bir boşluk olmasını isteriz ancak bu boşluk, geniş ekrandaki kadar büyük olmamalıdır.
grid-template-columns özelliği 3 CSS işlevi kullanır: repeat(), minmax() ve min(). Una Kravets'in bu konuyla ilgili harika bir düzen blog yayını var. Bu yayında RAM olarak adlandırılıyor.
Una'nın düzeniyle karşılaştırırsanız bizim düzenimizde 3 özel ekleme vardır:
- Ek bir
min()işlevi iletiyoruz. align-items: flex-startdeğerini belirtiriz.max-width: 89vwtarzı var.
Evan Minto, blogundaki Intrinsically Responsive CSS Grid with minmax() and min() (minmax() ve min() ile Doğal Olarak Duyarlı CSS Izgarası) başlıklı yazısında ek min() işlevini ayrıntılı bir şekilde açıklıyor. Bu yazıyı okumanızı öneririm. flex-start hizalama düzeltmesi, varsayılan esnetme efektini kaldırır. Böylece bu düzenin alt öğelerinin eşit yüksekliklere sahip olması gerekmez, doğal ve içsel yüksekliklere sahip olabilirler. Bu YouTube videosunda, hizalama eklemesiyle ilgili kısa bir özet yer alıyor.
max-width: 89vw, bu yayında küçük bir döküme değer.
Stil uygulanmış ve uygulanmamış düzeni göstereyim:
Neler oluyor? max-width belirtildiğinde, auto-fit düzen algoritmasının alana kaç tekrar sığdırabileceğini bilmesi için bağlam, açık boyutlandırma veya kesin boyutlandırma sağlar. Alan "tam genişlikte" gibi görünse de CSS ızgara spesifikasyonuna göre kesin bir boyut veya maksimum boyut sağlanmalıdır. Maksimum boyut belirttim.
Peki, neden 89vw? Çünkü düzenim için "işe yaradı".
Chrome ekibinden birkaç kişiyle birlikte, 100vw gibi daha makul bir değerin neden yeterli olmadığını ve bunun aslında bir hata olup olmadığını araştırıyoruz.
Boşluk
Bu düzendeki uyumun büyük bir kısmı, sınırlı bir boşluk paletinden (tam olarak 7) kaynaklanır.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
Bunların kullanımı; grid, CSS @nest ve @media'nın 5. seviye söz dizimi ile çok iyi uyum sağlar. Aşağıda, tamamen <main> düzen stili grubuna ait bir örnek verilmiştir.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
Ortalanmış içeriğe sahip, varsayılan olarak orta düzeyde dolgulu bir tablo (mobil cihazlardaki gibi). Ancak görüntü alanı genişledikçe dolguyu artırarak yayılır. 2021 CSS is looking pretty good!
"Yalnızca boşluk için" adlı önceki düzeni hatırlıyor musunuz? Bu bileşende nasıl göründüklerinin daha eksiksiz bir versiyonunu burada bulabilirsiniz:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
Renk
Renklerin kontrollü kullanımı, bu tasarımın hem etkileyici hem de minimal olmasını sağladı. Ben şöyle yapıyorum:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
Yüzey ve metin renklerimi surface-dark ve surface-darker gibi adlar yerine sayılarla adlandırıyorum. Çünkü medya sorgusunda bunları ters çevireceğim ve açık ile koyu anlamlı olmayacak.
Bunları aşağıdaki gibi bir tercih medya sorgusunda çeviriyorum:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
Renk söz dizimi ayrıntılarına girmeden önce genel resme ve stratejiye hızlıca göz atmak önemlidir. Ancak biraz acele ettiğim için biraz geriye dönelim.
LCH?
Renk teorisi konusuna çok fazla girmeden LCH, rengi matematikle (ör. 255) nasıl ölçtüğümüze değil, rengi nasıl algıladığımıza hitap eden insan odaklı bir söz dizimidir. Bu durum, insanların daha kolay yazabilmesi ve diğer insanların bu düzenlemelere uyum sağlayabilmesi açısından belirgin bir avantaj sağlar.
Bugün bu demoda, açık ve koyu mod için değiştirdiğim söz dizimine ve değerlere odaklanalım. 1 yüzey ve 1 metin rengini inceleyelim:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
--surface1: lch(10 0 0), 10% açıklık, 0 kroma ve 0 renk tonuna karşılık gelir: çok koyu, renksiz bir gri. Ardından, açık mod için medya sorgusunda açıklık, 90% ile --surface1: lch(90 0 0); olarak değiştirilir. Stratejinin özü bu. İki tema arasında yalnızca açıklığı değiştirerek başlayın. Tasarımın gerektirdiği veya erişilebilirliği koruyabilecek kontrast oranlarını koruyun.
lch() ile ilgili avantaj, açıklığın insan odaklı olmasıdır. Bu nedenle, % oranında bir değişiklik yapıldığında, algısal ve tutarlı olarak % oranında farklı olacağını biliriz. Örneğin, hsl() o kadar güvenilir değildir.
İlgileniyorsanız renk uzayları ve lch() hakkında daha fazla bilgi edinebilirsiniz. Yakında geliyor.
CSS şu anda bu renklere hiçbir şekilde erişemez. Tekrar edelim: Modern monitörlerin çoğunda renklerin üçte birine erişimimiz yok. Bunlar sıradan renkler değil, ekranın gösterebileceği en canlı renklerdir. Monitör donanımı, CSS spesifikasyonlarından ve tarayıcı uygulamalarından daha hızlı geliştiği için web sitelerimiz soluk görünüyor.
Lea Verou
Renk şemasıyla uyarlanabilir form kontrolleri
Şu anda Safari ve Chromium gibi birçok tarayıcıda koyu tema kontrolleri bulunur ancak tasarımınızın bunları kullandığını CSS veya HTML'de belirtmeniz gerekir.
Yukarıda, DevTools'un Stiller panelinden özelliğin etkisi gösterilmektedir. Demoda HTML etiketi kullanılıyor. Bu, bence genellikle daha iyi bir konum:
<meta name="color-scheme" content="dark light">
Thomas Steiner'ın bu color-scheme makalesinde konuyla ilgili her şeyi öğrenebilirsiniz. Koyu renkli onay kutusu girişlerinden
çok daha fazlasını elde edebilirsiniz.
CSS accent-color
Son zamanlarda form öğelerinde accent-color ile ilgili etkinlikler oldu. Bu, tarayıcıların giriş öğesinde kullanılan ton rengini değiştirebilen tek bir CSS stilidir. GitHub'da daha fazla bilgi edinebilirsiniz. Bu bileşen için stillerime ekledim. Tarayıcılar destekledikçe onay kutularım, pembe ve mor çarpıcı renklerle temaya daha uygun hale gelecek.
input[type="checkbox"] {
accent-color: var(--brand);
}

Sabit renk geçişleri ve focus-within ile çarpıcı renkler
Renkler, az kullanıldığında daha çok dikkat çeker. Ben de bu etkiyi renkli kullanıcı arayüzü etkileşimleriyle yaratmayı seviyorum.
Yukarıdaki videoda, etkileşime kişilik kazandırmaya yardımcı olan birçok kullanıcı arayüzü geri bildirimi ve etkileşimi katmanı vardır:
- Bağlam vurgulanıyor.
- Değerin aralıkta "ne kadar dolu" olduğuna dair kullanıcı arayüzü geri bildirimi sağlama.
- Bir alanın giriş kabul ettiğine dair kullanıcı arayüzü geri bildirimi sağlama
CSS, bir öğeyle etkileşim kurulduğunda geri bildirim sağlamak için çeşitli öğelerin görünümünü değiştirmek üzere :focus-within sözde sınıfını kullanır. .fieldset-item öğesini inceleyelim. Bu çok ilginç bir konu:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
Bu öğenin alt öğelerinden birinde focus-within olduğunda:
.fieldset-itemarka planına daha yüksek kontrastlı bir yüzey rengi atanır.- İç içe yerleştirilmiş
svg, daha yüksek kontrast için beyaz renkle doldurulur. - İç içe yerleştirilmiş
<picture>clip-pathtam bir daireye dönüşür ve arka plan parlak sabit geçişle doldurulur.
Özel aralık
Aşağıdaki HTML giriş öğesini kullanarak görünümünü nasıl özelleştirdiğimi göstereceğim:
<input type="range">
Bu öğenin özelleştirmemiz gereken 3 bölümü vardır:
Aralık öğesi stilleri
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
CSS'nin ilk birkaç satırı, stillerin özel kısımlarıdır. Bunları net bir şekilde etiketlemenin faydalı olacağını umuyorum. Geri kalan stiller, bileşenin zor kısımlarını oluşturmak için tutarlı bir temel sağlamak amacıyla çoğunlukla sıfırlama stilleridir.
Stilleri takip edin
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
Bunun püf noktası, canlı dolgu rengini "ortaya çıkarmaktır". Bu işlem, üstteki sert duraklı gradyanla yapılır. Gradyan, dolgu yüzdesine kadar şeffaftır ve sonrasında doldurulmamış parça yüzey rengini kullanır. Doldurulmamış yüzeyin arkasında, şeffaflıkla ortaya çıkmayı bekleyen tam genişlikte bir renk vardır.
İz dolgu stili
Tasarımım, dolgu stilini korumak için JavaScript gerektiriyor. Yalnızca CSS stratejileri de var ancak bunlar, kaydırma çubuğu öğesinin kaydırma çubuğuyla aynı yükseklikte olmasını gerektiriyor ve bu sınırlar içinde bir uyum bulamadım.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
Bence bu, görsel açıdan güzel bir yükseltme. Kaydırma çubuğu JavaScript olmadan da sorunsuz çalışır. --track-fill özelliği zorunlu değildir. Bu özellik yoksa dolgu stili olmaz. JavaScript kullanılabiliyorsa özel niteliği doldurun ve kullanıcı değişikliklerini de gözlemleyerek özel niteliği değerle senkronize edin.
CSS-Tricks'te Ana Tudor tarafından yazılan bu makalede, yalnızca CSS kullanılarak çubuk dolgusunun nasıl yapılacağı gösteriliyor. Ayrıca range öğesini de çok ilham verici buldum.
Küçük resim stilleri
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
Bu stillerin çoğu güzel bir daire oluşturmak için kullanılır.
Burada da küçük resimlerin, parçaların ve ilişkili SVG öğelerinin dinamik renklerini birleştiren sabit arka plan gradyanını görüyorsunuz.
Fareyle üzerine gelindiğinde vurgulama için kullanılan box-shadow tekniğini ayırmak amacıyla etkileşim stillerini ayırdım:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
Hedef, kullanıcı geri bildirimleri için yönetimi kolay ve animasyonlu bir görsel vurgu oluşturmaktı. Kutu gölgesi kullanarak efektle düzen tetiklemeyi önleyebilirim. Bunu, bulanık olmayan ve kaydırma düğmesi öğesinin dairesel şekline uyan bir gölge oluşturarak yapıyorum. Ardından, fareyle üzerine gelindiğinde yayılma boyutunu değiştirip geçiş efekti ekliyorum.
Keşke onay kutularında da vurgu efekti bu kadar kolay olsaydı…
Tarayıcılar arası seçiciler
Tarayıcılar arası tutarlılık sağlamak için bu -webkit- ve -moz- seçicilere ihtiyacım olduğunu fark ettim:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
Özel onay kutusu
Aşağıdaki HTML giriş öğesini kullanarak görünümünü nasıl özelleştirdiğimi göstereceğim:
<input type="checkbox">
Bu öğenin özelleştirmemiz gereken 3 bölümü vardır:
Onay kutusu öğesi
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
transform-style ve position stilleri, vurguyu biçimlendirmek için daha sonra tanıtacağımız sözde öğeye hazırlanır. Aksi takdirde, çoğunlukla benim kişisel görüşlerimi yansıtan küçük stil değişiklikleri yapıyorum. İmlecin işaretçi olmasını seviyorum, ana hat ofsetlerini seviyorum, varsayılan onay kutuları çok küçük ve accent-color destekleniyorsa bu onay kutularını marka renk şemasına getirin.
Onay kutusu etiketleri
Onay kutuları için etiket sağlamak iki nedenden dolayı önemlidir. İlki, onay kutusu değerinin ne için kullanıldığını belirtmek, yani "ne için açık veya kapalı?" sorusunu yanıtlamaktır. İkincisi ise kullanıcı deneyimiyle ilgilidir. Web kullanıcıları, onay kutularıyla ilişkili etiketler aracılığıyla etkileşim kurmaya alışmıştır.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
Etiketinize, kimliğe göre bir onay kutusunu işaret eden bir for özelliği ekleyin: <label for="text-notifications">. Onay kutunuzda, fare veya ekran okuyucu gibi farklı araç ve teknolojilerle bulunabilmesi için hem adı hem de kimliği iki katına çıkarın:
<input type="checkbox" id="text-notifications" name="text-notifications">.
:hover, :active ve daha fazlası bağlantıyla birlikte ücretsiz olarak sunulur ve formunuzla etkileşim kurma yollarını artırır.
Onay kutusu vurgulama
Arayüzlerimin tutarlı olmasını istiyorum. Kaydırma çubuğu öğesinde, onay kutusuyla birlikte kullanmak istediğim güzel bir küçük resim vurgusu var. Küçük resim, gölgeyi büyütüp küçültmek için box-shadow ve spread özelliğini kullanabildi. Ancak bu efekt burada çalışmaz çünkü onay kutularımız kare şeklindedir ve kare şeklinde olmalıdır.
Aynı görsel efekti bir sözde öğe ve çok sayıda karmaşık CSS ile elde edebildim:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
Daire şeklinde bir sözde öğe oluşturmak kolay bir iş olsa da bu öğeyi bağlı olduğu öğenin arkasına yerleştirmek daha zordu. Düzeltmeden önceki ve sonraki hâli:
Bu kesinlikle bir mikro etkileşim ancak görsel tutarlılığı korumak benim için önemli. Animasyon ölçeklendirme tekniği, diğer yerlerde kullandığımız teknikle aynıdır. Özel bir özelliği yeni bir değere ayarladık ve CSS'nin bu özelliği hareket tercihlerine göre geçirmesine izin verdik. Buradaki temel özellik translateZ(-1px). Üst öğe 3D bir alan oluşturdu ve bu sözde öğe alt öğesi, kendisini z-uzayında biraz geriye yerleştirerek bu alandan yararlandı.
Erişilebilirlik
YouTube videosunda, bu ayar bileşeni için fare, klavye ve ekran okuyucu etkileşimleri çok iyi bir şekilde gösteriliyor. Burada bazı ayrıntılara değineceğim.
HTML öğesi seçenekleri
<form>
<header>
<fieldset>
<picture>
<label>
<input>
Bunların her biri, kullanıcının tarama aracıyla ilgili ipuçları ve püf noktaları içerir. Bazı öğeler etkileşim ipuçları sağlar, bazıları etkileşimi bağlar ve bazıları da ekran okuyucunun gezindiği erişilebilirlik ağacını şekillendirmeye yardımcı olur.
HTML özellikleri
Ekran okuyucular için gerekli olmayan öğeleri gizleyebiliriz. Bu örnekte, kaydırma çubuğunun yanındaki simgeyi gizleyebiliriz:
<picture aria-hidden="true">
Yukarıdaki videoda, Mac OS'te ekran okuyucu akışı gösterilmektedir. Giriş odağının bir kaydırma çubuğundan diğerine nasıl doğrudan geçtiğine dikkat edin. Bunun nedeni, bir sonraki kaydırıcıya giden yolda bir durak olabilecek simgeyi gizlemiş olmamızdır. Bu özellik olmadan, kullanıcının durması, dinlemesi ve göremediği resmi geçmesi gerekir.
SVG bir dizi matematiksel işlemden oluşur. Fareyle üzerine gelindiğinde gösterilecek bir başlık ve matematiksel işlemlerin ne oluşturduğuna dair okunabilir bir yorum için <title> öğesi ekleyelim:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
Bunun dışında, formun fare, klavye, video oyunu kumandaları ve ekran okuyucularda gerçekten iyi test edilmesi için yeterince açıkça işaretlenmiş HTML kullandık.
JavaScript
Çubuk dolgu renginin JavaScript'ten nasıl yönetildiğini daha önce ele almıştık.
Şimdi <form> ile ilgili JavaScript'e bakalım:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
Formla her etkileşimde bulunulduğunda ve form değiştirildiğinde, konsol formu bir nesne olarak tabloya kaydeder. Böylece, sunucuya gönderilmeden önce kolayca incelenebilir.

Sonuç
Benim nasıl yaptığımı öğrendiniz. Peki siz nasıl yapardınız? Bu da eğlenceli bir bileşen mimarisi oluşturur. En sevdiği çerçevede yuvalar içeren ilk sürümü kim yapacak? 🙂
Yaklaşımlarımızı çeşitlendirelim ve web'de geliştirme yapmanın tüm yollarını öğrenelim. Bir demo oluşturun, bağlantıları bana tweetleyin. Ben de bunları aşağıdaki Topluluk remiksleri bölümüne ekleyeyim.