Mem-build komponen Setelan

Ringkasan dasar tentang cara membuat komponen setelan berupa 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 seluruh browser. Coba demo.

Demo

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

Ringkasan

Saya telah membagi 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 GUI Challenge pertama yang semuanya menggunakan Petak CSS. Berikut setiap petak yang ditandai dengan Chrome DevTools untuk petak:

Overlay jarak dan garis luar berwarna yang membantu menampilkan semua kotak yang membentuk tata letak setelan

Khusus untuk kesenjangan

Tata letak yang paling umum:

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

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

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

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

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

Kesenjangan yang 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 adalah tata letak makro, sistem tata letak logis antara <main> dan <form>.

Memusatkan konten yang digabungkan

Flexbox dan petak memberikan kemampuan untuk align-items atau align-content, dan saat menangani elemen pembungkus, 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 telah terjadi pelipatan.

Ulangi minmaks pengepasan otomatis

<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 jarak yang besar, tetapi tidak sebesar jika kita menggunakan 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 menyebutnya RAM.

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

  • Kita meneruskan fungsi min() tambahan.
  • Kami 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 postingan tersebut. Koreksi perataan flex-start adalah untuk menghapus efek peregangan default, sehingga turunan tata letak ini tidak perlu memiliki tinggi yang sama, mereka dapat memiliki tinggi intrinsik alami. Video YouTube memberikan ringkasan singkat tentang penambahan perataan ini.

max-width: 89vw layak dibahas secara singkat dalam postingan ini. Saya akan menunjukkan tata letak dengan dan tanpa gaya yang diterapkan:

Apa yang terjadi? Jika max-width ditentukan, max-width akan memberikan konteks, ukuran eksplisit, atau ukuran pasti untuk algoritma tata letak auto-fit agar mengetahui berapa banyak pengulangan yang dapat dimuat dalam ruang. Meskipun tampaknya jelas bahwa ruangnya "lebar penuh", sesuai dengan spesifikasi petak CSS, ukuran atau ukuran maksimum yang pasti harus diberikan. Saya telah memberikan ukuran maksimum.

Jadi, mengapa 89vw? Karena "berfungsi" untuk tata letak saya. Saya dan beberapa orang lain di Chrome sedang menyelidiki mengapa nilai yang lebih wajar, seperti 100vw, tidak cukup, dan apakah ini sebenarnya bug.

Spasi

Sebagian besar keharmonisan tata letak ini berasal dari palet jarak 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, CSS @nest, dan sintaksis level 5 @media. Berikut contohnya, kumpulan gaya tata letak <main> 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);
    }
  }
}

Petak dengan konten yang berada di tengah, diberi padding sedang secara default (seperti di perangkat seluler). Namun, saat lebih banyak ruang tampilan tersedia, ruang tersebut akan menyebar dengan meningkatkan padding. CSS 2021 terlihat cukup bagus.

Ingat tata letak sebelumnya, "hanya untuk celah"? Berikut adalah versi yang lebih lengkap tentang tampilan mereka 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 tampil ekspresif namun 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 membalik keduanya, dan terang serta 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 secara keseluruhan sebelum kita mempelajari detail sintaksis warna. Namun, karena saya terlalu bersemangat, izinkan saya mengulang sedikit.

LCH?

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

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

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

Bonus dengan lch() di sini adalah bahwa kecerahan berorientasi pada manusia, dan kita dapat merasa senang dengan perubahan %, bahwa perubahan tersebut akan secara perseptual dan konsisten berbeda %. hsl() misalnya, tidak seandalan.

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

CSS saat ini tidak dapat mengakses warna ini sama sekali. Izinkan saya mengulanginya: Kita tidak memiliki akses ke sepertiga warna di sebagian besar monitor modern. Dan ini bukan sekadar warna, tetapi warna paling cerah yang dapat ditampilkan layar. Situs kami terlihat pudar karena hardware monitor berkembang lebih cepat daripada spesifikasi CSS dan penerapan browser.

Lea Verou

Kontrol formulir adaptif dengan color-scheme

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

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 semuanya dalam color-schemeartikel ini oleh Thomas Steiner. Ada banyak hal lain yang bisa didapatkan selain input kotak centang gelap.

CSS accent-color

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

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

Screenshot dari Chromium di Linux dengan kotak centang berwarna merah muda

Pop warna dengan gradien tetap dan fokus dalam

Warna akan paling terlihat saat digunakan dengan hemat, dan salah satu cara yang saya sukai untuk mencapainya adalah melalui interaksi UI yang penuh warna.

Ada banyak lapisan umpan balik 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.
  • Memberikan masukan UI bahwa kolom menerima input.

Untuk memberikan masukan saat elemen berinteraksi, CSS menggunakan :focus-within pseudo class untuk mengubah tampilan berbagai elemen. Mari kita bahas .fieldset-item, 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 fokus dalam:

  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 meluas menjadi lingkaran penuh dan latar belakang diisi dengan gradien tetap cerah.

Rentang kustom

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

<input type="range">

Ada 3 bagian elemen ini yang perlu kita sesuaikan:

  1. Elemen / penampung rentang
  2. Lacak
  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 saya harap pelabelan yang jelas dapat membantu. Gaya lainnya sebagian besar adalah gaya reset, untuk memberikan fondasi yang konsisten untuk 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 "mengungkapkan" warna pengisi yang cerah. Hal ini dilakukan dengan gradien penghentian keras di atas. Gradien transparan hingga persentase pengisian, dan setelah itu menggunakan warna permukaan jalur yang tidak terisi. Di belakang permukaan yang tidak terisi tersebut, ada warna lebar penuh, yang menunggu transparansi untuk menampilkannya.

Gaya pengisian jalur

Desain saya memerlukan JavaScript untuk mempertahankan gaya pengisian. Ada strategi khusus CSS, tetapi strategi tersebut mengharuskan elemen ibu jari memiliki tinggi yang sama dengan jalur, dan saya tidak dapat 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));
  })
})

Saya rasa ini akan memberikan peningkatan visual yang bagus. Penggeser berfungsi dengan baik tanpa JavaScript, properti --track-fill tidak diperlukan, dan tidak akan memiliki gaya pengisian jika tidak ada. Jika JavaScript tersedia, isi properti kustom sambil mengamati perubahan pengguna, menyinkronkan properti kustom dengan nilai.

Berikut adalah postingan bagus di CSS-Tricks oleh Ana Tudor, yang menunjukkan solusi khusus CSS untuk pengisian jalur. Saya juga merasa terinspirasi dengan elemen range ini.

Gaya thumbnail

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 melihat gradien latar belakang tetap yang menyatukan warna dinamis pada thumbnail, jalur, dan elemen SVG terkait. Saya memisahkan gaya untuk interaksi guna membantu mengisolasi teknik yang digunakan untuk sorotan saat mengarahkan kursor:box-shadow

@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 animasi yang mudah dikelola untuk masukan pengguna. Dengan menggunakan bayangan kotak, saya dapat menghindari pemicuan tata letak dengan efek. Saya melakukannya dengan membuat bayangan yang tidak buram dan cocok dengan bentuk lingkaran elemen jempol. Kemudian, saya mengubah dan mentransisikan ukuran penyebarannya saat kursor diarahkan.

Jika saja efek sorotan pada kotak centang semudah ini…

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

<input type="checkbox">

Ada 3 bagian 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 memberi gaya pada sorotan. Jika tidak, sebagian besar adalah hal-hal kecil terkait gaya penulisan dari saya. Saya ingin kursor menjadi penunjuk, saya ingin offset garis luar, kotak centang default terlalu kecil, dan jika accent-colordidukung, bawa kotak centang ini ke dalam skema warna merek.

Label kotak centang

Penting untuk memberikan label pada kotak centang karena 2 alasan. Yang pertama adalah untuk merepresentasikan penggunaan nilai kotak centang, untuk menjawab "aktif atau nonaktif untuk apa?" Kedua adalah untuk UX, pengguna web telah terbiasa berinteraksi dengan kotak centang melalui label terkaitnya.

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, masukkan atribut for yang mengarah ke kotak centang menurut 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 gratis dengan koneksi, sehingga meningkatkan cara interaksi dengan formulir Anda.

Sorotan kotak centang

Saya ingin menjaga 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 untuk menskalakan bayangan ke atas dan ke bawah. Namun, efek tersebut tidak berfungsi di sini karena kotak centang kita berbentuk persegi, dan harus berbentuk persegi.

Saya dapat mencapai efek visual yang sama dengan elemen semu, dan CSS rumit yang sayangnya cukup banyak:

@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 terlampir padanya lebih sulit. Berikut sebelum dan setelah 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 di sini adalah translateZ(-1px). Elemen induk membuat ruang 3D dan elemen turunan semu ini memanfaatkannya dengan menempatkan dirinya sedikit ke belakang dalam ruang z.

Aksesibilitas

Video YouTube tersebut mendemonstrasikan interaksi mouse, keyboard, dan pembaca layar untuk komponen setelan ini dengan sangat baik. Saya akan menyebutkan beberapa detailnya di sini.

Pilihan Elemen HTML

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

Setiap penyimpanan ini berisi petunjuk dan tips untuk alat penjelajahan pengguna. Beberapa elemen memberikan petunjuk interaksi, beberapa menghubungkan interaktivitas, dan beberapa membantu membentuk hierarki aksesibilitas yang dinavigasi 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 kami 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 saat mengarahkan kursor mouse secara bebas dan komentar yang mudah dibaca tentang apa yang dibuat oleh matematika tersebut:

<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 pengujian formulir berjalan dengan baik di mouse, keyboard, pengontrol video game, dan pembaca layar.

JavaScript

Saya telah membahas cara warna pengisian jalur dikelola dari JavaScript, jadi mari kita lihat JavaScript terkait <form> sekarang:

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

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

Setiap kali formulir digunakan dan diubah, konsol mencatat formulir sebagai objek ke dalam tabel agar mudah ditinjau sebelum dikirimkan ke server.

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

Kesimpulan

Sekarang setelah Anda tahu cara saya melakukannya, bagaimana Anda?! Hal ini menghasilkan arsitektur komponen yang 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, kirimkan linknya kepada saya di Twitter, dan saya akan menambahkannya ke bagian Remix komunitas di bawah.

Remix komunitas

  • @tomayac dengan gaya mereka terkait area pengarahan kursor untuk label kotak centang. Versi ini tidak memiliki jeda saat mengarahkan kursor di antara elemen: demo dan sumber.