Opsi lainnya untuk menata gaya <details>

Dipublikasikan: 6 Nov 2024

Mulai Chrome 131, Anda memiliki lebih banyak opsi untuk menata gaya struktur elemen <details> dan <summary>. Anda kini dapat menggunakan elemen ini saat membuat widget pengungkapan atau akordeon.

Khususnya, perubahan yang diperkenalkan di Chrome 131 memungkinkan penggunaan properti display pada elemen ini, dan menambahkan elemen pseudo ::details-content untuk mengubah gaya bagian yang diperluas dan diciutkan.

Browser Support

  • Chrome: 131.
  • Edge: 131.
  • Firefox: 143.
  • Safari: 18.4.

Source

Menetapkan display pada elemen <details>

Sebelumnya, jenis tampilan elemen <details> tidak dapat diubah. Pembatasan ini kini telah dilonggarkan, sehingga Anda dapat, misalnya, menggunakan tata letak petak atau fleksibel pada elemen <details>.

Dalam contoh berikut, accordion eksklusif terdiri dari beberapa elemen <details> yang ditempatkan berdampingan. Saat meluaskan salah satu elemen <details>, kontennya akan ditempatkan di samping <summary>.

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/VwoBQjY di Chrome 131

Hal ini dicapai dengan menggunakan tata letak fleksibel pada elemen <details>, menggunakan CSS berikut:

details {
  display: flex;
  flex-direction: row;
}

Nilai tampilan lain seperti grid juga diizinkan.

Catatan tentang penggunaan display: inline

Nilai display yang dapat memberikan hasil yang tidak terduga adalah inline. Bukan karena tidak berfungsi, tetapi karena keterbatasan parser HTML.

Saat menempatkan elemen <details> di dalam paragraf, parser HTML akan dipaksa untuk menutup paragraf yang terbuka terlebih dahulu, seperti yang ditentukan di bagian 13.2.6.4.7 Standar HTML:

Tag awal yang nama tagnya adalah salah satu dari: "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul"

Jika tumpukan elemen terbuka memiliki elemen p dalam cakupan tombol, tutup elemen p. Sisipkan elemen HTML untuk token.

Akibatnya, <details> mengalir ke arah blok, terlepas dari apakah Anda telah menetapkan display: inline.

Misalnya, markup berikut

<p>Hello <details>…</details> world</p>

Menjadi seperti ini setelah penguraian:

<p>Hello </p><details>…</details> world<p></p>

Anda dapat melihatnya sendiri di demo ini dengan memeriksa markup yang diuraikan menggunakan Chrome DevTools.

Perhatikan bahwa hal ini hanya berlaku untuk menyusun <details> di dalam <p>. Penggunaan display: inline pada <details> di dalam <div> berfungsi dengan baik.

Pseudokelas ::details-content

Di browser, elemen <details> diimplementasikan menggunakan Shadow DOM. Elemen ini berisi satu <slot> untuk ringkasan (dengan turunan ringkasan default) dan <slot> untuk semua konten yang tersisa, yang berarti semua turunan elemen <details> kecuali elemen <summary>.

<details>
  ↳ #shadow-root (user-agent)
      <slot id="details-summary">
        <summary>Details</summary>
        <!-- The summary goes here -->
      </slot>
      <slot id="details-content">
        <!-- All content goes here -->
      </slot>
</details>

Selain menggunakan lebih banyak jenis tampilan di <details>, slot konten kini dapat ditargetkan menggunakan elemen semu ::details-content. Anda dapat menggunakan pseudo ini untuk menata gaya penampung yang membungkus konten elemen <details>.

details::details-content {
  border: 5px dashed hotpink;
}

Untuk hanya menerapkan gaya yang ditetapkan saat elemen <details> dalam status terbuka, tambahkan pemilih [open] ke elemen tersebut.

[open]::details-content {
  border: 5px dashed hotpink;
}

Sebaiknya hanya terapkan gaya pada pseudo ::details-content saat elemen <details> dalam status [open].

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/oNKMEYv di Chrome 131

Jenis display dari ::details-content ditetapkan ke block dalam stylesheet UA, sedangkan sebelumnya menggunakan display: contents. Perubahan ini mungkin merugikan Anda dalam beberapa kasus, seperti konten yang diungkapkan yang mengandalkan height: 100%. Jika hal ini menjadi masalah bagi Anda, Anda dapat mengatasinya dengan menyetel kembali jenis display ke contents, seperti berikut: details[open]::details-content { display: contents; }.

Menganimasikan pseudo ::details-content

Anda dapat menganimasikan konten elemen <details> saat meluas. Dalam contoh berikut, lebar dianimasikan dari 0px ke 300px.

::details-content {
  transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
  width: 0;
}

[open]::details-content {
  width: 300px;
}

Selain mentransisikan width, properti content-visibility juga perlu ditransisikan. Hal ini karena nilainya berubah antara status belum dibuka dan dibuka, seperti yang ditentukan dalam lembar gaya User-Agent. Karena properti tersebut adalah properti yang dapat dianimasikan secara diskret, Anda memerlukan kata kunci allow-discrete agar berfungsi.

Ditambahkan ke demo akordeon eksklusif yang dibagikan sebelumnya, hasilnya menjadi seperti ini:

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/XWvBZNo di Chrome 131

height juga dapat dianimasikan. Untuk menganimasikan ke height: auto, Anda perlu menggunakan interpolate-size atau calc-size(). Selain itu, untuk mencegah konten keluar dari pseudo ::details-content, terapkan overflow: clip ke konten tersebut.

::details-content {
    transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
    height: 0;
    overflow: clip;
}

/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }

    [open]::details-content {
        height: auto;
    }
}

/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
    [open]::details-content {
        height: 150px;
        overflow-y: scroll; /* In case the contents should be taller than 150px */
    }
}

Anda dapat melihat kode ini beroperasi dalam demo berikut, yang terinspirasi oleh akordeon Material UI. Konten setiap elemen <details> dianimasikan dengan baik.

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/ExqpQZM di Chrome 131

Di browser yang tidak mendukung ::details-content, komponen tetap berfungsi dengan baik. Satu-satunya hal yang tidak dapat dilihat pengunjung adalah animasinya.

Deteksi fitur

Untuk mendeteksi dukungan fitur untuk pseudo ::details-content di CSS, gunakan cuplikan berikut.

@supports selector(::details-content) {
  
}

Anda juga dapat menggunakan deteksi ini sebagai pemeriksaan untuk mengetahui apakah browser yang digunakan pengunjung Anda mendukung nilai tampilan tambahan atau tidak.

Pertimbangan aksesibilitas

Pengenalan elemen semu ::details-content dan kemampuan untuk mengubah jenis tampilan tidak berdampak pada aksesibilitas elemen <details>.

Seperti sebelumnya, setidaknya di browser berbasis Chromium dan sesuai dengan Standar HTML, elemen <details> dapat ditelusuri dan otomatis diperluas saat browser mencoba men-scroll ke konten tersembunyinya sebagai respons terhadap penelusuran dalam halaman, ScrollToTextFragment, dan navigasi fragmen elemen. Hal ini tidak berubah.

Namun, sebelum menggunakan akordeon eksklusif, pertimbangkan apakah akordeon tersebut bermanfaat atau merugikan pengguna. Meskipun menggunakan akordeon eksklusif mengurangi jumlah ruang visual yang ditempati konten, pengguna mungkin harus membuka banyak item untuk menggunakan semua informasi. Hal ini dapat membuat frustrasi pengguna yang ingin melihat beberapa item sekaligus.

Bagaimana cara menata gaya penanda?

Saat ini, penataan gaya penanda daftar tidak dapat dioperasikan karena ada dua pendekatan yang berbeda, satu dilakukan oleh Gecko dan (saat ini) Chromium, dan yang lainnya dilakukan oleh WebKit (yang sebelumnya dibagikan dengan Chromium).

Setelah fitur ini dapat beroperasi dengan baik, tujuan kami adalah memberi Anda kontrol yang lebih baik atas cara menata gaya penanda.

Demo lainnya

Sebagai penutup, berikut beberapa demo lainnya yang dapat Anda lihat. Semuanya menggunakan ::details-content.

Akordeon UIKit

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/rNXrJyQ di Chrome 131

Demo ini dibuat setelah Accordion UIKit. Kodenya hampir sama dengan akordeon Material UI yang dibagikan sebelumnya.

Widget pengungkapan terbuka sebagian

Demo

Merekam

Perekaman https://codepen.io/web-dot-dev/pen/PoMBQmW di Chrome 131

Demo ini menampilkan widget pengungkapan yang terbuka sebagian dan kontennya sudah terlihat di layar. Untuk mencapai hal ini, content-visibility selalu disetel ke visible. height dianimasikan menggunakan calc-size() karena ada perhitungan yang terlibat.

::details-content {
  content-visibility: visible; /* Make it always visible */
    
  transition: height 0.5s ease;
  height: 150px;
  overflow: clip;
}

[open]::details-content {
  height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}

Untuk kemudahan penataan gaya, konten dibungkus dalam div wrapper. Div wrapper mendapatkan gaya tata letak seperti padding yang diterapkan dan pseudo ::details-content dianimasikan.