Choć boom na tzw. checkbox-hack chyba minął, nadal jest przydatny. Można rzec, że jego bohaterstwo spowszedniało. Jednym z jego wyczynów była współpraca przy efekcie akordeonu, czyli rozwijanych sekcji, tak aby pozbyć się konkurencji w postaci JavaScript. W dzisiejszym wpisie jeszcze bardziej go pogrążymy.
Harmoniusz bez haka.
Jak się okazuje jest możliwe osiągnięcie efektu akordeonu bez żadnych sztuczek, jest to natywny element HTML. Właściwie dwa elementy, bo tworzą nierozerwalnie jedną sekcję. Są nimi DETAILS oraz SUMMARY w układzie:
<details>
<summary>Nagłówek</summary>
Szczegóły, czyli zawartość sekcji.
</details>
DETAILS pełni rolę kontenera dla sekcji i w nim umieszczamy treść, SUMMARY jest przełącznikiem pozwalającym otwierać i zamykać sekcję. W przeciwieństwie do akrodeonów opartych o JS czy checbox-hack, przełącznik jest dzieckiem kontenera, a nie jego sąsiadem. SUMMARY może być umieszczone w dolnym miejscu DETAILS - na początku, na końcu, nawet w środku treści, pod warunkiem, że nie jest owinięty w dozwolony element (np. DIV). Jeśli jednak zdarzy się ta ostatnia sytuacja, to wtedy sekcja dostanie domyślny przełącznik, natomiast SUMMARY pozostanie w środku treści, nadal jako ten sam tag, lecz pozbawiony swojej funkcjonalności.
DETAILS może posiadać atrybut open, co powoduje, że sekcja domyślnie jest otwarta. Oparty na tych elementach akordeon działa podobnie do akordeonu wykorzystującego checkbox-hack (dokładnie checkbox, a nie radio) - czyli można otworzyć kilka sekcji jednocześnie.
Wygląda i funkcjonuje to tak (ostatnia sekcja ma nadany wspomniany atrybut):
Tuning wizualny harmonii.
Nie daje się nie zauważyć, że domyślna strzałka elementu SUMMARY jest brzydka. Oczywiście jest możliwość jej stylizacji, ale poprzez zastąpienie jej pseudoelementem. Tak więc aby wyłączyć strzałke na Chrome i Safari, stosujemy selektor:
details summary::-webkit-details-marker {
display: none;
}
W przypadku Firefox (ta przeglądarka wyświetla SUMMARY jako element listy):
details summary {
list-style: none;
}
Swoją drogą list‑style‑type dla zamkniętej sekcji na Firefox ma wartość: disclosure‑closed, a dla otwartej: disclosure‑open.
Właśnie ze względu na dwie metody stylizacji strzałki w zależności od przeglądarki, musimy po prostu je wyłączyć i wstawić jeden element możliwy do wyświetlenia na każdej z nich. Pamiętając o atrybucie open, selektory bedą wyglądać tak:
details summary:before {
content: "+";
}
details[open] summary:before {
content: "-";
}
W ten sposób pozbyliśmy się wielgaśnych strzałek:
Jeśli chodzi o możliwość płynnego otwierania sekcji, to jesteśmy ograniczeni tym, że przeglądarka samodzielnie steruje wysokością sekcji (nie widać tego w CSS). Posługując się transition w połączeniu z max-height zobaczymy efekt przy rozwijaniu, bo max-height będzie ograniczał height, natomiast przy zwijaniu, kiedy nadana jest zerowa wysokość (prawie, bo o wysokości SUMMARY), wtedy max-height nie ma władzy nad mniejszym height i efekt przypomina trzaśnięcie drzwiami.
details {
/* przestrzeń dla nagłówka */
min-height: 20px;
/* domyślnie sekcja zwinięta */
max-height: 0;
transition: max-height 1s ease;
overflow: hidden;
}
/* dla rozwiniętej sekcji
ustalamy jakieś stałe,
maksymalne max-height
*/
details[open] {
max-height: 500px;
}
Dmucha czy wciąga?
Co prawda dzisiejszy wpis miał nie tykać JS, ale trzeba wspomnieć o zdarzeniach generowanych przez element DETAILS - akurat tu jest tylko jedno: toggle. Ale w nim nie uzyskamy informacji w jakim stanie jest sekcja, tego musimy dowiedzieć się bezpośrednio z DETAILS, odczytując właściwość open:
details.addEventListener("toggle", function() {
if (this.open) {
alert('otwarty');
} else {
alert('zamkniety');
}
});
W przypadku przeglądarek IE oraz Edge nie ma żadnych problemów z akordeonem, bo... te tagi nie są w ogóle obsługiwanie przez te przeglądarki.
Au revoir!
Przydatne linki:
Tego się nie da odkliknąć! Czyli o przycisku radio i jego wyłączaniu.