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

Yayın tarihi: 6 Kasım 2024

Chrome 131'den itibaren <details> ve <summary> öğelerinin yapısını stilize etmek 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 özelliğinin kullanılmasını sağlar ve genişleyen ve daralan kısmı stilize etmek için ::details-content sözde öğesini ekler.

Browser Support

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

Source

<details> öğesinde display ayarını yapma

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 exclusive accordion, 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ı

Bu, <details> öğesinde esnek düzen kullanılarak ve aşağıdaki CSS 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

Beklenmedik bir sonuç verebilecek display değeri inline'dir. Çalışmadığı için değil, HTML ayrıştırıcı sınırlamaları nedeniyle.

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

Etiket adı şu öğelerden 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 öğeler yığınında düğme kapsamında bir p öğesi varsa p öğesini kapatın. Jeton için bir HTML öğesi ekleyin.

Bu nedenle, display: inline ayarını yapmış olsanız bile <details> akışı engelleme yönünde olur.

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

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

Ayrıştırmadan sonra şu hale gelir:

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

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

Bu durumun yalnızca <details> öğesinin <p> öğesinin içine yerleştirilmesi için geçerli olduğunu unutmayın. display: inline simgesini <div> içindeki <details> üzerinde kullanmak sorunsuz çalışır.

::details-content sözde sınıfı

Tarayıcılarda <details> öğesi, Shadow DOM kullanılarak uygulanır. Özette bir <slot> (varsayılan özet alt öğesiyle) ve kalan tüm içeriklerde bir <slot> bulunur. Bu, <summary> öğesi hariç <details> öğesinin tüm alt öğeleri anlamına gelir.

<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> üzerinde daha fazla görüntüleme türü kullanmanın yanı sıra içerik alanı 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 öğeyi kullanabilirsiniz.

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

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

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

<details> öğesi [open] durumundayken yalnızca ::details-content sözde öğesine stil uygulamanız önerilir.

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/oNKMEYv adresinin kaydı

::details-content öğesinin display türü, UA stil sayfasında block olarak ayarlanmıştır. Daha önce ise display: contents olarak ayarlanıyordu. Bu değişiklik, height: 100%'ya dayalı açıklanmış içerikler gibi bazı durumlarda aleyhinize çalışabilir. Bu durum sizin için sorun teşkil ediyorsa display türünü tekrar contents olarak ayarlayarak bu sorunu giderebilirsiniz. Örneğin: details[open]::details-content { display: contents; }.

::details-content sözde öğesine animasyon ekleme

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

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

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

width özelliğinin yanı sıra content-visibility özelliği de taşınmalıdır. Bunun nedeni, User-Agent stil sayfasında tanımlandığı gibi, değerinin açılmamış ve açılmış durum arasında değişmesidir. Bu özellik ayrı ayrı animasyon oluşturulabilen bir özellik olduğundan çalışması için allow-discrete anahtar kelimesini kullanmanız gerekir.

Daha önce paylaşılan özel akordeon demosuna eklenen sonuç şu şekilde olur:

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/XWvBZNo adresinin kaydı

height simgesi de animasyonlu olabilir. height: auto animasyonunu kullanmak için interpolate-size veya calc-size() kullanmanız gerekir. Ayrıca, içeriğin ::details-content sözde öğesinden taşmasını önlemek için overflow: clip 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 */
    }
}

Material UI'ın akordeonundan esinlenerek oluşturulan aşağıdaki demoda kodu çalışırken görebilirsiniz. Her bir <details> öğesinin içeriği güzel bir şekilde animasyonla gösterilir.

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/ExqpQZM kaydı

::details-content desteği olmayan tarayıcılarda bileşen sorunsuz çalışmaya devam eder. Ziyaretçilerin görmediği tek şey animasyondur.

Özellik algılama

CSS'de ::details-content sözde öğesi için özellik algılama desteğini kullanmak üzere 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 anlamak 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 özelliği, <details> öğesinin erişilebilirliğini etkilemez.

En azından Chromium tabanlı tarayıcılarda ve HTML Standardı'na göre, <details> öğesi aranabilir ve tarayıcı, sayfada bulma, ScrollToTextFragment ve öğe parçası gezinme işlemlerine yanıt olarak gizli içeriklerine kaydırmaya çalıştığında otomatik olarak genişler. Bu durum değişmez.

Ancak, özel akordeonları kullanmadan önce kullanıcılar için yararlı mı yoksa zararlı mı olduğunu göz önünde bulundurun. Özel bir akordeon kullanmak içeriğin kapladığı görsel alanı azaltır ancak kullanıcıların tüm bilgileri tüketmek için birçok öğeyi açması gerekebilir. Bu durum, aynı anda birden fazla öğeye bakmak isteyen kullanıcıları rahatsız edebilir.

İşaretçiyi stilize etme

Gecko ve (mevcut) Chromium'un kullandığı bir yaklaşım ile WebKit'in (daha önce Chromium ile paylaşılan) kullandığı bir yaklaşım olmak üzere iki farklı yaklaşım olduğundan liste işaretçisinin stilini belirleme şu anda birlikte çalışılamaz.

Özellik birlikte çalışabilir hale geldiğinde, işaretçinin stilini nasıl belirleyeceğiniz konusunda size daha fazla kontrol olanağı sunmayı amaçlıyoruz.

Daha fazla demo

Son olarak, inceleyebileceğiniz diğer bazı demoları aşağıda bulabilirsiniz. Hepsi ::details-content kullanıyor.

UIKit Accordion

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/rNXrJyQ kaydı

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

Kısmen açılan açıklama widget'ı

Demo

Kayıt

Chrome 131'de https://codepen.io/web-dot-dev/pen/PoMBQmW kaydı

Bu demoda, içeriği ekranda zaten görünür olan, kısmen açılmış bir açıklama widget'ı yer alıyor. Bunu sağlamak için content-visibility her zaman visible olarak ayarlanır. Hesaplama yapıldığından 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 yerleştirilir. Sarmalayıcı div'e padding gibi düzen stilleri uygulanır ve ::details-content sözde öğesi animasyonlu hale getirilir.