Mem-build komponen Setelan

Ringkasan dasar tentang cara membuat komponen setelan penggeser dan kotak centang.

Dalam postingan ini, saya ingin berbagi pemikiran tentang cara membuat komponen Setelan untuk web yang responsif, mendukung beberapa input perangkat, dan berfungsi di berbagai browser. Coba demo.

Demo

Jika Anda lebih suka video, atau ingin pratinjau UI/UX dari apa yang sedang kita bangun, berikut adalah panduan yang lebih singkat di YouTube:

Ringkasan

Kami telah menguraikan aspek komponen ini ke dalam bagian berikut:

  1. Tata Letak
  2. Warna
  3. Input rentang kustom
  4. Input kotak centang kustom
  5. Pertimbangan aksesibilitas
  6. JavaScript

Tata letak

Ini adalah demo Tantangan GUI pertama yang sepenuhnya menggunakan Petak CSS. Berikut adalah setiap petak yang ditandai dengan Chrome DevTools untuk petak:

Garis batas berwarna dan overlay jarak celah yang membantu menampilkan semua kotak yang membentuk tata letak setelan

Just for gap

Tata letak yang paling umum:

foo {
  display: grid;
  gap: var(--something);
}

Saya menyebut tata letak ini "hanya untuk celah" karena hanya menggunakan petak untuk menambahkan celah di antara blok.

Lima tata letak menggunakan strategi ini, berikut semua tata letak yang ditampilkan:

Tata letak petak vertikal ditandai dengan garis batas dan celah yang terisi

Elemen fieldset, yang berisi setiap grup input (.fieldset-item), menggunakan gap: 1px untuk membuat batas garis tipis di antara elemen. Tidak ada solusi perbatasan yang rumit.

Celah terisi
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Trik batas
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

Penggabungan petak alami

Tata letak yang paling kompleks akhirnya menjadi tata letak makro, sistem tata letak logis antara <main> dan <form>.

Memusatkan konten gabungan

Flexbox dan petak menyediakan kemampuan untuk align-items atau align-content, dan saat menangani elemen penggabungan, perataan tata letak content akan mendistribusikan ruang di antara turunan sebagai grup.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

Elemen utama menggunakan singkatan perataan place-content: center sehingga turunan dipusatkan secara vertikal dan horizontal dalam tata letak satu dan dua kolom.

Tonton video di atas untuk melihat bagaimana "konten" tetap berada di tengah, meskipun penggabungan telah terjadi.

Ulangi minmax auto-fit

<form> menggunakan tata letak petak adaptif untuk setiap bagian. Tata letak ini beralih dari satu ke dua kolom berdasarkan ruang yang tersedia.

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;
}

Petak ini memiliki nilai yang berbeda untuk row-gap (--space-xl) daripada column-gap (--space-xxl) untuk memberikan sentuhan kustom pada tata letak responsif. Saat kolom ditumpuk, kita menginginkan celah yang besar, tetapi tidak sebesar jika kita berada di layar lebar.

Properti grid-template-columns menggunakan 3 fungsi CSS: repeat(), minmax(), dan min(). Una Kravets memiliki postingan blog tata letak yang bagus tentang hal ini, yang disebutnya RAM.

Ada 3 tambahan khusus dalam tata letak kami, jika Anda membandingkannya dengan tata letak Una:

  • Kita meneruskan fungsi min() tambahan.
  • Kita menentukan align-items: flex-start.
  • Ada gaya max-width: 89vw.

Fungsi min() tambahan dijelaskan dengan baik oleh Evan Minto di blognya dalam postingan Intrinsically Responsive CSS Grid with minmax() and min(). Sebaiknya baca artikel tersebut. Koreksi perataan flex-start adalah untuk menghapus efek peregangan default, sehingga turunan tata letak ini tidak perlu memiliki tinggi yang sama, tetapi dapat memiliki tinggi intrinsik yang alami. Video YouTube ini memiliki ringkasan singkat tentang penambahan perataan ini.

max-width: 89vw layak diuraikan secara singkat dalam postingan ini. Berikut adalah tata letak dengan dan tanpa gaya yang diterapkan:

Apa yang terjadi? Saat max-width ditentukan, parameter ini memberikan konteks, ukuran eksplisit, atau ukuran pasti untuk algoritma tata letak auto-fit agar mengetahui jumlah pengulangan yang dapat dimasukkan ke dalam ruang. Meskipun tampaknya jelas bahwa ruang tersebut "lebar penuh", sesuai spesifikasi petak CSS, ukuran atau ukuran maksimum yang pasti harus disediakan. Saya telah memberikan ukuran maksimum.

Jadi, mengapa 89vw? Karena "berhasil" untuk tata letak saya. Saya dan beberapa orang Chrome lainnya sedang menyelidiki mengapa nilai yang lebih masuk akal, seperti 100vw tidak cukup, dan apakah ini sebenarnya bug.

Spasi

Sebagian besar harmoni tata letak ini berasal dari palet spasi yang terbatas, tepatnya 7.

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

Penggunaan alur ini sangat cocok dengan petak, @nest CSS, dan sintaksis level 5 @media. Berikut contohnya, kumpulan gaya tata letak <main> sepenuhnya.

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);
    }
  }
}

Petak dengan konten di tengah, dengan padding sedang secara default (seperti di perangkat seluler). Namun, seiring bertambahnya ruang area pandang, elemen akan menyebar dengan meningkatkan padding. CSS 2021 terlihat cukup bagus.

Ingat tata letak sebelumnya, "hanya untuk celah"? Berikut adalah versi yang lebih lengkap tentang tampilannya dalam komponen ini:

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

Warna

Penggunaan warna yang terkontrol membantu desain ini terlihat ekspresif, tetapi minimalis. Saya melakukannya seperti ini:

: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);
}

Saya menamai warna permukaan dan teks dengan angka, bukan nama seperti surface-dark dan surface-darker karena dalam kueri media, saya akan membaliknya, dan terang dan gelap tidak akan bermakna.

Saya membaliknya dalam kueri media preferensi seperti ini:

: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);
    }
  }
}

Penting untuk melihat sekilas gambaran dan strategi keseluruhan sebelum kita membahas detail sintaksis warna. Namun, karena saya terlalu cepat membahasnya, mari kita mundur sedikit.

LCH?

Tanpa terlalu mendalami teori warna, LCH adalah sintaksis yang berorientasi pada manusia, yang memenuhi cara kita memandang warna, bukan cara kita mengukur warna dengan matematika (seperti 255). Hal ini memberikan keuntungan tersendiri karena manusia dapat menulisnya dengan lebih mudah dan manusia lain akan selaras dengan penyesuaian ini.

Screenshot halaman pod.link/csspodcast, dengan episode Color 2: Perception ditampilkan
Pelajari warna persepsi (dan lainnya) di CSS Podcast

Untuk hari ini, dalam demo ini, mari kita fokus pada sintaksis dan nilai yang saya ubah untuk membuat mode terang dan gelap. Mari kita lihat 1 warna platform dan 1 warna teks:

: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) diterjemahkan menjadi kecerahan 10%, kroma 0, dan hue 0: abu-abu gelap tanpa warna. Kemudian, dalam kueri media untuk mode terang, kecerahan diubah menjadi 90% dengan --surface1: lch(90 0 0);. Dan itulah inti dari strategi ini. Mulailah dengan mengubah kecerahan di antara 2 tema, dengan mempertahankan rasio kontras yang diperlukan desain atau yang dapat mempertahankan aksesibilitas.

Bonus dengan lch() di sini adalah kecerahan berorientasi pada manusia, dan kita dapat merasa nyaman dengan perubahan % padanya, bahwa perubahan tersebut akan berbeda secara persepsi dan konsisten %. hsl() misalnya, tidak seandal itu.

Ada banyak hal yang perlu dipelajari tentang ruang warna dan lch() jika Anda tertarik. Fitur ini akan segera hadir.

Saat ini, CSS tidak dapat mengakses warna ini sama sekali. Sekali lagi: Kita tidak memiliki akses ke sepertiga warna di sebagian besar monitor modern. Dan ini bukan sembarang warna, melainkan warna paling cerah yang dapat ditampilkan layar. Situs kami terlihat pudar karena hardware monitor berkembang lebih cepat daripada spesifikasi CSS dan implementasi browser.

Lea Verou

Kontrol formulir adaptif dengan skema warna

Banyak browser yang menyediakan kontrol tema gelap, saat ini Safari dan Chromium, tetapi Anda harus menentukan dalam CSS atau HTML bahwa desain Anda menggunakannya.

Contoh di atas menunjukkan efek properti dari panel Styles di DevTools. Demo ini menggunakan tag HTML, yang menurut saya umumnya merupakan lokasi yang lebih baik:

<meta name="color-scheme" content="dark light">

Pelajari semua hal tentangnya dalam artikel color-scheme ini oleh Thomas Steiner. Ada banyak hal lain yang bisa diperoleh selain input kotak centang gelap.

CSS accent-color

Ada aktivitas terbaru seputar accent-color pada elemen formulir, yang merupakan satu gaya CSS yang dapat mengubah warna tint yang digunakan dalam elemen input browser. Baca selengkapnya di sini di GitHub. Saya telah menyertakannya dalam gaya saya untuk komponen ini. Karena browser mendukungnya, kotak centang saya akan lebih sesuai dengan tema dengan pop warna merah muda dan ungu.

input[type="checkbox"] {
  accent-color: var(--brand);
}

Screenshot dari Chromium di Linux yang menampilkan kotak centang berwarna merah muda

Pop warna dengan gradien tetap dan focus-within

Pop warna paling terlihat saat digunakan secukupnya, dan salah satu cara yang saya suka untuk mencapainya adalah melalui interaksi UI yang berwarna-warni.

Ada banyak lapisan masukan dan interaksi UI dalam video di atas, yang membantu memberikan kepribadian pada interaksi dengan:

  • Menyoroti konteks.
  • Memberikan masukan UI tentang "seberapa penuh" nilai dalam rentang tersebut.
  • Memberikan masukan UI bahwa kolom menerima input.

Untuk memberikan masukan saat elemen sedang berinteraksi, CSS menggunakan class pseudo :focus-within untuk mengubah tampilan berbagai elemen. Mari kita uraikan .fieldset-item, ini sangat menarik:

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

Saat salah satu turunan elemen ini memiliki focus-within:

  1. Latar belakang .fieldset-item diberi warna permukaan dengan kontras yang lebih tinggi.
  2. svg bertingkat diisi dengan warna putih untuk kontras yang lebih tinggi.
  3. <picture> clip-path bertingkat diperluas menjadi lingkaran penuh dan latar belakang diisi dengan gradien tetap yang cerah.

Rentang kustom

Dengan elemen input HTML berikut, saya akan menunjukkan cara menyesuaikan tampilannya:

<input type="range">

Ada 3 bagian dari elemen ini yang perlu kita sesuaikan:

  1. Elemen/penampung rentang
  2. Pelacakan
  3. Thumb

Gaya elemen rentang

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 */
}

Beberapa baris pertama CSS adalah bagian kustom dari gaya, dan kami harap pemberian label yang jelas dapat membantu. Gaya lainnya sebagian besar adalah gaya reset, untuk memberikan fondasi yang konsisten dalam membangun bagian komponen yang rumit.

Gaya jalur

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;
}

Triknya adalah "menampilkan" warna pengisi yang cerah. Hal ini dilakukan dengan gradien hard stop di atas. Gradiennya transparan hingga persentase pengisian, dan setelah itu menggunakan warna permukaan trek yang tidak terisi. Di balik permukaan yang tidak terisi itu, ada warna dengan lebar penuh, yang menunggu transparansi untuk menampilkannya.

Gaya isian trek

Desain saya memerlukan JavaScript untuk mempertahankan gaya pengisian. Ada strategi khusus CSS, tetapi strategi tersebut mengharuskan elemen thumb memiliki tinggi yang sama dengan trek, dan saya tidak dapat menemukan harmoni dalam batas tersebut.

/* 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));
  })
})

Menurut saya, ini adalah peningkatan visual yang bagus. Penggeser berfungsi dengan baik tanpa JavaScript, properti --track-fill tidak diperlukan, penggeser tidak akan memiliki gaya pengisian jika tidak ada. Jika JavaScript tersedia, isi properti kustom sekaligus amati setiap perubahan pengguna, sinkronkan properti kustom dengan nilai.

Berikut adalah postingan yang bagus di CSS-Tricks oleh Ana Tudor, yang menunjukkan solusi khusus CSS untuk pengisian trek. Saya juga menemukan elemen range ini sangat menginspirasi.

Gaya thumb

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;
}

Sebagian besar gaya ini adalah untuk membuat lingkaran yang bagus. Sekali lagi, Anda akan melihat gradien latar belakang tetap yang menyatukan warna dinamis thumb, trek, dan elemen SVG terkait. Saya memisahkan gaya untuk interaksi guna membantu mengisolasi teknik box-shadow yang digunakan untuk penandaan saat kursor diarahkan:

@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;
  }
}

Tujuannya adalah membuat sorotan visual animasi yang mudah dikelola untuk masukan pengguna. Dengan menggunakan bayangan kotak, saya dapat menghindari pemicuan tata letak dengan efek tersebut. Saya melakukannya dengan membuat bayangan yang tidak buram dan cocok dengan bentuk lingkaran elemen thumb. Kemudian, saya mengubah dan mentransisikan ukuran penyebarannya saat kursor diarahkan ke elemen.

Seandainya efek sorotan semudah itu pada kotak centang…

Pemilih lintas browser

Saya menemukan bahwa saya memerlukan pemilih -webkit- dan -moz- ini untuk mencapai konsistensi lintas browser:

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

Kotak centang kustom

Dengan elemen input HTML berikut, saya akan menunjukkan cara menyesuaikan tampilannya:

<input type="checkbox">

Ada 3 bagian dari elemen ini yang perlu kita sesuaikan:

  1. Elemen kotak centang
  2. Label terkait
  3. Efek sorotan

Elemen kotak centang

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;
}

Gaya transform-style dan position mempersiapkan elemen semu yang akan kita perkenalkan nanti untuk menata gaya sorotan. Jika tidak, sebagian besar adalah hal-hal kecil yang bersifat subjektif dari saya. Saya ingin kursor menjadi pointer, saya suka offset garis batas, kotak centang default terlalu kecil, dan jika accent-color didukung, masukkan kotak centang ini ke dalam skema warna merek.

Label kotak centang

Penting untuk memberikan label pada kotak centang karena 2 alasan. Pertama, untuk merepresentasikan kegunaan nilai kotak centang, untuk menjawab "aktif atau nonaktif untuk apa?" Kedua, untuk UX, pengguna web telah terbiasa berinteraksi dengan kotak centang melalui label terkait.

input
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
label
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

Pada label Anda, tempatkan atribut for yang mengarah ke kotak centang berdasarkan ID: <label for="text-notifications">. Pada kotak centang, gandakan nama dan id untuk memastikan kotak centang ditemukan dengan berbagai alat dan teknologi, seperti mouse atau pembaca layar: <input type="checkbox" id="text-notifications" name="text-notifications">. :hover, :active, dan lainnya tersedia secara gratis dengan koneksi, sehingga meningkatkan cara formulir Anda dapat berinteraksi.

Sorotan kotak centang

Saya ingin mempertahankan konsistensi antarmuka, dan elemen penggeser memiliki sorotan thumbnail yang bagus yang ingin saya gunakan dengan kotak centang. Thumbnail dapat menggunakan box-shadow dan properti spread-nya untuk meningkatkan dan menurunkan skala bayangan. Namun, efek tersebut tidak berfungsi di sini karena kotak centang kita, dan seharusnya, berbentuk persegi.

Saya dapat mencapai efek visual yang sama dengan elemen pseudo, dan sejumlah CSS yang rumit:

@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;
}

Membuat elemen semu lingkaran adalah pekerjaan yang mudah, tetapi menempatkannya di belakang elemen yang dilampirkan lebih sulit. Berikut adalah sebelum dan sesudah saya memperbaikinya:

Ini jelas merupakan interaksi mikro, tetapi penting bagi saya untuk menjaga konsistensi visual. Teknik penskalaan animasi sama dengan yang telah kita gunakan di tempat lain. Kita menetapkan properti kustom ke nilai baru dan membiarkan CSS mentransisikannya berdasarkan preferensi gerakan. Fitur utamanya adalah translateZ(-1px). Induk membuat ruang 3D dan turunan elemen semu ini memanfaatkannya dengan menempatkan dirinya sedikit ke belakang di ruang z.

Aksesibilitas

Video YouTube memberikan demonstrasi yang bagus tentang interaksi mouse, keyboard, dan pembaca layar untuk komponen setelan ini. Kami akan menjelaskan beberapa detailnya di sini.

Pilihan elemen HTML

<form>
<header>
<fieldset>
<picture>
<label>
<input>

Masing-masing berisi petunjuk dan tips untuk alat penjelajahan pengguna. Beberapa elemen memberikan petunjuk interaksi, beberapa menghubungkan interaktivitas, dan beberapa membantu membentuk hierarki aksesibilitas yang dijelajahi pembaca layar.

Atribut HTML

Kita dapat menyembunyikan elemen yang tidak diperlukan oleh pembaca layar, dalam hal ini ikon di samping penggeser:

<picture aria-hidden="true">

Video di atas menunjukkan alur pembaca layar di Mac OS. Perhatikan bagaimana fokus input berpindah langsung dari satu penggeser ke penggeser berikutnya. Hal ini karena kita telah menyembunyikan ikon yang mungkin menjadi perhentian dalam perjalanan ke penggeser berikutnya. Tanpa atribut ini, pengguna harus berhenti, mendengarkan, dan melewati gambar yang mungkin tidak dapat mereka lihat.

SVG adalah sekumpulan matematika, mari tambahkan elemen <title> untuk judul pengarahan kursor mouse gratis dan komentar yang dapat dibaca manusia tentang apa yang dibuat oleh matematika:

<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>

Selain itu, kami telah menggunakan HTML yang ditandai dengan jelas, sehingga formulir ini berfungsi dengan sangat baik di mouse, keyboard, controller game, dan pembaca layar.

JavaScript

Kami telah membahas cara warna pengisi trek dikelola dari JavaScript, jadi sekarang mari kita lihat JavaScript terkait <form>:

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

Setiap kali formulir berinteraksi dan diubah, konsol akan mencatat formulir sebagai objek ke dalam tabel agar mudah ditinjau sebelum dikirim ke server.

Screenshot hasil console.table(), tempat data formulir ditampilkan dalam tabel

Kesimpulan

Setelah tahu cara saya melakukannya, bagaimana cara Anda melakukannya? Hal ini membuat arsitektur komponen menjadi menarik. Siapa yang akan membuat versi pertama dengan slot di framework favorit mereka? 🙂

Mari kita diversifikasi pendekatan kita dan pelajari semua cara untuk membangun di web. Buat demo, tweet link-nya kepada saya, dan saya akan menambahkannya ke bagian Remix komunitas di bawah.

Remix komunitas

  • @tomayac dengan gayanya terkait area pengarahan kursor untuk label kotak centang. Versi ini tidak memiliki celah pengarahan kursor di antara elemen: demo dan sumber.