Přejít k navigační liště

Zdroják » Webdesign » Vše o prvku BUTTON a tlačítkách v HTML

Vše o prvku BUTTON a tlačítkách v HTML

Články Webdesign

Prvek button reprezentuje tlačítko. Tím bychom mohli skončit a jít na pivo, že jo? To byste ale byli na špatném místě. My půjdeme do hloubky.

Text vyšel původně na autorově blogu.

Jak hluboko půjdeme?

  • Doporučím vám dávat prvku <button> přednost před tlačítky v <input>.
  • Upozorním, že prvek <a> stylovaný jako tlačítko vždy nemusí být dobrý nápad.
  • Nakonec společně zjistíme, že <button> je vlastně univerzální interaktivní prvek.

Začneme ale u samotné HTML značky.

Prvek BUTTON

Specifikace uvádí, že <button> reprezentuje tlačítko, jenže definice tlačítka je širší, než bychom mohli čekat.

Nespornou výhodou prvku <button> je jeho párovost. Můžeme do něj vložit libovolný text, který zároveň slouží jako jeho popis (label). Můžeme do něj vložit libovolnou HTML strukturu.

Atributem type="" můžete tlačítku vnutit různé vzorce chování:

  • <button type="submit"> nebo <button> – odesílá formulář
  • <button type="reset"> – resetuje hodnoty ve formuláři
  • <button type="button"> – nedělá nic

Poslední typ neodešle formulář, takže mu můžete přidávat nejrůznější funkce. Rozdíl mezi odesílacím a neodesílacím tlačítkem je patrný také v mé další ukázce. cdnp.io/e/VrZJwX

To, že type="button" nic nedělá, neznamená, že nic neumí. Má vlastnosti, které jiným HTML prvkům chybí. Za chvilku se k nim dostaneme. Nejprve ještě k sesterské značce <input>.

Proč prvek BUTTON a ne INPUT?

Známe přeci <input type="button"> nebo jiné s hodnotami imagesubmit a reset v atributu type="". Proč tedy <button>?

Protože je univerzální a snadněji se styluje.

Do prvku BUTTON můžete vložit další element

Prvek pojme skoro jakoukoliv HTML strukturu:

<button>
  <img src="icon.svg" alt="">
  Tlačítko <em>s důrazem</em>
</button>

Přesněji řečeno: Pojme jakékoliv značky, které popisují text v odstavci (tzv. Phrasing Content). Takže <svg><img> nebo dokonce <iframe> je povolený. <p><div> nebo <h1> naopak zakázaný.

<input> přijímá pouze textové hodnoty nebo obrázek, který je ovšem dneska kvůli přístupnosti už dost krajní možností.

Můžete používat pseudotřídy :before a :after

Tohle bychom s <input> jako nepárovou značkou opět nemohli:

button:before {
  background: url(icon.svg)
}

Nicméně pozor na velké aktivní plochy. Jak uvádí Bohumil Jahoda, větší plochy pseudotříd nejsou aktivní ve Firefoxu. kod.djpw.cz/mckc

Problémy se starými Explorery, spíše pro zajímavost

<button> se pojily nějaké problémy v Internet Explorerech verzí 6-9. Zejména pak v situacích, když jste textovou hodnotu uvedenou v <button>chtěli poslat na server. Mě osobně to nevadí, protože to je velmi vzácný scénář a protože už i staré Explorery jsou dnes druh velmi vzácný, až vyhynulý. Problémy se starými Explorery přesně popisuje Bohumil Jahoda, ale nenechte se jimi odradit.

Nepleťte si tlačítko s odkazem

Odkaz (link) specifikace definuje jako interaktivní odkaz na interní nebo externí zdroj. Prostě kotva uvnitř dokumentu nebo odkaz na jinou adresu. Plně mu odpovídá prvek <a>.

Odkaz má kromě toho speciální chování v prohlížečích. Jejich obsah lze pomocí drag’n’drop přemístit jinam. Některé prohlížeče po najetí myši ukazují cílovou adresu. Poslední specialita je možnost otevřít cílovou adresu v novém okně pomocí klávesové zkratky nebo z kontextové nabídky. Někteří také tvrdí, že je jim vyhrazený kurzor v podobě ruky (cursor:pointer), ale s tím já se neztotožňuji. „Pracičkový“ kurzor se dnes na webech široce používá pro zvýraznění aktivních elementů a je to zažitá věc.

Tlačítko (button) je naproti tomu prvek, který po aktivování vyvolává akci uvnitř aktuální stránky. Plně mu odpovídá element <button>.

Pokud tedy prvek vyvolává akci, ale nemění lokaci, je správnější použít značku <button>.

Neznamená to však, že byste měli pro všechny komponenty rozhraní s vizuálem tlačítka používat zásadně jen <button>. Občas je kvůli jednotnosti rozhraní potřeba odkaz nastylovat vizuálem tlačítka.

Znamená to především, že byste neměli používat prvek <a> tam, kde je významově vhodnější tlačítko. Prostě pro akce, které nemění URL prohlížeče. Neměli byste dělat ošklivárny tohoto typu:

<input type="text">

<a href="#" class="button">
  Tlačítko pro ovládání inputu
</a> 

Nebo takhle: Když už to udělat potřebujete, měli byste přidat všechny očekávané funkce tlačítka.

Odkaz s vizuálem tlačítka: na co všechno myslet?

Pojďme si to ukázat na příkladu. Předpokládeme, že se jedná z významového pohledu o tlačítko, tedy nepřecházíme na novou URL. Pojďme to zkusit udělat špatně, odkazem:

<a href="#" class="button">
  Problémové tlačítko
</a>

Prvek bude mít díky třídě vizuál tlačítka. Čtečky dávají prvku <a> jiný význam než prvku <button>. Proto bychom museli přidat WAI-ARIA roli pro tlačítko:

<a href="#" class="button" role="button">
  Problémové tlačítko
</a>

Ale je tu i další problém: Odkaz není na rozdíl od tlačítka možné v prohlížečích aktivovat mezerníkem. Tlačítko má být aktivovatelné mezerníkem i enterem, odkaz jen enterem. Více o tom píší třeba na MDN.

Jak to vyřešit? Mohlo by vás napadnout třeba zanoření nativních prvků:

<a href="#">
  <button>
    Problémové tlačítko
  </button>
</a>

Jenže to dobře fungovat nebude. Při ovládání z klávesnice musí uživatel zápasit se dvěmi zaměřeními, s dvojitým focusem. Nebude pro něj snadné vybrat ten správný.

Zkusme tedy další pokus s odkazem. Hlídání stisknutí mezerníku musíme ošetřit Javascriptem:

<a href="#" role="button" class="btn btn-secondary"
  onkeypress="if(event.keyCode==13){alert('Ahoj!')};
  onclick="alert('Ahoj!')">
    Problémové tlačítko
</a>

Můžete si to zkusit na Codepenu: cdpn.io/e/eExXmy.

A teď úplná prasárna: prvek SPAN jako tlačítko

Existence ARIA role="button" by mohla napovídat, že bychom snad měli možnost udělat tlačítko z čehokoliv, třeba z prvku <span>:

<span role="button">
  Tlačítko prasátko
</span>

Je to samozřejmě blbost. Pojďme si na tabulce ukázat, jaké všechny funkce jsou skryté v prvku <button> a které prvky <span> ani <a> nemají.

Prvek Vzhled Klik/touch Focus Význam Mezerník
<span> + +
<a> + + +
<button> + + + + +
Tabulka: Přidáním třídy můžeme nastavit vzhled tlačítka na jakýkoliv element, prvek SPAN nebude možné aktivovat klikáním a dotyky a nebude možné jej zaměřit z klávesnice (:focus). To asi nepřekvapí. Prvek A ovšem nenese význam tlačítka a není možné jej aktivovat mezerníkem.

Do vytvoření tlačítka pomocí jiných prvků než <button> se proto ideálně nepouštějte.

Paul J. Adam píše i o dalších věcech, které se mi sem nevešly. Cituji:

There’s a lot to consider when making a custom button control fully accessible with an experience equal to a native button. You need tabindex=0, role=button, onkeydown, .keyCode == 13, .keyCode == 32, event.preventDefault(), and extra CSS to make it look like a real button.

Ano, sémanticky správné tlačítko totiž vypadá úplně jednoduše:

<button>
  Správné tlačítko
</button>

Jak navíc ve své skvělé knize píše Heydon Pickering, jen tlačítko udělané z prvku <button> je – a teď cituji – „resizable, translatable, focusable, interoperable, stylable, restylable, maintainable, mutable, simple“.

A jak za chvilku uvidíte, používat pro prvek <button> označení „tlačítko“ trochu zavání podceňováním.

Značka BUTTON jako univerzální iteraktivní prvek

Button je zaměřitelný a aktivovatelný dotykem, myší i z klávesnice. To je věc, kterou potřebujeme fakt často. Co třeba akordeony a další rozklikávací rozhraní?

Aktivační prvek akordeonu je totiž významem typické tlačítko:

<h3>
  <button 
    aria-expanded="false" aria-controls="collapsible-0">
    Rozklikávač
  </button>
</h3>

<div id="collapsible-0" aria-hidden="true">   
  <p>Rozklikávaný obsah…</p>
</div>

Příklad s akordeonem jsem si vypůjčil z ukázek Heydona Pickeringa.

Další možnosti jsou vidět na webu Inclusive Components. Jednou z nich je stylování vlastních přepínačů – dvoupolohových tlačítek:

<span id="notify-email">
  Notify by email
</span> 
<button role="switch" 
  aria-checked="true" aria-labelledby="notify-email">
  <span>on</span>
  <span>off</span>
</button>

Vidíte, že pomocí atributu role="" měníme význam tlačítka na „přepínač“. Věnujte prosím pozornost i dalším atributům začínajícím slovem aria-.

Takovéto prvky v rozhraní jako běžná tlačítka nevypadají, přesto u nich může být prvek <button> díky svým vlastnostem velmi užitečný.

Vzpomeňte si na něj až budete nějakou takovou komponentu stylovat. <a>pro tlačítka používejte jen tam, kde se to významově hodí. Jiné elementy nejlépe vůbec pro tlačítka nevyužívejte.

ebook-vdcss3-prebal-final

Vzhůru do (responzivního) designu

Průvodce návrhem a implementací responzivních uživatelských rozhraní. Vyšlo v květnu 2017. Koupit e-book.

Komentáře

Subscribe
Upozornit na
guest
8 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Dominik

Velmi pekny clanok, kto raz zacne riesit web accessibility, tak vsetky tieto rady vyuzije. Mam vsak otazku na autora, nakolko vyzera ze sa v tejto teme fakt vyzna. Ide o pomerne bezny use-case: na stranke sa zobrazuju nejake dlazdice (napr. grid 9 dlazdic) pricom kazda z nich je vlastne odkazom na bud inu podstranku, alebo vyskoci modalne okno a pod.. Vzhladom na design, kazda dlazdica ma ramcek, obsahuje nadpis, nejaky popis a na spodku button, ktory vyvolava danu akciu. Lenze aby to bolo user-friendly, reagovat ma cela dlazdica, nielen ten button v nej (ten je fakt akoby len do poctu kvoli dizajnu). Ako to spravne urobit? Urobit z celej dlazdice button (a vyuzit ze ide o tag parovy a teda vieme do neho vnorit svoj bordel), alebo to v takomto pripade moze byt div ktoremu akurat namapujeme cez JS danu akciu s tym, ze to bude dostupne len mysou a citacky o tom ani vediet nebudu, pre klavesnicu vlastne zostane ten button vnutri stale plne accessible?

Dominik

Dakujem, zvacsa to robim podobne (aj ked priznavam, miesto a tam este obcas hodim len div). V takomto pripade teda ak bude vo vnutri toho article dalsi button bude to v poriadku? Citacka tak vlastne 2x zahlasi moznost prechodu na detail clanku/produktu (raz pre a a raz pre button).

Dominik

pretoze niekedy tam nieje link ale len akcia typu popup a pod.

Rob

Hlavní výhoda buttonu oproti inputu je je podle mě jednoduše to, že value (zasílaná na server) je oddělená od zobrazovaného textu. Třeba taková vícejazyčná aplikace, s několika tlačítky v jednom formuláři se pomocí inputů programuje fakt docela blbě.
Ale jinak dobrý článek.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.