Lekce 20 - Bootstrap - Navigace
V předešlém cvičení, Řešené úlohy k 17.-19. 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 naučíme stylovat navigaci.
Navigace v Bootstrapu
Kdykoli budeme v naší prezentaci potřebovat navigaci, nemusíme pro styly
chodit daleko. Bootstrap má pro nás připravenou jak samostatnou navigaci, tak
i responzivní navigační lištu s vyjíždějícím menu. V dnešní lekci se
budeme věnovat samostatné navigaci, pro kterou máme k dispozici třídu
.nav
.
Ukažme si nejprve jak komponenta vypadá. K reprezentaci prvků navigace použijeme položky seznamu:
<ul class="nav"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="#">O firmě</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Produkty</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Kontakt</a> </li> </ul>
Výsledek v prohlížeči:
Prvkům navigace přiřazujeme třídu .nav-link
. Pro označení
aktivního odkazu v navigaci používáme třídu .active
a pro
zneaktivnění některých položek používáme .disabled
. Zde
ještě používáme atribut tabindex="-1"
. Jeho hodnota
-1
uživatelům znemožní na tento prvek přejít pomocí
klávesnice.
Element <nav>
a
zarovnání
Kromě seznamu můžeme použít i obyčejné odkazy bez dalších elementů,
které uzavřeme do elementu <nav>
, opět se třídou
.nav
. Rovnou si ukažme i jak položky v navigaci zarovnat
vodorovně. Jelikož celá navigace je postavena na flexboxu, použijeme nám
již známých flexbox utilit. Konkrétně k zarovnání na střed využijeme
třídu .justify-content-center
:
<nav class="nav justify-content-center"> <a class="nav-link active" aria-current="page" href="#">O firmě</a> <a class="nav-link" href="#">Produkty</a> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> <a class="nav-link" href="#">Kontakt</a> </nav>
A výsledek:
Pro zarovnání vpravo bychom použili třídu
.justify-content-end
.
Svislá navigace
Pokud bychom chtěli navigaci nastylovat jako svislou, využijeme třídy
.flex-column
. Svislé navigace se uplatní zejména na menších
displejích, proto můžeme jednoduše navigaci nastylovat i jako vodorovnou na
počítačích a svislou na telefonech. K tomu bychom využili například
třídy .flex-sm-row
:
<ul class="nav flex-column"> <li class="nav-item"> <a class="nav-link" aria-current="page" href="#">O firmě</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Produkty</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Kontakt</a> </li> </ul>
Výsledek:
Opačného chování bychom docílili třídou .flex-sm-column
,
kdy by byla navigace svislá na počítačích a vodorovná na telefonech. Jako
další bychom mohli využít responzivní třídy jako
.text-sm-center
, kterou bychom přiřadili položkám a ta by je na
počítačích centrovala a na mobilech, kde je navigace svislá, by je nechala
zarovnané vlevo jako svislý seznam.
Záložky
Navigaci můžeme jednoduše nastylovat jako záložky přidáním třídy
.nav-tabs
. Je zde podporovaná i třída .active
. K
plné funkcionalitě je třeba nalinkovat i javascriptový plugin
Bootstrapu:
<ul class="nav nav-tabs"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="#">O firmě</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Produkty</a> <div class="dropdown-menu"> <a class="dropdown-item" href="#">Dílna</a> <a class="dropdown-item" href="#">Kuchyně</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Zahrada</a> </div> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Kontakt</a> </li> </ul>
Výsledek v prohlížeči:
Všimněme si, že v jedné záložce je použito i rozbalovací tlačítko Dropdown z lekce Bootstrap - Dropdowns.
Pilulky
Podobně můžeme z odkazů udělat i "pilulky" přidáním třídy
.nav-pills
. Rovnou si ukážeme využití i další třídy,
.nav-fill
, která roztáhne obsah navigace tak, aby vyplnil celou
její šířku. Pro prvky se stejnou šířkou použijeme také
.nav-justified
. Veškerý vodorovný prostor bude obsazen
navigačními odkazy, ale na rozdíl od výše uvedeného .nav-fill
bude každá navigační položka stejně široká.
Pokud bychom k definici navigace využili element <nav>
a
odkazy <a>
, tedy zkrácenou verzi bez seznamu, odkazům již
nemusíme přiřazovat třídu .nav-item
. Ukažme si tento
příklad:
<nav class="nav nav-pills nav-fill"> <a class="nav-link active" aria-current="page" href="#">O firmě</a> <a class="nav-link" href="#">Produkty</a> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> <a class="nav-link" href="#">Kontakt</a> </nav>
V prohlížeči:
Pokud bychom chtěli přidat i Dropdown, postupovali bychom stejně jako u záložek a využili bychom definici pomocí seznamu:
<ul class="nav nav-pills"> <li class="nav-item"> <a class="nav-link active" href="#">O firmě</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Produkty</a> <div class="dropdown-menu"> <a class="dropdown-item" href="#">Dílna</a> <a class="dropdown-item" href="#">Kuchyně</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Zahrada</a> </div> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Ceník</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Kontakt</a> </li> </ul>
V prohlížeči:
Sémantika
Navigaci pomocí seznamu <ul>
musíme přiřazovat
nadřazenému rodičovskému prvku i atribut role="navigation"
pro
hlasové čtečky nebo ji obalit ještě do sémantického elementu
<nav>
. Do atributu role
NEuvádíme hodnoty tablist
, tab
ani
tabpanel
a to i když v navigaci záložky používáme, protože
tyto role slouží pro dynamický obsah, který záložky přepínají.
Dynamické záložky bychom neměli kombinovat s Dropdown tlačítky, protože
může být matoucí, že "aktivační" tlačítko nebude hned zpočátku
viditelné, ale bude schované spolu se záložkou.
Dynamické záložky
Jelikož jsme dynamické záložky již několikrát zmínili, pojďme si ukázat, jak je na navigaci napojit. Nezapomeňme připojit JavaScript:
<ul class="nav nav-tabs" id="navigace" role="tablist"> <li class="nav-item" role="presentation"> <button class="nav-link active" id="o-firme-tab" data-bs-toggle="tab" data-bs-target="#o-firme" role="tab" aria-controls="o-firme" aria-selected="true">O firmě</button> </li> <li class="nav-item"> <button class="nav-link" id="produkty-tab" data-bs-toggle="tab" data-bs-target="#produkty" role="tab" aria-controls="produkty" aria-selected="false">Produkty</button> </li> <li class="nav-item"> <button class="nav-link" id="kontakt-tab" data-bs-toggle="tab" data-bs-target="#kontakt" role="tab" aria-controls="kontakt" aria-selected="false">Kontakt</button> </li> </ul> <div class="tab-content" id="navigace-obsah"> <div class="tab-pane fade show active" id="o-firme" role="tabpanel" aria-labelledby="o-firme-tab">Obsah záložky O firmě...</div> <div class="tab-pane fade" id="produkty" role="tabpanel" aria-labelledby="produkty-tab">Obsah záložky Produkty...</div> <div class="tab-pane fade" id="kontakt" role="tabpanel" aria-labelledby="kontakt-tab">Obsah záložky Kontakt...</div> </div>
Výsledek:
Všimněme si využití tříd .fade
a .show
k
dosažení animace. Následuje zjednodušená verze s elementem
<nav>
:
<nav class="nav nav-tabs" id="navigace" role="tablist"> <button class="nav-item nav-link active" id="o-firme-tab" data-bs-toggle="tab" data-bs-target="#o-firme" role="tab" aria-controls="o-firme" aria-selected="true">O firmě</button> <button class="nav-item nav-link" id="produkty-tab" data-bs-toggle="tab" data-bs-target="#produkty" role="tab" aria-controls="produkty" aria-selected="false">Produkty</button> <button class="nav-item nav-link" id="kontakt-tab" data-bs-toggle="tab" data-bs-target="#kontakt" role="tab" aria-controls="kontakt" aria-selected="false">Kontakt</button> </nav> <div class="tab-content" id="navigace-obsah"> <div class="tab-pane fade show active" id="o-firme" role="tabpanel" aria-labelledby="o-firme-tab">Obsah záložky O firmě...</div> <div class="tab-pane fade" id="produkty" role="tabpanel" aria-labelledby="produkty-tab">Obsah záložky Produkty...</div> <div class="tab-pane fade" id="kontakt" role="tabpanel" aria-labelledby="kontakt-tab">Obsah záložky Kontakt...</div> </div>
Výstup v prohlížeči:
Navigaci s dynamickými záložkami můžeme vytvořit i s pomocí pilulek,
stačí místo třídy .nav-tabs
přiřadit třídu
.nav-pills
. Ideálně bychom měli změnit i hodnotu data atributu
data-bs-toggle
z tab
na pill
. Dokonce
můžeme záložky umístit i vertikálně, tento příklad si ukážeme:
<div class="row"> <div class="col-3"> <div class="nav flex-column nav-pills" id="navigace" role="tablist" aria-orientation="vertical"> <button class="nav-link active" id="o-firme-tab" data-bs-toggle="pill" href="#o-firme" role="tab" aria-controls="o-firme" aria-selected="true">O firmě</button> <button class="nav-link" id="produkty-tab" data-bs-toggle="pill" href="#produkty" role="tab" aria-controls="produkty" aria-selected="false">Produkty</button> <button class="nav-link" id="kontakt-tab" data-bs-toggle="pill" href="#kontakt" role="tab" aria-controls="kontakt" aria-selected="false">Kontakt</button> </div> </div> <div class="col-9"> <div class="tab-content" id="navigace-obsah"> <div class="tab-pane fade show active" id="o-firme" role="tabpanel" aria-labelledby="o-firme-tab">Obsah záložky O firmě...</div> <div class="tab-pane fade" id="produkty" role="tabpanel" aria-labelledby="produkty-tab">Obsah záložky Produkty...</div> <div class="tab-pane fade" id="kontakt" role="tabpanel" aria-labelledby="kontakt-tab">Obsah záložky Kontakt...</div> </div> </div>
Výstup v prohlížeči:
V ukázce je použit responzivní grid, který si podrobně vysvětlíme dále v kurzu.
JavaScript
Jako u většiny komponent, i u navigace můžeme ovlivňovat chování
JavaScript pluginů. Jako vždy můžeme využívat k uzpůsobení chování
buď data atributy nebo k jednotlivým vlastnostem přistupovat pomocí
JavaScriptu. Vlastnosti mají v JavaScriptu stejné názvu jako data atributy
(bez prefixu data-bs-
). Jedná se o data atribut
data-bs-toggle
s hodnotou tab
nebo
pill
.
Přes JavaScript bychom bez data atributů inicializovali záložky jako:
var triggerTabList = [].slice.call(document.querySelectorAll('#myTab a')) triggerTabList.forEach(function (triggerEl) { var tabTrigger = new bootstrap.Tab(triggerEl) triggerEl.addEventListener('click', function (event) { event.preventDefault() tabTrigger.show() }) })
Záložky můžeme také aktivovat individuálně následujícími způsoby:
var triggerEl = document.querySelector('#myTab a[href="#profile"]') bootstrap.Tab.getInstance(triggerEl).show() // Výběr dle jména var triggerFirstTabEl = document.querySelector('#myTab li:first-child a') bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Výběr první záložky
Metody třídy Tab
Třída Tab
v Bootstrapu poskytuje následující metody pro
práci s jejími instancemi:
dispose()
- Tato metoda zničí instanci záložky, uvolní všechny její prostředky a odstraní příslušné posluchače událostí.show()
- Metoda aktivuje a zobrazí záložku spojenou s danou instancí třídyTab
.getInstance(element)
- Statická metoda, která získá instanciTab
spojenou s určeným DOM elementem. Pokud taková instance neexistuje, vrátínull
.getOrCreateInstance(element, config)
- Statická metoda, která získá existující instanciTab
spojenou s DOM elementem nebo vytvoří novou instanci, pokud žádná není nalezena. Volitelný parametrconfig
může být použit pro nastavení instance.
Využití metod v praxi
Zobrazení záložky vypadá následovně:
var someTabTriggerEl = document.querySelector('#someTabTrigger') var tab = new bootstrap.Tab(someTabTriggerEl) tab.show()
Získání instance tab
spojené s DOM elementem:
var triggerEl = document.querySelector('#trigger') var tab = bootstrap.Tab.getInstance(triggerEl)
Získání instance tab
spojené s DOM elementem, nebo
vytvoření nové, pokud nebyla inicializována:
var triggerEl = document.querySelector('#trigger') var tab = bootstrap.Tab.getOrCreateInstance(triggerEl)
K aktivování určité záložky postupujeme následovně.
Pro otevření záložky podle jména:
var triggerEl = document.querySelector('#zalozky a[href="#produkty"]'); var tab = new bootstrap.Tab(triggerEl); tab.show();
Pro otevření první záložky:
var firstTabEl = document.querySelector('#zalozky a:first-child'); var firstTab = new bootstrap.Tab(firstTabEl); firstTab.show();
Pro otevření poslední záložky:
var lastTabEl = document.querySelector('#zalozky a:last-child'); var lastTab = new bootstrap.Tab(lastTabEl); lastTab.show();
Pro otevření konkrétní záložky (zde čtvrté):
var specificTabEl = document.querySelector('#zalozky li:nth-child(4) a'); var specificTab = new bootstrap.Tab(specificTabEl); specificTab.show();
Metody jsou asynchronní a předají řízení dříve, než dojde opravdu k přepnutí záložky! Je to z důvodu probíhající animace. Pokud animace (transition) právě probíhá, budou veškerá volání metod ignorována.
Události
Reagovat můžeme v JavaScriptu i na následující události:
hide.bs.tab
- Událost vyvolaná na aktivní záložce, když je na cestě k deaktivaci kvůli zobrazení nové záložky.show.bs.tab
- Událost vyvolaná na záložce, která se bude zobrazovat, ale ještě než je zobrazena.hidden.bs.tab
- Událost vyvolaná na původně aktivní záložce, ale až po tom, co byla deaktivována a zobrazila se nová záložka.shown.bs.tab
- Událost vyvolaná na nově aktivní záložce po jejím zobrazení.
Reakce na událost bude vypadat například takto:
var tabEl = document.querySelector('button[data-bs-toggle="tab"]') tabEl.addEventListener('shown.bs.tab', function (event) { event.target // Nově aktivovaná záložka event.relatedTarget // Předchozí aktivní záložka })
V příští lekci, Bootstrap - Navigační lišta, si ukážeme, jak napsat responzivní navigační lištu.