Opsi lainnya untuk menata gaya <details>

Dipublikasikan: 6 November 2024

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

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

Dukungan Browser

  • Chrome: 131.
  • Edge: tidak didukung.x
  • Firefox: tidak didukung.
  • Safari: tidak didukung.

Menetapkan display pada elemen <details>

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

Pada contoh berikut, akordeon 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 memiliki 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", " peringkat", "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. Masukkan 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 bertingkat <details> di dalam <p>. Penggunaan display: inline pada <details> di dalam <div> berfungsi dengan baik.

Pseudo ::details-content

Di browser, elemen <details> diterapkan menggunakan Shadow DOM. File ini berisi satu <slot> untuk ringkasan (dengan turunan ringkasan default) dan <slot> untuk semua konten yang tersisa, yang berarti semua turunan dari 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 pseudo ::details-content. Anda dapat menggunakan pseudo ini untuk menata gaya penampung yang menggabungkan 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] di awal.

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

Sebaiknya hanya terapkan gaya ke pseudo ::details-content saat elemen <details> berada 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 di style sheet UA, sedangkan sebelumnya digunakan menjadi display: contents. Perubahan ini mungkin merugikan Anda dalam beberapa kasus, seperti konten yang diungkapkan yang mengandalkan height: 100%. Jika hal ini merupakan masalah bagi Anda, Anda dapat mengatasinya dengan menetapkan jenis display kembali ke contents, seperti ini: details[open]::details-content { display: contents; }.

Menganimasikan pseudo ::details-content

Anda dapat menganimasikan konten elemen <details> saat elemen tersebut diperluas. Pada contoh berikut, lebar dianimasikan dari 0px menjadi 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 sheet gaya User-Agent. Karena properti tersebut adalah properti yang dapat dianimasikan secara terpisah, Anda memerlukan kata kunci allow-discrete agar dapat 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 harus 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 cara kerja kode 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 masih berfungsi dengan baik. Satu-satunya hal yang tidak bisa dilihat pengunjung adalah animasinya.

Deteksi fitur

Untuk menampilkan dukungan deteksi untuk pseudo ::details-content di CSS, gunakan cuplikan berikut.

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

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

Pertimbangan aksesibilitas

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

Seperti sebelumnya, setidaknya di browser berbasis Chromium dan sesuai HTML Standard, elemen <details> dapat ditelusuri dan diperluas secara otomatis saat browser mencoba men-scroll ke konten tersembunyi sebagai respons terhadap find-in-page, ScrollToTextFragment, dan navigasi fragmen elemen. Hal ini tidak berubah.

Namun, sebelum menggunakan akordeon eksklusif, pertimbangkan apakah akordeon tersebut bermanfaat atau berbahaya bagi pengguna. Meskipun penggunaan akordeon eksklusif mengurangi jumlah ruang visual yang digunakan konten, pengguna mungkin harus membuka banyak item untuk menggunakan semua informasi. Hal ini dapat membuat pengguna yang ingin melihat beberapa item secara bersamaan merasa frustrasi.

Bagaimana dengan menata gaya penanda?

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

Setelah fitur ini dapat dioperasikan secara interaktif, 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. Kode ini praktis sama dengan akordeon UI Material yang dibagikan sebelumnya.

Widget pengungkapan yang dibuka sebagian

Demo

Merekam

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

Demo ini menampilkan widget pengungkapan yang terbuka sebagian, yang kontennya sudah terlihat di layar. Untuk mencapai hal ini, content-visibility selalu ditetapkan ke visible. height dianimasikan menggunakan calc-size() karena ada penghitungan 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 memudahkan gaya visual, konten digabungkan dalam div wrapper. Div wrapper mendapatkan gaya tata letak seperti padding yang diterapkan dan pseudo ::details-content dianimasikan.