Samozřejmě můžete použít DIV
nebo SPAN
a připlácnout k němu nějakou třídu, přes kterou ho naformátujete. Nebo můžete změnit tag STRONG
, aby byl podtržený místo tučný. Nebo můžete použít ARIA role, a dodávat význam tam, kde není potřeba. Ale nešlo by to trochu chytřeji s využitím všech těch úžasných novinek, které přináší HTML5? (Nebo dokonce HTML4?)
Formátovací tagy
Původní HTML tagy se zaměřovali na formát, takže existovali tagy jako FONT
(v HTML5 již není podporován), B
a I
(nejsou doporučovány), EM
a STRONG
(ty jsou doporučovány, i když rozdíl oproti B
a I
často není jasně vysvětlen), a další.
Samozřejmě je můžete používat (vyjma níže uvedených) pro označení a formátování blíže neurčeného textu, ale ve většině případů je možno použít lepší tagy, které místo konkrétního formátu zachytí význam daného textu a vy nebudete muset přemýšlet o tom, jestli citát má být napsán kurzívou nebo jiným písmem, nebo zda cena zboží má být tučná nebo podtržená.
Pro shrnutí (a vysvětlení anglických výrazů pro lepší pochopení):
B
označuje zvýrazněný text, bez dalšího upřesnění, proč je zvýrazněný.- Např. když chcete zdůraznit něčí jméno nebo důležité slovo.
- Anglický výraz bold se často překládá jako tučný (tlustý) ale také znamená výrazný, statečný, sebevědomý nebo snadno viditelný – což je případ právě tučného písma.
I
označuje kurzívu, protože chcete kurzívu.- Např. chcete označit jméno jiné firmy.
- Vychází z výrazu italic (anglicky doslova italské, protože ho prvně použili v Itálii v roce 1501).
- Český výraz kurzíva (z latinského cursivus, tedy běžný, od currere = běhat) označuje písmo, které má spojená písmena, aby se snadněji psalo rukou – označovat tak tiskařské nakloněné písmo je tedy nesprávné a měl by se spíše používat počeštěný výraz italika.
EM
označuje zvýrazněný text, který má nějaký speciální význam.- Např. neznámý výraz, který později objasníte.
- Vychází z anglického emphasize (doslova zdůraznit)
STRONG
označuje důležitý text, na který je potřeba dát si pozor.- Např. upozornění nebo varování.
- Výraz strong se může (chybně) překládat jako „silný“ (připomínaje český výraz tlustý, který označuje tučné písmo), ale tag by se měl překládat jako vážný nebo důležitý (např. strong warning = důležité varování)
MARK
označuje text, který se nějak týká toho, co uživatel zrovna dělá nebo co je důležité v kontextu stránky.- Např. na stránce se slevami takto označíte zvýhodněné ceny.
- Slouží také k označení hledaného výrazu v textu.
- Slovo mark v angličtině doslova znamená nakreslit čáru nebo jiný symbol pro označení pozice hledané věci.
SMALL
označuje méně důležitý text nebo poznámku.- Např. že cena je bez DPH.
- Anglické small může označovat malé číslo nebo malou velikost (např. oblečení) tak i něco méně důležitého (např. small changes = nedůležité změny).
U
označuje podtržení, tedy text, který je potřeba označit, ale nemá vyšší (EM
,STRONG
, …) ani nižší (SMALL
) prioritu.- V HTML5 lze použít např. pro označení gramatické nebo matematické chyby (podržení vlnovkou)
- Z anglického underline, doslova čára pod. Výraz lze ale ve větě použít podobně jako emphesize a nemusí tedy označovat skutečnou čáru, ale jen něco očividného.
SUB
(dolní) aSUP
(horní) označuje dolní a horní index.- Např. pro matematické zápisy nebo poznámky pod čarou.
- Tagy
,FONT
,STRIKE
aBIG
jsou v HTML5 zakázány (nejsou podporovány).CENTER
Části stránky
Pro označení různých částí stránky slouží následující tagy:
MAIN
označuje hlavní část stránky, kde uživatel najde obsah. Musí být na stránce jen jeden a nesmí být uvnitřARTICLE
,ASIDE
,HEADER
,FOOTER
neboNAV
(ale může být uvnitřSECTION
).HEADER
uvnitřBODY
neboMAIN
označuje hlavičku stránky, tedy tu část, kde je logo, jméno stránky, příp. rychlé menuFOOTER
uvnitřBODY
neboMAIN
označuje konec stránky, obvykle obsahující odkazy jinam, kontakt autora, apod.SECTION
označuje části stránky, které obsahují odlišné informace.- Např. část pro firmy, soukromé osoby, novináře, apod.
ARTICLE
označuje blok obsahující hlavní text stránky nebo sekce (navíc plní stejnou funkci jakoSECTION
).ASIDE
pak označuje text, který hlavní článek doplňuje nebo rozšiřuje (navíc plní stejnou funkci jakoSECTION
) .- Specifikace HTML 5.1 umožňuje použít
HEADER
aFOOTER
uvnitř sekcí (SECTION
,ARTICLE
,ASIDE
, apod.). Dokonce lze vnořit do sebe např.SECTION
–HEADER
–ASIDE
–HEADER
. TagyMENU
označuje menu se seznamem odkazů. Ty by měli být značeny tagemMENUITEM
.MENU
aMENUITEM
jsou z HTML5 vyloučeny. Pro menu je potřeba použít tagNAV.
- Specifikace HTML 5.1 přidává zpět tagy
MENU
aMENUITEM
, ale pouze pro definici akcí pro kontextové menu prohlížeče (viz dále). TagMENU
musí mít atributtype=context
aMENUITEM
musí mít atributtype
s hodnotamicommand
,checkbox
neboradio
(hodnotacommand
je výchozí a může být vynechána). NAV
označuje navigační menu nebo část stránky obsahující navigační odkazy (např. sitemap či odkazy v patičce).- Navigace musí obsahovat obyčejné odkazy
A
. Případně lze menu doplnit oUL-LI
strukturu. - Navigace neslouží jako obal libovolného odkazu v textu ale jako samostatný blok odkazů nesouvisejících s obsahem stránky nebo článku (pokud je uvedena v
BODY
,MAIN
,HEADER
neboFOOTER
). - Pokud je
NAV
uveden uvnitř sekce (ARTICLE
,ASIDE
, apod.), týká se navigace dané sekce (např. obsah se seznam nadpisů v článku); pro přístupnost by taková navigace měla být označena pomocí aria-labeledby, aby bylo jasné, které části stránky se týká.
- Navigace musí obsahovat obyčejné odkazy
FIGURE
označuje část, která obsahuje různé spolu související prvky. Titulek by měl být označen tagemFIGCAPTION
.- Např. blok s obrázkem a jeho popisem, datem a místem pořízení, apod.
- Ve formulářích může označovat blok s
input
em, jeholabel
em, chybovou hláškou, atd. Figure
může obsahovat více obrázků, videa, reklamy, atd. Může obsahovat i další vnořenéfigure
.FIGCAPTION
může obsahovat další tagy jako jeHx
,P
, atd.
ADDRESS
obsahuje kontaktní informace související s článkem nebo stránkou.- Nejedná se o poštovní adresu, kterou chcete uvést, ale nesouvisí s textem nebo jeho autorem.
- Může obsahovat údaje jako jméno, telefon, email, ale i poštovní adresu (pokud dává v kontextu smysl) buď na autora článku, majitele autorských práv, nebo někoho, kdo je za text zodpovědný (např. HR nebo PR oddělení).
- Adresa se vždy váže k textu v tagu
ARTICLE
, nebo k celé stránce (pokud není uvnitřARTICLE
).
TIME
obsahuje časové informace (jak čas tak i datum) související s článkem nebo stránkou.- Opět nejde o označení času uvedeného v textu.
Citace
Pokud uvádíte text z jiné stránky, knihy či jiného dokumentu, můžete použít tagy Q
(quote), BLOCKQUOTE
a CITE
.
Tag Q
je určen pro inline text, kdy například do vaší věty zahrnete citát z jiného zdroje. Naopak BLOCKQUOTE
, jak název napovídá, slouží jako blokový prvek, kdy uvádíte celou větu nebo odstavec z jiného dokumentu. Oba mohou mít atribut cite
, který by měl obsahovat URL adresu (či jakýkoliv jiný zdroj, např. jméno knihy), odkud jste čerpali. Pokud do textu uvedete i jméno autora nebo díla, můžete k tomu použít tag CITE
.
Jaký je rozdíl mezi I a EM?
Slovy <cite>Shakespeara</cite>:
<q>
Voněla by snad růže jinak,
kdyby nebyla růží zvána?
<cite>(Romeo a Julie)</cite>
</q>.
Takže je používejte jak jen chcete.
<cite>Cimrman</cite> by na to řekl:
<blockquote
cite="http://citaty.net/autori/jara-cimrman/">
Do hospody s umytýma nohama.
</blockquote>
Úpravy textu
Pro různé blogy a novinové servery, které se o své články starají a upravují je podle současné situace, se hodí tagy DEL
, INS
a S
. Lze je ale také použít např. pro seznamy, kde chcete označit již neplatné nebo nově přidané položky (seznam úkolů, kroky návodu, apod.).
Tag S
(jméno pochází ze strike-through, protože v HTML4 jednoduše označoval přeškrtnutí, ale v HTML5 má jiný význam – jméno zůstalo pro zapamatovatelnost) slouží pro označení textu, který již za současné situace neplatí, ale stále je dobré vědět, jak to dříve fungovalo. Naopak tag DEL
(„deleted“ = smazáno) označuje text, který byl vymazán kvůli tomu, že je chybný.
Tag INS
(„inserted“ = vloženo) by pak měl následovat za S
nebo DEL
a označovat text, který byl nově vložen a nahrazuje původní text. Samozřejmě tagy S
, DEL
a INS
je možno použít i samostatně, pokud mažete text, který není potřeba nahradit, nebo naopak vkládáte text, který něco doplňuje, ale neruší platnost stávajícího textu.
<!-- Starý text je opraven novým,
ale ten nemění fakt, že dříve to tak
fungovalo a bylo to správně, proto tag S -->
<s>Tag B označuje tučný text.</s>
<ins>V HTML5 používejte EM pro zvýraznění,
STRONG pro zdůraznění a MARK pro označení.</ins>
<!-- Zde naopak nový text opravuje starý,
který nebyl platný ani v době zápisu,
ale byl v textu ponechán, aby si čtenář uvědomil,
že původní text obsahoval chybu,
takže tag DEL -->
Flexbox je plně podporován ve Firefoxu od verze <del>20</del><ins>28 (předchozí verze mají jen částečnou
nebo experimentální podporu)</ins>.
<!-- Zde se jedná o starou informaci,
protože IE8 již není podporováno,
ale je dobré stále vědět, že byla
nějaká omezení, proto tag S.
Není ale již potřeba uvádět,
že od IE9 je podporován (vyplývá to z textu),
takže není potřeba uvádět INS. -->
Tag MARK podporují všechny prohlížeče
<s>kromě IE8</s>.
Všechy 3 tagy mohou obsahovat atribut cite
s URL odkazující na důvod změny (zde by to mohl být třeba http://caniuse.com pro příslušné vlastnosti).
Také mohou obsahovat atribut timestamp
s časem, kdy ke změně došlo, pokud je to relevantní. Čas by měl být ve formátu yyyy-mm-ddThh:mm:ss+zz:zz
(tedy datum a čas vč. časové zóny; místo T
lze uvést mezeru a odděluje datum a čas). Pokud nechcete uvádět přesný čas, můžete použít atribut datetime
a uvést datum a/nebo čas s libovolnou přesností.
Rozšiřující informace
Pro rozbalovací prvek, který po kliknutí zobrazí další informace slouží kombinace prvků DETAILS
a SUMMARY
. Tag DETAILS
označuje kontejner, který obsahuje všechny informace. Tag SUMMARY
pak označuje text, který bude (jako jediný) vidět a ostatní obsah v DETAILS
se skryje. Po kliknutí na SUMMARY
se pak zobrazí i zbytek DETAILS
. Nyní jsou již oba podporované ve všech prohlížečích (v Chromium od 2014, v Safari od 2018 a Edge od 2020 po přechodu na Chromium).
Alternativně můžete použít tag DIALOG
, jehož obsah bude také skryt. V okamžiku, kdy prvku nastavíte atribut open
, zobrazí se jeho obsah uprostřed stránky. V Chromium je od roku 2014, a od března 2022 ho podporují všechny ostatní prohlížeče.
<details>
<summary>Klikni pro více informací</summary>
Více informací (zobrazí se po kliku)...
</details>
<dialog>
Tohle nebude vidět.
</dialog>
<dialog open>
Tohle bude vidět uprostřed stránky.
</dialog>
Poznámka: tagy DETAILS
a SUMMARY
byly přesunuty do specifikace HTML 5.1, protože pouze Chrome ji podporoval jako součást HTML5.
Kód
Původní tag TT
(„TeleType“ = telegrafický zápis) je v HTML5 zakázán. Místo něj lze použít tagy podle toho, co chcete zobrazit.
- Tag
CODE
je určen pro zdrojový kód (např. tak, jako se to používá zde). - Pokud v textu odkazujete na konkrétní proměnnou nebo funkci, k označení slouží tag
VAR
(variable). - Pokud chcete uvést, co má uživatel zadat do systémové konzole nebo jakou klávesu má stisknout, můžete použít tag
KBD
(keyboard input = vstup z klávesnice). - Pro zápis toho, co se v konzoly, v programu nebo v souboru vypíše, pak slouží tag
SAMP
(sample = ukázka).
Samozřejmě v HTML5 je možno použít tag PRE
, který se od všech ostatních liší tím, že zobrazuje mezery, tabulátory a odřádkování přesně tak, jak jsou zapsány v HTML souboru.
Kromě PRE
jsou všechny tyto tagy primárně inlinové, ale lze je pomocí CSS změnit na blokové či jinak formátovat.
Formuláře
Formátováním formulářů se zabývá článek Méně známé typy inputů.
V HTML5 jsou pro seskupování prvků formuláře nejvhodnější tagy FIELDSET
(rámeček s titulkem LEGEND
) nebo FIGURE
(skupina souvisejících prvků).
Verze HTML 5.1 přidává JS metodu form.checkValidity()
, pomocí které možné vyvolat validaci formuláře programově. Metoda označí nevalidní prvky a následně vrátí TRUE
nebo FALSE
, podle toho, zda validace uspěla či nikoliv.
Tabulka
Tabulka má celou řadu tagů, které slouží pro její formátování:
TABLE
označuje celou tabulku.TBODY
obsahuje řádky (TR
) a sloupce (TD
) s daty.THEAD
obsahuje řádky (TR
) a sloupce (TH
) s popisy sloupců vTBODY
.TFOOT
obsahuje řádky (TR
) a sloupce (TD
) se součty nebo jinými souhrnnými informacemi.TH
lze také použít pro popis řádky (první buňka řádky).CAPTION
může obsahovat popis tabulky- Uvádí se uvnitř tabulky a bude zobrazen nad nebo pod tabulkou přes celou její šířku.
COLGROUP
může definovat hromadný formát pro celý sloupec (stejně jakoTR
definuje formát pro řádek).- Měl by obsahovat tag
COL
pro každýTD
v řádkáchTR
.COL
nemá žádný obsah, jen definujeID
,CLASS
neboSTYLE
pro celý sloupec.COL
může obsahovat atributspan
, pokud zastupuje více sloupců.
- Měl by obsahovat tag
Skryté obrázky
Specifikace HTML 5.1 umožňuje legálně používat skryté obrázky, jako jsou trackovací pixely. Takový obrázek musí mít atributy WIDTH
a HEIGHT
nastaveny na nulu a atribut ALT
musí být prázdný:
<img src="//ad.com/track/pixel" width=0 height=0 alt="">
Kontextové menu
Tato možnost byla plánována v HTML4, ale jelikož ji v té době podporoval pouze Firefox, byla z HTML5 odebrána. Nová specifikace HTML 5.1 ji znovu přidává s tím, že výrazně omezuje možnosti použití.
Pomocí tagu MENU můžete nadefinovat položky, které se zobrazí v kontextovém menu prohlížeče, když na něj kliknete pravým tlačítkem (resp. jiným způsobem, který na daném OS vyvolá kontextovou nabídku).
Podle specifikace HTML 5.1 musí mít tag MENU
atribut type=context
. Jakékoliv jiné použití známé z HTML4 (např. type=toolbar
) není možné. S konkrétním prvkem pak menu svážete atributem contextmenu
, do kterého uvede id daného menu (tudíž MENU
musí mít také atribut id
, jinak nejde použít a nedává smysl).
Příklad použití – stažení obrázku v plném rozlišení po kliknutí na náhled (thumbnail):
<img src="img_th.jpg" contextmenu=pictureMenu>
<menu type=context id=pictureMenu>
<menuitem label="Download" onclick="download(this)"></menuitem>
</menu>
Po kliknutí na obrázek z příkladu se zobrazí standardní kontextové menu prohlížeče, ale prohlížeč, který to podporuje (zatím jen Firefox), přidá do menu položku „Download„, která po kliknutí vyvolá JS funkci download()
.
Kontextové menu může obsahovat i podmenu, které vytvoříte vložením vnořeného tagu MENU:
<img src="img_th.jpg" contextmenu=pictureMenu>
<menu type=context id=pictureMenu>
<menuitem label="Download" onclick="download(this)"></menuitem>
<menu type=context label="Zoom">
<menuitem onclick="zoomin(this)">Zoom in</menuitem>
<menuitem onclick="zoomout(this)">Zoom out</menuitem>
<menu>
</menu>
Tento příklad přidá kromě položky Download také submenu Zoom, které obsahuje příkazy pro přiblížení a oddálení.
Všimněte si, že popisek položek menu můžete nadefinovat v atributu label
, nebo v případě MENUITEM
jako obsah tagu.
Položka MENUITEM
bez atributu type
má výchozí typ command
, který říká, že po kliknutí pouze vyvolá onlick
. Položky ale mohou mít i typy checkbox
nebo radio
a v tom případě se pak chovají stejně jako formulářový checkbox
nebo radio
(radia se seskupují podle atributu name
). Stav můžete nastavit nebo přečíst z atributu checked
.
Šablony (Templates)
HTML5 nabízí možnost uložit do HTML kódu části, které nebudou při renderování použity a vloženy do DOMu. Místo toho se uloží odděleně a lze je použít později z Javascriptu pro změnu obsahu nebo po načtění nového obsahu.
Tag template
musí mít atribut id
pomocí něhož ho můžete najít (resp. nemusí, ale hledat ho jiným způsobem je pomalejší). Tag template
je v moderních prohlížečích skrytý a ani se nerenderuje (tzn. pokud obsahuje HTML tagy, v DOM inspektoru ho uvidíte jako text podobně jako komentář).
<body>
<h1>Titulek stránky</h1>
<template id=myArticle>
<article>
<h2>Nadpis článku</h2>
<p>Text článku</p>
</article>
</template>
<p>Toto je první odstravec stránky</p>
...
Pokud nemáte jistotu, že stránka nebude zobrazena ve starších prohlížečích, doporučuji do CSS přidat podmínku, která tagy template
skryje:
template { display: none; }
Template můžete načíst z JS a vložit do stránky podle potřeby:
var template = document
.getElementById('myArticle');
var article = template.content || template;
var clone = article.cloneNode(true);
clone.getElementsByTagName('h2')[0]
.innerHTML = response.json.title;
clone.getElementsByTagName('p')[0]
.innerHTML = response.json.body;
body.appendChild(clone);
V kódu si všimněte, že nejprve najdeme template podle jeho ID a následně ho necháme převést na HTML pomocí template.content
. Pro starší prohlížeče, které template
neznají a obsah již vyrenderovali pak stačí použít přímo daný kontejner.
Vlastnost content
vyrenderuje prvky v šabloně, ale mimo aktivní DOM. Pro použití prvků a následné vložení do DOM musíme na vytvořený prvek použít article.cloneNode(true)
nebo document.importNode(article, true)
– oba postupy vytvoří kopii kontejneru a všech jeho vnořených prvků v aktivním DOM.
Následně již můžeme obsah prvků upravit podle potřeby a vložit do DOM (v kódu na konec body
).
Stínový DOM a sloty
Data do template nemusíte vkládat jen přes JS (typicky načtené v JSON přes AJAX), ale můžete je nadefnovat v HTML (v jakémsi XML zápisu). Tato možnost je ale podporována jen ve Firefox 63+, Chrome 53+, Edge 79+, Safari 10.3+ a Opera 40+ (dříve byste pro IE a starší Edge museli použít polyfill, ale dnes (2022) už asi není potřeba s nimi počítat).
Pointa stínového DOMu je obdobná jako XML transformace. Tedy máte nějaká surová data, která převedete na jinou strukturu (pomocí šablony). Stínový DOM je sice nadefinován v HTML, ale vyžaduje JS pro jeho aktivaci.
Příklad šablony a stínového DOMu:
<template id=myArticle>
<h2>
<slot name=title>Nadpis článku</slot>
<a href="#menu">Nahoru</a>
</h2>
<p>
<slot name=text>Text článku</slot>
</p>
</template>
<article>
<span slot=title>HTML5 prvky</span>
<span slot=text>HTML5 přináší ...</span>
</article>
<article>
<span slot=title>ECMA 2015</span>
<span slot=text>Nová verze JS ...</span>
</article>
...
Když máte takovouhle HTML strukturu (vygenerovanou jednoduše na serveru, kde template načtete z *.html
souboru a seznam článků vygenerujete jednoduchým FOR-EACH
), můžete pomocí javaskriptu aplikovat na jednotlivé články uvedenou šablonu:
if (!'attachShadow' in document
.createElement('article')
) {
alert('Tento prohlížeč neumí'
+' stránku správně zobrazit!!!');
return;
}
//díky podpoře ShadowDOM lze využít ES6
let template = document
.getElementById('myArticle');
let articles = document
.getElementsByTagName('article');
for (const article of articles) {
article
.attachShadow({mode:'open'})
.appendChild(template
.content.cloneNode(true)
)
;
}
Kód získá template
a seznam článků. Následně každý článek označí jako stínový DOM, který obsahuje pouze data a následně k němu připojí šablonu definující strukturu.
Metoda .attachShadow()
vytvoří stínový DOM nad prvkem. Je důležité poslat parametr {mode: 'open'}
, aby byl stínový DOM dostupný z javaskriptu. Metoda nevrací přímo prvek, ale jeho stínovou kopii (shadowRoot
), takže následná práce s ním je trochu jiná, než na co jste zvyklí (např. to, že šablona se aplikuje přes .appendChild()
).
Prohlížeč pak automaticky nahradí všechny prvky slot
v šabloně za prvky z článku s vlastností slot
s odpovídajím jménem name
.
Prohlížeč, který stínový DOM nepodporuje, zobrazí chybu a surová data. Pro vylepšení můžete dopsat do CSS podmínku, která article
zobrazí až po té, co se aplikuje šablona (tím, že mu přiřadíte nějakou třídu).
Poznámka: sloty můžete použít i bez stínového DOMu tak, že v JS načtete všechny prvky, které mají atribut slot
(document.querySelector('[slot]')
) a následně přečtením hodnoty atributu slot
a innerHTML
získáte seznam klíčů a hodnot, které pak můžete podle potřeby použít (vložit do šablony, apod.), ale proč to dělat složitě, když máte jednodušší způsob?
Hodnota slotu nemusí obsahovat jen text a může obsahovat další DOM prvky, které se do slotu vloží. Často je tak hodnější formátování typu H2, P, FIGURE, A (odkaz) mít v datech a do slotů je jen vkládat:
<template>
<article>
<figure>
<slot name=image></slot>
<figcaption>
<slot name=title></slot>
</figcaption>
</figure>
<slot name=text></slot>
<slot name=more></slot>
</template>
<div id=article1>
<h2 slot=title>Nadpis článku</h2>
<img slot=image src="image-12345.webp>
<a slot=more href="#more">Číst dále</a>
<div slot=text>
<p>Text článku</p>
<p>Text článku</p>
<p>Text článku</p>
<div>
</div>
Stylování slotů
Pozor na to, že stínový DOM je samostatný dokument, který nemá přístup ke stylům načteným v hlavním dokumentu. Pomocí stylů z hlavního dokumentu tak můžete formátovat pouze SLOT prvky, jejichž styl se pak přenese i do stínového DOMu.
Pokud potřebujete formátovat prvky ve stínovém DOMu, musíte potřebné styly vložit přímo do TEMPLATE (buď pomocí STYLE nebo přes LINK rel=STYLESHEET).
<template id=myArticle>
<!-- styl pro nadpis, který nelze
naformátovat přes již načtené CSS -->
<style>
h2 { color: blue }
<style>
<!-- styl pro odkaz, který musí být znovu
načten do stínového DOMu -->
<link rel=stylesheet href="/css/navigation.css">
<h2>
<slot name=title>Nadpis článku</slot>
<a href="#menu">Nahoru</a>
</h2>
<p>
<slot name=text>Text článku</slot>
</p>
</template>
Pokud potřebujete uvnitř stínového DOMu zjistit, jestli nějaký prvek má nebo nemá hodnotu, můžete použít pseudo-třídu (funkci) ::slotted()
. Ta funguje podobně jako ::empty
s tím rozdílem, že empty nepozná, jestli je ve slotu něco vloženo o jen ověřuje, jestli má nebo nemá výchozí hodnotu (nezávisle na tom, jestli je tato hodnota vidět nebo ne).
Pokud tedy chcete formátovat výchozí hodnotu slotu, musíte ji obalit nějakým prvek (SPAN) a ten pak formátovat. V okamžiku, kdy se do slotu vloží jiný prvek se ten výchozí automaticky skryje:
<template>
<style>
article slot * {
display: none; //skryj výchozí obsah
}
article ::slotted(*) {
display: block; //zobraz jen skutečný obsah
}
</style>
<article>
<slot name=title><h2>Výchozí titulek<h2></slot>
<slot name=text><p>Výchozí text<p></slot>
</article>
</template>
<div id=article1>
<p slot=text>Text článku bez titulku</p>
</div>
<div id=article2>
<h2 slot=title>Titulek bez článku</h2>
</div>
Všimněte si, že styly se slotted musíme definovat přímo v šabloně, protože styly z hlavního dokumentu (nalinkované CSS and styly z debuggeru) stínový DOM ignoruje (nemá k nim přístup).
Funkci slotted
můžete také použít k tomu, že určutý slot naformátujete podle toho, jaký prvek je do něj vložen. Plný zápis selektoru pro slot s vloženým prvek by byl:
slot[name=<jméno>]::slotted(<vložený prvek>) {
//styl prvku uvnitř slotu
}
Pokud nepotřebujete styl určovat pro konkrétní slot podle jeho jména, můžete ho vynechat a použít jen funkci ::slotted()
– browser sám pozná, že tuto funkci lze aplikovat pouze na slot
a sám ji tedy bude použít jen na slot
prvky.
Pro příklad, pokud chcete formátovat všechny obrázky vložené do slotu template, provedete to takhle:
::slotted(img) {
display: block;
//další styly
}
Dležité je uvědomit si, že funkce slotted
v selektoru zastupuje dva prvky: samotný slot, který určuje selektor před funkcí (např. slot[name=username]::slotted()
) a pak prvek vložený do slotu, který je určen selektorem v závorce (např. ::slotted(span.large[slot=username])
). Styl určený selektorem se pak aplikuje na prvek vložený do slotu!
article slot[name=title]::slotted(h2.news) {
//styl pro titulek článku,
//pokud je jím nadpis se třídou "news"
}
article slot[name=title]::slotted(figure.photo) {
//styl pro titulek článku,
//pokud je v něm fotka s popiskem
}
Levou část selektoru se slotted můžete vynechat, pokud poznáte slot podle vloženého prvku (např. ::slotted(h2)
bude pravděpodobně nadpis článku, tedy slot title). Pravou část (vložený prvek) můžete nahradit za hvězdičku a formátovat tak jakýkoliv prvek (např. slot[name=username]::slotted(*)
pro shodné formátování jména nezávisle na vloženénm prvku).
Styl slotu před kompilací
Pokud používáte LESS nebo SASS a využíváte kaskádovaných tříd, je potřeba si dát pozor na to, jak zapíšete prvek uvnitř slotu.
.article {
&-header {
&-title {
&, ::slotted(&) { ... }
}
}
}
Tento styl popisuje třídu article-header-title
a aplikuje na ní styl, ať už je uvedená samostatně nebo ve slotu.
.article {
&-header {
> h2 { //NEPOUŽÍVAT!!!
&, ::slotted(&) { ... }
}
}
}
Tento styl popisuje prvek H2
uvnitř kontejneru article-header
. Styl pro slot
by ale fungoval jen v případě, že uvnitř slotu by byla celá hlavička s nadpisem; pokud ale máte slot
uvnitř hlavičky a vkládáte jen nadpis, musel by styl být:
.article {
&-header {
> h2, > ::slotted(h2) { ... }
}
}
Vlastní tagy pomocí CustomElements
Když už používáte Šablony a Stínový DOM, tak můžete rovnou začít používat i vlastní prvky, protože jejich podpora je v podstatě stejná jako pro Stínový DOM.
Pointa CustomElements je taková, že pokud chcete do Šablony zobrazit nějaké data vygenerovaná na serveru, není potřeba generovat je do známých (výše uvedených) prvků z HTML5, ale můžete použít libovolnou XML strukturu (např. ze SOAP API) a prohlížeči pak jen říct, jak má XML strukturu zobrazit – tedy na které prvky aplikovat šablony.
Začít musíte tím, že zjistíte, jestli prohlížeč podporuje CustomElements a následně zaregistrovat ty typy, které chcete použít:
//Kontrola, že lze registrovat vlastní prvky:
if ('customElements' in window) {
//Registrace vlastního prvku
customElements.define(
//jméno dat v XML
'data-item',
//Registrace jako HTML prvku
class extends HTMLElement {
//definice, co se má udělat,
//když prohlížeč najde tento prvek
//v HTML a potřebuje ho vyrenderovat
constructor() {
//aplikace stylu standardního HTML
super();
//Přidání vlastní šablony
this.attachShadow({mode: 'open'})
.appendChild(document.
.getElementById('item-tmplt')
.content.cloneNode(true)
);
} //konec konstruktoru
} //konec třídy
); //konec define()
} //konec IF
Tento přístup vám umožní automaticky aplikovat Šablonu na libovolný prvek, ale má jeden problém – že byste museli mít v daném XML již připravého atributy SLOT pro vložení konkrétních dat do slotů šablony. Pokud data načítáte z vlastního API nebo je generujete na serveru, tak to nejspíš není problém.
Pokud ale skutečně načítáte data z externího API, kde nemůžete řídit strukturu dat, budete muset ještě doplnit informaci o tom, jak data do šablony vložit.
//Kontrola, že lze registrovat vlastní prvky:
if ('customElements' in window) {
//Registrace vlastního prvku
customElements.define(
//jméno dat v XML (jméno položky)
'data-item-name',
//Registrace jako HTML prvku
class extends HTMLElement {
constructor() {
//aplikace stylu standardního HTML
super();
//Určení slotu, do kterého
//se má hodnota vložit
this.setAttribute(
'slot',
'name'
);
} //konec konstruktoru
} //konec třídy
); //konec define()
} //konec IF