Membuat komponen Setelan

Ikhtisar dasar tentang cara membangun komponen setelan {i>slider<i} dan kotak centang.

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

Demo

Jika Anda lebih menyukai video, atau menginginkan pratinjau UI/UX terkait hal yang kami kembangkan, berikut panduan singkat di YouTube:

Ringkasan

Saya telah membagi beberapa aspek komponen ini menjadi beberapa 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 menjadi semua Petak CSS. Berikut adalah setiap petak yang ditandai dengan Chrome DevTools untuk petak:

Overlay spasi celah dan garis warna-warni yang membantu menampilkan semua kotak yang membentuk tata letak setelan

Hanya untuk jeda

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

Lima tata letak menggunakan strategi ini, berikut semuanya ditampilkan:

Tata letak petak vertikal ditandai dengan garis batas dan celah terisi

Elemen fieldset, yang berisi setiap grup input (.fieldset-item), menggunakan gap: 1px untuk membuat batas garis rambut antar-elemen. Tidak ada solusi pembatas yang rumit!

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

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Trik pembatas
.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, yaitu sistem tata letak logis antara <main> dan <form>.

Memusatkan konten ke tengah

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

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 di tata letak satu dan dua kolom.

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

Ulangi paskan otomatis minmax

<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) dengan column-gap (--space-xxl) untuk menempatkan sentuhan kustom tersebut di tata letak responsif. Saat kolom ditumpuk, kita menginginkan kesenjangan yang besar, tetapi tidak sebesar jika kita berada di layar yang 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 menyebutnya RAM.

Ada 3 tambahan khusus pada tata letak kita, 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 Petak CSS yang Responsif terhadap Intrinsik dengan minmax() dan min(). Sebaiknya baca hal tersebut. Koreksi perataan flex-start adalah menghapus efek regang default, sehingga turunan tata letak ini tidak perlu memiliki ketinggian yang sama, tetapi dapat memiliki ketinggian intrinsik alami. Video YouTube memberikan penjelasan singkat tentang penambahan penyelarasan ini.

max-width: 89vw perlu dijelaskan secara singkat dalam postingan ini. Izinkan saya menunjukkan tata letak dengan dan tanpa penerapan gaya:

Apa yang terjadi??? Jika max-width ditentukan, fungsi ini akan memberikan konteks, pengubahan ukuran eksplisit, atau pengubahan ukuran yang pasti untuk algoritma tata letak auto-fit guna mengetahui jumlah pengulangan yang dapat ditampung dalam ruang. Meskipun tampaknya sudah jelas bahwa ruangnya memiliki "lebar penuh", sesuai spesifikasi petak CSS, ukuran yang pasti atau ukuran maksimum harus disediakan. Saya telah memberikan ukuran maksimum.

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

Spasi

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

: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 baik dengan petak, CSS @nest, dan sintaksis @media level 5. Berikut adalah contohnya, kumpulan gaya tata letak <main> yang lengkap.

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

{i>Grid<i} dengan konten di tengah, dengan padding yang cukup secara {i>default<i} (seperti di perangkat seluler). Namun, jika makin banyak ruang area pandang yang tersedia, area ini akan menyebar dengan meningkatkan padding. CSS 2021 terlihat cukup bagus!

Ingat tata letak sebelumnya, "hanya untuk celah"? Berikut adalah versi yang lebih lengkap 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 menonjol sebagai ekspresif namun minimal. 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 saya dengan angka, bukan nama seperti surface-dark dan surface-darker karena dalam kueri media, saya akan membaliknya, dan terang serta gelap tidak akan bermakna.

Saya memasukkannya ke 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 secara keseluruhan sebelum membahas detail sintaksis warna. Tapi, karena saya sudah terlalu terlalu cepat, izinkan saya kembali.

LCH?

Tanpa terlalu mendalami teori warna, LCH adalah sintaksis berorientasi manusia, yang melayani cara kita memandang warna, bukan cara kita mengukur warna dengan matematika (seperti 255). Cara ini memberi keunggulan karena manusia dapat menulisnya dengan lebih mudah, dan orang lain akan dapat menyesuaikan dengan penyesuaian ini.

Screenshot halaman web pod.link/csspodcast, dengan Color 2: Perception episode yang dibuka
Pelajari warna persepsi (dan banyak lagi) di Podcast CSS

Untuk hari ini, dalam demo ini, mari kita fokus pada sintaks dan nilai yang saya balik untuk membuat terang dan gelap. Mari kita lihat 1 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 10% kecerahan, 0 kroma, dan 0 hue: abu-abu tidak berwarna yang sangat gelap. Kemudian, pada kueri media untuk mode terang, kecerahan dibalik menjadi 90% dengan --surface1: lch(90 0 0);. Dan itulah inti dari strategi tersebut. Mulailah dengan hanya mengubah kecerahan di antara 2 tema, mempertahankan rasio kontras yang diperlukan desain, atau apa yang dapat mempertahankan aksesibilitas.

Bonus dari lch() di sini adalah bahwa kecerahan berorientasi pada manusia, dan kita dapat merasakan perubahan % padanya, sehingga akan secara persepsi dan konsisten bahwa % berbeda. hsl() misalnya, tidak terlalu andal.

Ada lebih banyak hal yang dapat dipelajari tentang ruang warna dan lch() jika Anda tertarik. Segera hadir!

Saat ini CSS tidak dapat mengakses warna ini sama sekali. Izinkan saya mengulangi: Kita tidak memiliki akses ke sepertiga warna di sebagian besar monitor modern. Dan ini bukan sekadar warna, tetapi warna paling jernih yang dapat ditampilkan layar. Situs kami hancur karena monitor hardware berevolusi lebih cepat daripada spesifikasi CSS dan implementasi browser.

Lea Verou

Kontrol bentuk adaptif dengan skema warna

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

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

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

Pelajari semuanya di artikel color-scheme oleh Thomas Steiner. Ada lebih banyak hal yang bisa didapatkan daripada input kotak centang gelap!

CSS accent-color

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

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

Screenshot dari Chromium di Linux dengan kotak centang merah muda

Pop warna dengan gradien tetap dan fokus di dalam

Warna muncul paling banyak jika tidak sering digunakan, dan salah satu cara yang ingin saya capai adalah melalui interaksi UI yang penuh warna.

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

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

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

.fieldset-item {
  ...

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

    & svg {
      fill: white;
    }

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

Jika salah satu turunan elemen ini memiliki focus-dalam:

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

Rentang kustom

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

<input type="range">

Ada 3 bagian untuk elemen ini yang perlu kita sesuaikan:

  1. Elemen / container rentang
  2. Pelacakan
  3. Jempol

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 khusus dari gaya, dan saya harap pelabelan yang jelas akan membantu. Gaya lainnya sebagian besar adalah gaya yang direset, untuk memberikan fondasi yang konsisten dalam membangun bagian komponen yang rumit.

Gaya trek

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 "mengungkapkan" warna isian yang cerah. Hal ini dilakukan dengan gradien perhentian keras di bagian atas. Gradien transparan hingga persentase pengisian, dan setelah itu menggunakan warna platform trek yang tidak terisi. Di balik permukaan yang tidak terisi itu, ada warna dengan lebar penuh, yang menunggu transparansi untuk mengungkapnya.

Melacak gaya pengisian

Desain saya memerlukan JavaScript untuk mempertahankan gaya isian. Hanya ada strategi CSS tertentu, tetapi strategi tersebut memerlukan elemen thumb agar sama tingginya dengan lagu, dan saya tidak bisa menemukan keselarasan 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, hanya tidak akan memiliki gaya pengisian jika tidak ada. Jika JavaScript tersedia, isi properti kustom sekaligus amati setiap perubahan yang dilakukan pengguna, dengan menyinkronkan properti kustom dengan nilai.

Berikut ini postingan bagus tentang CSS-Tricks oleh Ana Tudor, yang menunjukkan solusi khusus CSS untuk pengisian jalur. Saya juga merasa elemen range ini sangat menginspirasi.

Gaya jempol

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

Mayoritas gaya ini adalah untuk membuat lingkaran yang bagus. Sekali lagi, Anda akan melihat gradien latar belakang tetap di sana yang menyatukan warna dinamis thumbnail, trek, dan elemen SVG terkait. Saya memisahkan gaya untuk interaksi guna membantu mengisolasi teknik box-shadow yang digunakan untuk sorotan pengarahan kursor:

@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 sorotan visual dengan animasi yang mudah dikelola untuk mendapatkan masukan pengguna. Dengan menggunakan bayangan kotak, saya dapat menghindari tata letak pemicu dengan efek. Saya melakukannya dengan membuat bayangan yang tidak diburamkan dan menyesuaikan dengan bentuk lingkaran elemen thumb. Lalu saya mengubah dan mentransisikan ukuran penyebarannya saat mengarahkan kursor.

Jika hanya efek sorotan yang begitu mudah di kotak centang...

Pemilih lintas browser

Saya mendapati 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 penampilannya:

<input type="checkbox">

Ada 3 bagian untuk 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 pseudo yang akan kita perkenalkan nanti untuk menata gaya sorotan. Jika tidak, itu sebagian besar berisi gaya opini minor dari saya. Saya suka kursor menjadi pointer, saya suka offset garis, 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 untuk kotak centang karena 2 alasan. Yang pertama adalah untuk menyatakan untuk apa nilai kotak centang digunakan, untuk menjawab "aktif atau nonaktif untuk apa?" Kedua, untuk UX, pengguna web sudah 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 menurut ID: <label for="text-notifications">. Pada kotak centang, gandakan nama dan ID untuk memastikannya ditemukan dengan berbagai alat dan teknologi, seperti mouse atau pembaca layar: <input type="checkbox" id="text-notifications" name="text-notifications">. :hover, :active, dan lainnya hadir secara gratis dengan koneksi ini, yang meningkatkan cara formulir Anda dapat berinteraksi.

Sorotan kotak centang

Saya ingin menjaga antarmuka saya konsisten, dan elemen {i>slider <i}memiliki sorot thumbnail yang bagus yang ingin saya gunakan dengan kotak centang. Thumbnail tersebut dapat menggunakan box-shadow dan properti spread-nya untuk menskalakan bayangan ke atas dan ke bawah. Namun, efek tersebut tidak berfungsi di sini karena kotak centang kita adalah, dan seharusnya, berbentuk persegi.

Saya dapat mencapai efek visual yang sama dengan elemen pseudo, dan CSS yang rumit dalam jumlah sangat sedikit:

@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 pseudo lingkaran adalah pekerjaan mudah, tetapi menempatkannya di belakang elemen yang dikaitkan lebih sulit. Ini sebelum dan setelah saya memperbaikinya:

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

Aksesibilitas

Video YouTube memberikan demonstrasi yang bagus tentang interaksi mouse, keyboard, dan pembaca layar untuk komponen setelan ini. Saya akan menyebutkan 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 dibuka 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 bergerak langsung dari satu penggeser ke penggeser berikutnya. Itu karena kita telah menyembunyikan ikon yang mungkin menjadi perhentian dalam perjalanan ke {i>slider<i} berikutnya. Tanpa atribut ini, pengguna harus berhenti, memproses, dan melewati gambar yang mungkin tidak dapat dilihat.

SVG adalah kumpulan matematika, mari kita 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 cukup jelas, sehingga pengujian bentuknya sangat baik di seluruh mouse, {i>keyboard<i}, pengontrol {i>video game<i}, dan pembaca layar.

JavaScript

Saya sudah membahas cara warna isian 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

Sekarang Anda tahu bagaimana saya melakukannya, bagaimana Anda akan?! Inilah arsitektur komponen yang menyenangkan! Siapa yang akan membuat versi pertama dengan slot di framework favorit mereka? 🙂

Mari lakukan diversifikasi pendekatan dan pelajari semua cara untuk membangun di web. Buat demo, link tweet me, 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 jarak pengarahan kursor antara elemen: demo dan sumber.