Studi Kasus: Memasukkan fungsionalitas CSS mutakhir ke dalam komponen navigasi kursus

 – Beragampengetahuan
14 mins read

Studi Kasus: Memasukkan fungsionalitas CSS mutakhir ke dalam komponen navigasi kursus – Beragampengetahuan

Saya bertemu posting hebat ini oleh Jhey Tompkins Navigator:

Ini memecahkan masalah UX yang saya hadapi pada satu proyek, jadi saya menyesuaikannya dengan kebutuhan untuk kursus online – jika Anda lebih suka, gunakan “Navigator kursus” – dan membangunnya. Hari ini, saya akan memisahkannya dan menunjukkan kepada Anda bagaimana semuanya bekerja:

Anda dapat melihat bahwa saya membayangkannya sebagai semacam navigasi yang mungkin Anda temukan dalam sistem manajemen pembelajaran online yang memberi kekuatan pada kursus online. Untuk meringkas peran komponen ini, itu adalah:

  • Tautan ke semua kursus,
  • Gulir halus ke kursus jangkar,
  • Menunjukkan berapa banyak yang ada dalam kursus saat ini,
  • Beralih antara mode terang dan gelap,
  • Duduklah di bagian bawah dan lipat pada gulungan.

Juga, meskipun bukan fitur, kami tidak akan menggunakan JavaScript. Anda mungkin berpikir ini tidak mungkin, tetapi serangkaian fitur CSS yang baru-baru ini dikirimkan membuat semua ini mungkin dengan Vanilla CSS, meskipun menggunakan teknologi pendarahan, yang hanya sepenuhnya didukung oleh Chrome ketika saya menulis posting ini. Jadi, crack membuka versi terbaru dan mari kita lakukan bersama!

Contents

Html

Kami sedang mencari widget pengungkapan ( <details> Elemen) memperbaiki posisi tetap di bagian bawah halaman. Nanti? Kelas kursus (atau beberapa efek) dibungkus <article> Dan idS ada di judul untuk penahan bersamaan. Klik untuk mengungkapkan <summary> Beralih navigasi kursus, yang dibungkus ::details-content Elemen Pseudo. Tautan navigasi ini ke kursus lain, tetapi juga menggulir ke judul di atas dari kursus saat ini.

ini <summary> Berisi label (seperti yang digunakan sebagai tombol cutoff sakelar), nama kursus saat ini, jarak gulir dan sakelar mode gelap.

Apakah kamu sudah bersamaku sejauh ini?

<details>
  
  <!-- The toggle (flex →) -->
  <summary>
    <span><!-- Toggle label --></span>
    <span><!-- Current lesson + % read --></span>
    <label><!-- Light/dark-mode toggle --></label>
  </summary>
  
  <!-- ::details-content -->
    <!-- Course navigation -->
  <!-- /::details-content -->
    
</details>

<article>
  <h1 id="sectionA">Section A</h1>
  <p>...</p>
  <h2 id="sectionB">Section B</h2>
  <p>...</p>
  <h2 id="sectionC">Section C</h2>
  <p>...</p>
</article>

Di tempat

Pertama, kami akan menempatkan pengungkapan dengan posisi tetap sehingga ditetapkan ke bagian bawah halaman:

details {
  position: fixed;
  inset: 24px; /* Use as margin */
  place-self: end center; /* y x */
}

Mengatur Mode Gelap CSS-Hanya (Metode Baru)

Dalam beberapa kasus, Mode Gelap lebih cocok untuk aksesibilitas, terutama untuk keterbacaan konten bentuk panjang, jadi mari kita atur.

Pertama, html. Kami memiliki input kotak centang yang jelek, yang karena bersembunyi hidden Properti, lalu <i> Setelah kami menaburkan beberapa font, ini akan menjadi kotak centang buatan yang lebih baik, lalu <span> Label teks untuk kotak centang. Dan kemudian semua ini dibungkus dalam aktual <label>Bergantung pada <summary>. Kami membungkus konten label <span> Flexbox seperti itu gapBerlaku di antara segalanya.

Secara fungsional, itu beralih ketika label diklik bahkan jika kotak centang disembunyikan. Pada titik ini, lebih baik menjadi ide yang bagus aria-label Pada tag ini, 100% yakin pembaca layar mengumumkan tag, karena tag implisit tidak selalu diambil.

<details>

  <summary>
    
    <!-- ... -->
        
    <label aria-label="Dark mode">
      <input type="checkbox" hidden>
      <i></i>
      <span>Dark mode</span>
    </label>
        
  </summary>
    
  <!-- ... -->
  
</details>

Selanjutnya, kita perlu memasukkan ikon yang benar di dalamnya, tetapi ikuti beberapa logika bersyarat. Alih -alih menggunakan kelas HTML Font Awesome, kami harus menggunakan CSS Override, kami akan menggunakan properti CSS Font Awesome dengan logika aturan kami sebagai berikut:

dalam kasus <i> Elemen diikuti oleh (perhatikan kotak centang Sibling Combiner berikutnya) di mana kami akan menampilkan ikon kotak centang untuk dicentang. Jika kotak centang yang tidak dicentang diikuti, kami akan menampilkan a Tidak dipilih Ikon kotak centang di dalamnya. Bahkan jika Anda tidak menggunakan font itu masih logika aturan yang sama.

/* Copied from Font Awesome’s CSS */
i::before {
  font-style: normal;
  font-family: "Font Awesome 6 Free";
  display: inline-block;
  width: 1.25em; /* Prevents content shift when swapping to differently sized icons by making them all have the same width (this is equivalent to Font Awesome’s .fa-fw class) */
}

/* If followed by a checked checkbox... */
input[type=checkbox]:checked + i::before {
  content: "\f058";
  font-weight: 900;
}

/* If followed by an unchecked checkbox... */
input[type=checkbox]:not(:checked) + i::before {
  content: "\f111";
  font-weight: 400;
}

Kita perlu menerapkan pola pada level root (sekali lagi, menggunakan beberapa logika bersyarat). Jika root :has Centang kotak centang, terapkan color-scheme: dark. Jika akarnya melakukannya :not(:has) ini Tidak dipilih Centang kotak dan kemudian kami terapkan color-scheme: light.

/* If the root has a checked checkbox... */
:root:has(input[type=checkbox]:checked) {
  color-scheme: dark;
}

/* If the root does not have a checked checkbox... */
:root:not(:has(input[type=checkbox]:checked)) {
  color-scheme: light;
}

Jika Anda beralih di kotak centang, UI browser web telah beralih antara skema terang dan gelap. Sekarang, mari kita pastikan demo kami digunakan light-dark() Fungsi CSS, yang memperhitungkan dua nilai- warna mode terang, lalu warna mode gelap. Anda dapat menggunakan fungsi ini alih -alih tipe data warna apa pun (kami bahkan akan menggunakannya dalam gradien kerucut nanti).

Dalam demo, saya menggunakan warna HSL yang sama di seluruh proses, tetapi dengan nilai kecerahan yang berbeda, dan kemudian membalik nilai kecerahan sesuai dengan mode:

color: light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%));
background: light-dark(hsl(var(--hs) 10%), hsl(var(--hs) 90%));

Saya tidak berpikir light-dark() Fungsionalitasnya lebih baik daripada menukar variabel CSS, tapi saya pikir itu juga tidak lebih buruk. Itu semua tergantung pada metode mana yang Anda pilih.

Tunjukkan kemajuan pengguliran

Sekarang mari kita tunjukkan jumlah bacaan yang ditentukan oleh kemajuan pengguliran, pertama -tama, apa yang ingin saya sebut “Pie Progress”, kedua, diikuti oleh persentase teks normal. Ini akan masuk <summary>:

<details>

  <summary>
    
    <!-- ... -->
      
    <span>
      <span id="progress-pie"></span>
      <span>1. LessonA</span>
      <span id="progress-percentage"></span>
    </span>
        
    <!-- ... -->

  </summary>
    
  <!-- ... -->
    
</details>

Yang kita butuhkan adalah menampilkan persentase dan memungkinkan “menghitung” saat posisi gulir berubah. Biasanya, ini langsung di ranah JavaScript. Tapi sekarang kita dapat mendefinisikan properti khusus kita sendiri, kita dapat membuat variabel yang disebut --percentage Formatnya adalah bilangan bulat, default 0. Ini memberikan konteks yang diperlukan untuk CSS untuk membaca dan memasukkan nilai 0 Dan 100ini adalah nilai maksimum yang ingin kami dukung.

Jadi pertama -tama, kami mendefinisikan variabel sebagai properti khusus:

@property --percentage {
  syntax: "<integer>";
  inherits: true;
  initial-value: 0;
}

Lalu kami mendefinisikan animasi di Keyframe sehingga --percentage Diperbarui 0 tiba 100:

@keyframes updatePercentage {
  to {
    --percentage: 100;
  }
}

Akhirnya, kami menerapkan animasi ke elemen root:

:root {
  animation: updatePercentage;
  animation-timeline: scroll();
  counter-reset: percentage var(--percentage);
}

Perhatikan apa yang kami lakukan di sini: ini Animasi yang digerakkan gulirDengan pengaturan animation-timeline tiba scroll()Kami tidak lagi menjalankan animasi berdasarkan timeline dokumen, tetapi berdasarkan posisi pengguliran pengguna. Anda dapat menggali jadwal bergulir di buku tahunan beragampengetahuan.

Karena kami berurusan dengan bilangan bulat, kami dapat menargetkan ::before Elemen semu dan menempatkan nilai persentase di dalamnya content Properti dan sedikit counter() Peretas (simbol persentase kedua):

#progress-percentage::before {
  content: counter(percentage) "%";
  min-width: 40px; display: inline-block; /* Prevents content shift */
}

Kemajuannya sama sederhana. Ini adalah gradien kerucut yang terdiri dari dua warna 0% Dan gulir persentase! Ini berarti Anda membutuhkan --percentage dapat diubah menjadi persentase aktual, tetapi Anda dapat mengubahnya menjadi 1% ((calc(var(--percentage) * 1%))

#progress-pie {
  aspect-ratio: 1;
  background: conic-gradient(hsl(var(--hs) 50%) calc(var(--percentage) * 1%), light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%)) 0%);
  border-radius: 50%; /* Make it a circle */
  width: 17px; /* Same dimensions as the icons */
}

Buat Navigasi Kursus (Bagus)

Sekarang, untuk konten tabel yang berisi daftar bersarang dari bagian -bagian kursus di dalamnya, pertama -tama, beberapa reset. Meskipun ada lebih banyak reset dan keseluruhan baris kode dalam demo, dua reset spesifik sangat penting untuk UX dari komponen ini.

Pertama, berikut adalah contoh cara menandai daftar bersarang:

<details>

  <summary>
    <!-- ... -->
  </summary>
  
  <ol>
    <li class="active">
      <a>LessonA</a>
      <ol>
        <li><a href="#sectionA">SectionA</a></li>
        <li><a href="#sectionB">SectionB</a></li>
        <li><a href="#sectionC">SectionC</a></li>
      </ol>
    </li>
    <li><a>LessonB</a></li>
    <li><a>LessonC</a></li>
  </ol>
    
</details>

Ayo setel ulang daftar jarak di CSS:

ol {
  padding-left: 0;
  list-style-position: inside;
}

padding-left: 0 Pastikan daftar induk dan semua daftar bersarang ada di sisi kiri pengungkapan, dikurangi bantalan apa pun yang mungkin ingin Anda tambahkan. Jangan khawatir tentang lekukan daftar bersarang – kami telah merencanakan beberapa rencana untuk daftar ini. list-style-position: inside memastikan Daftar tag Tangkap, bukan teks, menyebabkan penanda meluap.

Setelah itu, kami menampar color: transparent ada ::markerS Nesting <li> Elemen karena kami tidak perlu memberi nomor judul bagian “kursus”. Kami hanya menggunakan daftar bersarang secara semantik, dan kemudian bersarang nomor seri Daftar terutama karena berbagai jenis tanda daftar (seperti peluru) dapat menyebabkan ketidaksejajaran vertikal antara judul kursus dan judul bagian kursus.

ol ol li::marker {
  color: transparent;
}

Akhirnya, memudahkan pengguna untuk melakukan perjalanan melalui kursus saat ini, kami akan menggelapkan semua item daftar yang tidak terkait dengan kursus saat ini. Ini adalah bentuk menekankan sesuatu untuk menekankan orang lain:

details {
  /* The default color */
  color: light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%));
}

/* <li>s without .active that’re direct descendants of the parent <ol> */
ol:has(ol) > li:not(.active) {
  /* A less intense color */
  color: light-dark(hsl(var(--hs) 80%), hsl(var(--hs) 20%));
}

/* Also */
a {
  color: inherit;
}

Satu hal lagi … tautan jangkar ini menggulir pengguna ke judul tertentu, bukan? Jadi, scroll-behavior: smooth Pada akar, Anda dapat membuat gulungan yang halus di antara mereka. Dan persentase pembacaan pelacak yang kami buat? Ya, ini akan bekerja di sini juga.

:root {
  scroll-behavior: smooth; /* Smooth anchor scrolling */
  scroll-padding-top: 20px; /* A scroll offset, basically */
}

Pengungkapan Transisi

Selanjutnya, mari transisi ::details-content Elemen Pseudo. Secara default, <details> Elemen terbuka dan ditutup saat diklik, tetapi kami ingin transisi yang lancar. Geoff baru -baru ini memberikan pandangan terperinci tentang bagaimana melakukannya <details> elemen, tapi kami memecahnya bersama.

Pertama, kami akan melakukannya height: 0 tiba height: auto. Ini adalah fitur baru di CSS! Pertama kami “pilih” fungsi dari root interpolate-size: allow-keywords`:

:root {
  interpolate-size: allow-keywords;
}

Saya menyarankan pengaturan overflow-y: clip ada details::details-content Untuk mencegah konten meluap, pengungkapan internal dan eksternal:

details::details-content {
  overflow-y: clip;
}

Pilihan lain adalah menggeser konten, Kemudian Fade It (dan sebaliknya), tetapi Anda harus sangat spesifik tentang pengaturan transisi.

Pertama, untuk menyatakan “sebelum” dan “setelah”, Anda membutuhkan dua details[open] Dan details:not([open])karena posisi tersembunyi details Lalu gunakan details[open] Kami tidak diizinkan untuk membalikkan transisi.

Setelah itu, Pat transition Keduanya memiliki nilai keterlambatan transisi yang berbeda untuk membuat fade terjadi setelah pembukaan tetapi sebelum ditutup.

Akhirnya, Anda perlu menentukan properti mana yang telah ditransisikan. Kita bisa saja all Kata kunci di dalamnya, tetapi ini bukan kinerja atau memungkinkan kami untuk menetapkan durasi transisi dan keterlambatan untuk setiap properti. Oleh karena itu, kami akan mencantumkannya secara terpisah dalam daftar yang dipisahkan koma. Harap dicatat bahwa kami berspesialisasi dalam transisi content-visibility Dan gunakan allow-discrete Kata kunci adalah karena merupakan properti diskrit. Itulah mengapa kami memilih interpolate-size: allow-keywords Lebih awal.

details:not([open])::details-content {
  height: 0;
  opacity: 0;
  padding: 0 42px;
  filter: blur(10px);
  border-top: 0 solid light-dark(hsl(var(--hs) 30%), hsl(var(--hs) 70%));
  transition:
    height 300ms 300ms, 
    padding-top 300ms 300ms, 
    padding-bottom 300ms 300ms, 
    content-visibility 300ms 300ms allow-discrete, 
    filter 300ms 0ms, 
    opacity 300ms 0ms;
}

details[open]::details-content {
  height: auto;
  opacity: 1;
  padding: 42px;
  filter: blur(0);
  border-top: 1px solid light-dark(hsl(var(--hs) 30%), hsl(var(--hs) 70%));
  transition: 
    height 300ms 0ms, 
    padding-top 300ms 0ms, 
    padding-bottom 300ms 0ms, 
    content-visibility 300ms 0ms allow-discrete, 
    filter 300ms 300ms, 
    opacity 300ms 300ms;
}

Berikan label dan ikon abstrak

Sebelum judul kursus saat ini, persentase baca dan sakelar mode gelap <summary> Elemen membutuhkan label yang membantu menggambarkan pekerjaannya. Saya mengambil “kursus navigasi” yang termasuk aria-label Katakan hal yang sama sehingga pembaca layar tidak mengumumkan yang lainnya.

<details>
  <summary aria-label="Navigate course">
    <span>
      <i></i>
      <span>Navigate course</span>
    </span>
    
    <!-- ... -->

  </summary>
  
  <!-- ... -->
</details>

Selain itu, abstrak diperoleh display: flex Dengan cara ini kita dapat dengan mudah menggabungkan ketiga bagian gapyang juga menghapus tag default untuk ringkasan, memungkinkan Anda menggunakan tag default Anda sendiri. (Sekali lagi, saya menggunakan font di demo saya sangat bagus.)

i::before {
  width: 1.25em;
  font-style: normal;
  display: inline-block;
  font-family: "Font Awesome 6 Free";
}

details i::before {
  content: "\f0cb"; /* fa-list-ol */
}

details[open] i::before {
  content: "\f00d"; /* fa-xmark */
}


/* For older Safari */
summary::-webkit-details-marker {
   display: none;
}

Terakhir, jika Andacursor: pointer Untuk sebagian besar elemen interaktif, Anda perlu menggunakannya dalam ringkasan dan secara manual memastikan tag kotak centang mewarisi itu, karena tidak akan melakukannya secara otomatis.

summary {
  cursor: pointer;
}

label {
  cursor: inherit;
}

Mekanisme shutdown otomatis diungkapkan

Sedikit javascript tidak akan terluka, apakah itu oke? Saya tahu saya mengatakan itu adalah transaksi yang tidak relevan, tetapi ketika mouse dibiarkan, garis tunggal ini secara otomatis menutup pengungkapan:

document.querySelector("details").addEventListener("mouseleave", e => e.target.removeAttribute("open"));

Menjengkelkan atau bermanfaat? Saya akan membiarkan Anda memutuskan.

Secara otomatis atur skema warna yang disukai

Tentunya berguna untuk mengatur skema warna yang disukai secara otomatis, tetapi jika Anda ingin menghindari JavaScript sebanyak mungkin, saya tidak berpikir pengguna terlalu gila untuk menyediakan fitur ini. Either way, segmen bersyarat berikut dapat memeriksa apakah skema warna pilihan pengguna “gelap” dengan mengevaluasi kueri media CSS yang relevan (prefers-color-scheme: dark) menggunakan window.matchMedia Dan matches. Jika kriteria dipenuhi, centang kotak centang dan kemudian CSS memproses sisanya.

if (window.matchMedia("prefers-color-scheme: dark").matches) {
  document.querySelector("input[type=checkbox]").checked = true;
}

tinjauan

Ini sangat menarik! Kita dapat menggabungkan semua fitur CSS mutakhir ini bersama-sama, yang merupakan berkah, tidak hanya sebuah proyek, tetapi juga kombinasi menjadi komponen. Secara keseluruhan, ini termasuk:

  • Navigator kursus yang menampilkan gulungan halus antara kursus saat ini, semua kursus lain dan judul yang berbeda,
  • Pelacak gulir persentase yang menunjukkan jumlah teks biasa dan gradien kerucut berbunyi… Diagram lingkaran,,,,,
  • Switching mode terang/gelap (dengan beberapa javascript opsional yang mendeteksi skema warna yang disukai), dan adalah
  • Semua ini dikemas ke dalam satu komponen pengungkapan yang mengambang, animasi, asli.

Fitur CSS yang lebih baru yang telah kami perkenalkan dalam prosesnya:

  • Animasi yang digerakkan gulir
  • interpolate-size: allow-keywords Transisi antara 0 Dan auto
  • Gulir halus lewat scroll-behavior: smooth
  • Penggunaan Sihir Mode Gelap light-dark() Fungsi
  • Gunakan satu conic-gradient()
  • pemodelan ::details-content Elemen Pseudo
  • Animasi <details> elemen

Terima kasih Jhey atas inspirasi Anda! Jika Anda tidak mengikuti Bluesky atau Jhey di X, Anda akan melewatkannya. Anda juga dapat melihat karyanya di Codepen, dan dia berbicara tentang beberapa dari mereka di beragampengetahuan.

rencana pengembangan website



metode pengembangan website

jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website

#Studi #Kasus #Memasukkan #fungsionalitas #CSS #mutakhir #dalam #komponen #navigasi #kursus

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *