Stillendirme için daha fazla seçenek <details>

Yayınlanma tarihi: 6 Kasım 2024

Chrome 131'den itibaren <details> ve <summary> öğelerinin yapısını biçimlendirmek için daha fazla seçeneğiniz var. Artık açıklama veya akordeon widget'ları oluştururken bu öğeleri kullanabilirsiniz.

Özellikle Chrome 131'de yapılan değişiklikler, bu öğelerde display mülkünün kullanılmasını sağlar ve genişleyen ve daralan kısmı biçimlendirmek için bir ::details-content sözde öğesi ekler.

Tarayıcı desteği

  • Chrome: 131.
  • Edge: 131.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

<details> öğesinde display ayarlama

Geçmişte <details> öğesinin görüntüleme türünü değiştirmek mümkün değildi. Bu kısıtlama artık kaldırıldı. Örneğin, <details> öğesinde ızgara veya esnek düzenler kullanabilirsiniz.

Aşağıdaki örnekte özel akordeon, yan yana yerleştirilmiş birkaç <details> öğesinden oluşmaktadır. <details> öğelerinden biri genişletildiğinde, içeriği <summary> öğesinin yanına yerleştirilir.

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/VwoBQjY kaydının görüntüsü

Bu, <details> öğesinde aşağıdaki CSS kullanılarak bir esnek düzen kullanılarak elde edilir:

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

grid gibi diğer görüntüleme değerlerine de izin verilir.

display: inline kullanımıyla ilgili not

Beklenenden farklı bir sonuç verebilecek bir display değeri inline'dur. Bu, çalışmadığı için değil, HTML ayrıştırıcı sınırlamaları nedeniyledir.

Bir paragrafın içine <details> öğesi yerleştirildiğinde, HTML ayrıştırıcısı HTML Standardı'nın 13.2.6.4.7 numaralı bölümünde tanımlandığı gibi, açık paragrafı kapatmaya zorlanır:

Etiket adı şulardan biri olan bir başlangıç etiketi: "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"

Açık öğe yığınında düğme kapsamında bir p öğesi varsa p öğesini kapatın. Jeton için bir HTML öğesi ekleyin.

Sonuç olarak, display: inline'ü ayarlamış olsanız bile <details>, blok yönünde akar.

Örneğin, aşağıdaki işaretleme

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

Ayrıştırma işleminden sonra şu şekilde görünür:

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

Bu demoda, Chrome Geliştirici Araçları'nı kullanarak ayrıştırılmış işaretlemeyi inceleyerek bunu kendiniz görebilirsiniz.

Bunun yalnızca <details> öğesinin <p> içine yerleştirilmesi için geçerli olduğunu unutmayın. <div> içinde <details> üzerinde display: inline kullanmak sorunsuzdur.

::details-content sözde

Tarayıcılarda <details> öğesi gölge DOM kullanılarak uygulanır. Özet için bir <slot> (varsayılan özet alt öğesi ile) ve kalan tüm içerik için bir <slot> (<summary> öğesi hariç <details> öğesinin tüm alt öğeleri) içerir.

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

<details>'te daha fazla görüntüleme türü kullanmanın yanı sıra içerik yuvası artık ::details-content sözde öğesi kullanılarak da hedeflenebilir. <details> öğesinin içeriğini sarmalayan kapsayıcıyı biçimlendirmek için bu sözde sınıfı kullanabilirsiniz.

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

Ayarlanan stili yalnızca <details> öğesi açık durumdayken uygulamak için [open] seçicisini öğenin önüne ekleyin.

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

Stilin yalnızca <details> öğesi [open] durumundayken ::details-content sözde sınıfına uygulanması önerilir.

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/oNKMEYv kaydının görüntüsü

::details-content display türü, UA stil sayfasında block olarak ayarlanmıştır. Daha önce display: contents olarak ayarlanıyordu. Bu değişiklik, height: 100% kullanan açıklanan içerikler gibi bazı durumlarda aleyhinize olabilir. Bu durum sizin için soruna yol açıyorsa display türünü contents olarak ayarlayarak bu sorunu giderebilirsiniz. details[open]::details-content { display: contents; }

::details-content taklidi öğesine animasyon ekleme

<details> öğesinin içeriğini genişletilirken animasyonlu hâle getirebilirsiniz. Aşağıdaki örnekte, genişlik 0px değerinden 300px değerine animasyonlu olarak değişir.

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

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

width'ün yanı sıra content-visibility özelliğinin de geçiş yapması gerekir. Bunun nedeni, User-Agent stil sayfasında tanımlandığı gibi değerinin açılmamış ve açılmış durum arasında değişmesidir. Bu mülk ayrı ayrı animasyonlu bir mülk olduğundan, çalışmasını sağlamak için allow-discrete anahtar kelimesine ihtiyacınız vardır.

Daha önce paylaşılan özel akordeon demosuna eklendiğinde sonuç şu olur:

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/XWvBZNo kaydının görüntüsü

height animasyonlu da olabilir. height: auto olarak animasyon oluşturmak için interpolate-size veya calc-size() kullanmanız gerekir. Ayrıca, içeriğin ::details-content sahte metninin dışına taşmasını önlemek için overflow: clip'u uygulayın.

::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 */
    }
}

Kodun işleyişini, Material UI'nin akordeonundan esinlenerek oluşturulan aşağıdaki demoda görebilirsiniz. Her <details> öğesinin içeriği güzel bir şekilde animasyonlu olmalıdır.

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/ExqpQZM kaydının görüntüsü

::details-content desteği olmayan tarayıcılarda bileşen sorunsuz şekilde çalışmaya devam eder. Ziyaretçiler yalnızca animasyonu göremez.

Özellik algılama

CSS'de ::details-content sözde sınıfı için destek olup olmadığını tespit etmek istiyorsanız aşağıdaki snippet'i kullanın.

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

Bu algılamayı, ziyaretçinizin kullandığı tarayıcının ek görüntüleme değerlerini destekleyip desteklemediğini öğrenmek için de kullanabilirsiniz.

Erişilebilirlikle ilgili dikkat edilmesi gereken noktalar

::details-content sözde öğesinin kullanıma sunulması ve görüntüleme türünü değiştirme olanağı, <details> öğesinin erişilebilirliğini etkilemez.

Önceki gibi, en azından Chromium tabanlı tarayıcılarda ve HTML standardına göre <details> öğesi aranabilir durumdadır ve tarayıcı, sayfa içinde arama, ScrollToTextFragment ve öğe parçası gezinme işlemlerine yanıt olarak gizli içeriğine kaydırmaya çalıştığında otomatik olarak genişler. Bu durum değişmez.

Ancak, özel akordeonları kullanmadan önce bunun kullanıcılar için yararlı mı yoksa zararlı mı olduğunu düşünün. Özel akordeon kullanımı, içeriğin kapladığı görsel alanı azaltsa da kullanıcıların tüm bilgileri görmek için birçok öğeyi açması gerekebilir. Bu durum, aynı anda birden fazla öğeye bakmak isteyen kullanıcıları rahatsız edebilir.

İşaretçinin stilini değiştirmek ister misiniz?

Gecko ve (mevcut) Chromium tarafından kullanılan bir yaklaşım ile WebKit tarafından kullanılan (daha önce Chromium ile paylaşılan) farklı iki yaklaşım olduğu için liste işaretçisinin stili şu anda birlikte çalışamaz.

Bu özellik birlikte çalışabilir hale geldiğinde, işaretçiye nasıl stil vereceğiniz konusunda size daha fazla kontrol sunmayı amaçlıyoruz.

Diğer demolar

Son olarak, göz atabileceğiniz bazı diğer demoları burada bulabilirsiniz. Hepsi ::details-content kullanıyor.

UIKit Akordiyon

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/rNXrJyQ kaydının görüntüsü

Bu demo, UIKit Accordion'dan sonra oluşturulmuştur. Kod, daha önce paylaşılan Material UI akordeonuyla neredeyse aynıdır.

Kısmen açılmış açıklama widget'ı

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/PoMBQmW kaydının görüntüsü

Bu demoda, içeriği ekranda görünen kısmen açık bir açıklama widget'ı gösterilmektedir. Bunu sağlamak için content-visibility her zaman visible olarak ayarlanır. Hesaplama olduğu için height, calc-size() kullanılarak animasyonlu hale getirilir.

::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 */
}

Stil oluşturma kolaylığı için içerik bir sarmalayıcı div'e sarılır. Sarmalayıcı div'e padding gibi düzen stilleri uygulanır ve ::details-content sözde öğesi animasyonlu olur.