Lekce 15 - Bootstrap - Collapse a Accordion
V předešlém cvičení, Řešené úlohy ke 13.-14. lekci Bootstrap CSS frameworku, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
V dnešním tutoriálu CSS frameworku Bootstrap se budeme zabývat sbalovací/rozbalovací komponentou Collapse a její variantou Accordion.
Komponenta Collapse v Bootstrapu
Abychom docílili kvalitního uživatelského zážitku, měli bychom zobrazovat pouze relevantní informace a omezit množství viditelného obsahu, který může uživatele v danou chvíli rušit. K tomuto účelu se často používají záložky, které jsme si již ukazovali v lekci Bootstrap - List groups. Bootstrap však poskytuje ještě univerzálnější komponentu – takzvaný Collapse (možný český překlad je "zhroucení", budeme se však raději držet původního označení).
Komponentu Collapse typicky použijeme k zobrazení nějaké informace, která sice ve většině případů zabírá na stránce místo, ale některým uživatelům chceme přece jen ponechat možnost ji zobrazit. Zobrazení tohoto obsahu můžeme napojit například na tlačítko nebo odkaz. Často se tato funkčnost používá také na takzvané spoilery, kde skrytí obsahu řeší problém vyzrazení (např. odpovědi na hádanku, řešení příkladu nebo části recenze knihy, která odhaluje zápletku).
Jelikož napojení Collapse na tlačítko nebo odkaz vypadá v kódu jinak, ukažme si obě možnosti. Kód níže nechá uživatele zobrazit detailní popis platby za poštovné:
<p>Za poštovné si účtujeme 99 Kč.</p> <p> <a class="btn btn-primary" data-bs-toggle="collapse" href="#ukazka-collapse" role="button" aria-expanded="false" aria-controls="ukazka-collapse"> Více informací </a> <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#ukazka-collapse" aria-expanded="false" aria-controls="ukazka-collapse"> Více informací </button> </p> <div class="collapse" id="ukazka-collapse"> <div class="card card-body"> Poštovné zahrnuje dopravu Českou poštou, balné a službu upozornění naší operátorky na déle nevyzvednutou zásilku. </div> </div>
Nezapomeňme si do stránky nalinkovat Bootstrap JavaScript. Výsledek v prohlížeči vypadá takto:
Jak je u javascriptových Bootstrap komponent zvykem, také zde přiřazujeme
elementu s třídou .collapse jedinečné id. To
následně používáme v selektoru u tlačítek, aby se mohl element skrýt
nebo zobrazit. Tlačítkům/odkazům přiřazujeme data atribut
data-bs-toggle s hodnotou collapse. Selektor uvádíme
v závislosti na použitém elementu buď do atributu href, nebo do
data atributu data-bs-target. Selektor můžeme použít i na
třídu, a tak může odkrývat/skrývat více elementů než jen jeden. CSS
framework Bootstrap doporučuje přidávat další atributy pro hlasové
čtečky. Pro zobrazení dalších informací je zde použita karta z lekce Bootstrap - Karty, ale
samozřejmě se zde může nalézat naprosto libovolný HTML obsah.
Třídy
JavaScript elementu Bootstrap automaticky přiřazuje následující třídy:
.collapse– Obsah je skrytý..collapsing– Obsah se skrývá nebo odkrývá (při animaci)..collapse.show– Obsah je zobrazený.
Accordion
Komponenta Collapse přímo svádí k implementaci "efektu harmoniky". Ten
využijeme u složitých dokumentů, kde nás typicky zajímá jen část obsahu
a zobrazení celého dokumentu by bylo velmi nepřehledné. Otevření jedné
části harmoniky má za následek zavření části jiné. Tento princip se
často používá například při zobrazení smluvních podmínek nebo
zákonů, případně sekcí FAQ a podobně. K vytvoření tohoto efektu
můžeme zvolit dva způsoby, a to buď použití klasických karet, nebo
přímo třídy .accordion. Karty jsou vhodné například pro
nezávislý obsah, zatímco .accordion je lepší pro situace, kdy
chceme mít více souvisejících sekcí, které mohou být zobrazeny nebo
skryty nezávisle na sobě. Začneme s kartami.
Rozbalování/sbalování pomocí karet
Využijeme několik karet, na jejichž hlavičky napojíme komponenty Collapse, které tvoří těla těchto karet:
<h1>Živnostenský zákon</h1> <div id="harmonika" class="accordion" role="tablist"> <div class="card"> <div class="card-header" role="tab" id="hlavicka-1"> <h5 class="mb-0"> <a class="collapsed" data-bs-toggle="collapse" href="#collapse-1" aria-expanded="true" aria-controls="collapse-1"> Část první – Všeobecná ustanovení </a> </h5> </div> <div id="collapse-1" class="collapse show" role="tabpanel" aria-labelledby="hlavicka-1" data-bs-parent="#harmonika"> <div class="card-body"> Tento zákon upravuje podmínky živnostenského podnikání (dále jen "živnost") a kontrolu nad jejich dodržováním. Živností je soustavná činnost provozovaná samostatně, vlastním jménem, na vlastní odpovědnost, za účelem dosažení zisku a za podmínek stanovených tímto zákonem. </div> </div> </div> <div class="card"> <div class="card-header" role="tab" id="hlavicka-2"> <h5 class="mb-0"> <a data-bs-toggle="collapse" href="#collapse-2" aria-expanded="false" aria-controls="collapse-2"> Část druhá – Druhy živností </a> </h5> </div> <div id="collapse-2" class="collapse" role="tabpanel" aria-labelledby="hlavicka-2" data-bs-parent="#harmonika" > <div class="card-body"> Ohlašovacími živnostmi jsou <ul> <li>živnosti řemeslné, je-li podmínkou provozování živnosti odborná způsobilost uvedená v § 21 a 22, <li>živnosti vázané, je-li podmínkou provozování živnosti odborná způsobilost uvedená v příloze č. 2 k tomuto zákonu, není-li dále stanoveno jinak, <li>živnost volná, u které není jako podmínka provozování živnosti odborná způsobilost stanovena. </ul> </div> </div> </div> <div class="card"> <div class="card-header" role="tab" id="hlavicka-3"> <h5 class="mb-0"> <a data-bs-toggle="collapse" href="#collapse-3" aria-expanded="false" aria-controls="collapse-3"> Část třetí – Rozsah živnostenského oprávnění </a> </h5> </div> <div id="collapse-3" class="collapse" role="tabpanel" aria-labelledby="hlavicka-3" data-bs-parent="#harmonika"> <div class="card-body"> Rozsah živnostenského oprávnění (dále jen "rozsah oprávnění") se posuzuje podle předmětu podnikání uvedeného ve výpisu s přihlédnutím k ustanovením této části. Živnostenské oprávnění k výkonu živnosti volné opravňuje k výkonu činností uvedených v příloze č. 4 k tomuto zákonu. </div> </div> </div> </div>
Výsledek:
Kód asi není nutné příliš popisovat, jelikož se jedná o karty, které
jsme si v kurzu již podrobně vysvětlili v lekci Bootstrap - Karty. Hlavičky
karet jsme napojili pomocí unikátních id se selektory na jejich
těla. Díky data atributům a třídám .collapse je vždy
rozbalené jen tělo jedné karty.
Bootstrap nám dokonce umožňuje poskládat si harmoniku ze zcela
vlastních komponent, nemusí se jednat o karty. Díky jeho
flexibilitě můžeme využít jakékoli prvky a přizpůsobit je našim
potřebám, aniž bychom museli používat speciální data atribut
data-children elementu div s harmonikou jako v
dřívějších lekcích. Do atributu umístíme selektor na položky pro
definování vztahů mezi prvky. Důležité je ujistit se, že struktura a
třídy odpovídají požadavkům Bootstrapu pro správnou funkci Accordion:
<body> <h1>Živnostenský zákon</h1> <div id="harmonika" role="tablist"> <div class="polozka"> <a data-bs-toggle="collapse" href="#collapse-1" aria-expanded="true" aria-controls="collapse-1"> Část první – Všeobecná ustanovení </a> <div data-bs-parent="#harmonika" id="collapse-1" class="collapse show" role="tabpanel" aria-labelledby="hlavicka-1" > Tento zákon upravuje podmínky živnostenského podnikání (dále jen "živnost") a kontrolu nad jejich dodržováním. Živností je soustavná činnost provozovaná samostatně, vlastním jménem, na vlastní odpovědnost, za účelem dosažení zisku a za podmínek stanovených tímto zákonem. </div> </div> <div class="polozka"> <a data-bs-toggle="collapse" href="#collapse-2" aria-expanded="false" aria-controls="collapse-2"> Část druhá – Druhy živností </a> <div data-bs-parent="#harmonika" id="collapse-2" class="collapse" role="tabpanel" aria-labelledby="hlavicka-2"> Ohlašovacími živnostmi jsou <ul> <li>živnosti řemeslné, je-li podmínkou provozování živnosti odborná způsobilost uvedená v § 21 a 22, <li>živnosti vázané, je-li podmínkou provozování živnosti odborná způsobilost uvedená v příloze č. 2 k tomuto zákonu, není-li dále stanoveno jinak, <li>živnost volná, u které není jako podmínka provozování živnosti odborná způsobilost stanovena. </ul> </div> </div> <div class="polozka"> <a data-bs-toggle="collapse" href="#collapse-3" aria-expanded="false" aria-controls="collapse-3"> Část třetí – Rozsah živnostenského oprávnění </a> <div data-bs-parent="#harmonika" id="collapse-3" class="collapse" role="tabpanel" aria-labelledby="hlavicka-3"> Rozsah živnostenského oprávnění (dále jen "rozsah oprávnění") se posuzuje podle předmětu podnikání uvedeného ve výpisu s přihlédnutím k ustanovením této části. Živnostenské oprávnění k výkonu živnosti volné opravňuje k výkonu činností uvedených v příloze č. 4 k tomuto zákonu. </div> </div> </div> </body>
Pro podporu hlasových čteček si vždy ověříme správné přiřazení "aria" atributů, aby čtečka dokázala číst jen rozbalené elementy a nabízet podporu rozbalování těch zabalených.
Collapse můžeme použít pro libovolné elementy, stačí je správně napojit, viz první příklad.
Rozbalování/sbalování
pomocí tříd .accordion-
Accordion je zvláštní typ komponenty, která je navržena k zobrazení
skrytého obsahu. Každý prvek Accordionu (označovaný jako
accordion-item) obsahuje hlavičku (accordion-header),
která funguje jako interaktivní prvek pro rozbalení nebo sbalení
přidruženého obsahu (accordion-collapse). Tento typ komponenty
je ideální pro situace, kdy potřebujeme uživatelům poskytnout přístup k
více souvisejícím informacím v kompaktním formátu, například pro FAQ
sekce nebo pro zobrazení různých sekcí obsahu, které uživatel může dle
potřeby rozbalovat:
<div class="accordion" id="accordionPriklad"> <div class="accordion-item"> <h2 class="accordion-header" id="headingOne"> <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> První položka </button> </h2> <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionPriklad"> <div class="accordion-body"> Text první… </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header" id="headingTwo"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> Druhá položka </button> </h2> <div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionPriklad"> <div class="accordion-body"> Text druhý… </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header" id="headingThree"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree"> Třetí položka </button> </h2> <div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionPriklad"> <div class="accordion-body"> Text třetí… </div> </div> </div> </div>
JavaScript
Když potřebujeme reagovat na komponentu Collapse v JavaScriptu, můžeme namísto inicializace pomocí data atributů provést manuální inicializaci:
var collapseElementList = [].slice.call(document.querySelectorAll('.collapse')); var collapseList = collapseElementList.map(function (collapseEl) { return new bootstrap.Collapse(collapseEl); });
Tento kód projde všechny elementy s třídou .collapse ve
stránce a inicializuje na nich Bootstrap Collapse komponentu. Tento přístup
umožňuje lepší kontrolu nad komponentami a jejich chováním v aplikaci.
Vlastnosti
Pro tlačítka jsme používali data atribut data-bs-toggle. V
JavaScriptu můžeme použít stejnojmenné vlastnosti bez prefixu
data-bs-, tedy vlastnosti toggle, které
otevírají/zavírají daný element. Výchozí hodnotou je
true.
Metody
Metody se také u této komponenty volají asynchronně a během animace jsou další volání ignorována. Řízení je předáno těsně po spuštění animace, ale ještě před jejím dokončením.
Collapsible elementy můžeme pomocí JavaScriptu vytvořit jako:
var myCollapsible = document.getElementById('myCollapsible'); var bsCollapse = new bootstrap.Collapse(myCollapsible, { toggle: false });
Tento kód najde element s Id myCollapsible a
inicializuje na něm Collapse komponentu Bootstrapu s nastavením
toggle na false. To znamená, že komponenta nebude
při inicializaci automaticky přepnuta (rozbalena nebo sbalena). Díky tomu
máme nad chováním Collapse komponenty plnou kontrolu.
Na instanci carouselu bsCollapse pak můžeme z JavaScriptu
volat tyto metody:
toggle()– Zviditelní/skryje collapsible element, předá řízení dříve, než dojde k přepnutí.show()– Zviditelní collapsible element, předá řízení dříve, než dojde k přepnutí.hide()– Skryje collapsible element, předá řízení dříve, než dojde k přepnutí.dispose()– Odstraní Collapse.getInstance()– Umožňuje získat instanci sbalení přidruženou k prvku DOM.getOrCreateInstance()– Vrátí instanci sbalení přidruženou k prvku DOM nebo vytvoří novou v případě, že nebyla inicializována.
Události
Můžeme reagovat na následující javascriptové události:
show.bs.collapse– Vyvolá se ihned po zavolání metody s hodnotou"show".shown.bs.collapse– Vyvolá se po dokončení animace zobrazení elementu.hide.bs.collapse– Vyvolá se ihned po zavolání metody s hodnotou"hide".hidden.bs.collapse– Vyvolá se po dokončení animace skrytí elementu.
Na události můžeme zareagovat například takto:
document.getElementById('collapsible-polozka') collapsible-polozka.addEventListener('hidden.bs.collapse', function () { // nějaká reakce… });
V příští lekci, Bootstrap - Dropdowny, se budeme zabývat rozbalovacími tlačítky – dropdowny.

David se informační technologie naučil na