Martin Michálek Martin Michálek  – 30. 9. 2020

Vlastnost order nastavuje pořadí položky v kontejneru flexboxu nebo CSS Gridu.

Občas se může kodérům a kodérkám hodit proto, že zajistí odlišení vizuálního pořadí položek od pořadí zdrojového vycházejícího z HTML nebo lépe ze stromu DOM.

Jenže kouzlo téhle vlastnosti je zároveň rizikem z pohledu přístupnosti.

Ale než se k tomu dostaneme, pojďme si tu vlastnost rozebrat, jak je na Vzhůru dolů zvykem.

Jednoduchý příklad s flexboxem

Pro účely demonstrace zneužijeme čtyři nevinné položky v kontejneru flexboxu:

<div class="container">
  <div class="item item--1">
    Item 1
  </div>
  <div class="item item--2">
    Item 2
  </div>
  <div class="item item--3">
    Item 3
  </div>  
  <div class="item item--4">
    Item 4
  </div>
</div>

Vlastnost order budeme nastavovat jen u třetí položky:

.item--3 {
  order: 1;
}

Kam si myslíte, že se třetí položka posune? Na první místo? Na druhé?

Do obrázku jsem nakreslil řešení a rovnou hned dvě další nastavení.

Už tady je hezky vidět, že vlastnost mění pořadí prvků možná trošku jinak, než byste čekali:

  • order: 0 – u nulové hodnoty se od ovlivňované položky asi dá očekávat, že bude držet původní pozici. Nezklamala.
  • order: 1 – kladné hodnoty vytvářejí novou řadu položek řazených od nejmenšího po největší číslo. Ale pozor – až za původními, vlastností order nedotčenými položkami.
  • order: -1 – ano, lze použít i záporná čísla. Slouží k vytváření pořadí před původní řadou položek.

Jen si s tím směle pohrejte v mém CodePenu.

Pár věcí, které si stojí za to zapamatovat

Jak je vidět, vlastnost order, jakkoliv se zdá jednoduchá a přímočará, trošku klame tělem. A to jsme ještě nezačali mluvit o přístupnosti.

Jsou zde ale i další vědomosti, které byste měli mít v hlavě, než si s order začnete hrát.

  1. Pokud má více položek nastavenu stejnou hodnotu order, seřadí se podle pořadí v DOMu.
  2. Podle specifikace vlastnost order ovlivňuje také pořadí vykreslování při renderingu stránky prohlížečem, což asi má logiku.
  3. Absolutně pozicované položky vždy dostanou nastavení order: 0, takže drží pořadí vykreslení dle DOMu, což je vidět v mém CodePenu. cdnp.io/e/JjXxVJy

Teď k té přístupnosti. Jste připravení?

Přístupnost: pozor na vizuální pořadí

Musím vás upozornit na to, že jakmile odlišíte pořadí zobrazování od pořadí v kódu, může se stát, že při ovládání z klávesnice (tabulátorem) nebo použítí s odečítači pro zrakově hendikepované přestane pořadí dávat smysl.

Také proto je ve specifikaci obsaženo toto důrazné varování:

Authors must use order only for visual, not logical, reordering of content.

Něco vám řeknu – specifikace má pravdu. Pojďme si to ukázat na jednoduchém demu se čtyřmi položkami:

<div class="container">
  <a class="item item--1" href="#">
    Item 1
  </a>
  <a class="item item--2" href="#">
    Item 2
  </a>
  <a class="item item--3" href="#">
    Item 3
  </a>  
  <a class="item item--4" href="#">
    Item 4
  </a>
</div>

Jak vidíte, tentokrát jsem vyměnil DIVy za odkazy a to proto, abychom mohli obsahem navigovat pomocí tabulátoru.

Kontejner (.container) je obyčejný flexbox, ale za ukázání kódu stojí předpis pro třetí položku:

.item--3 {
  order: -1;
}

Původní pořadí (1, 2, 3, 4) se tedy v prohlížeči změní na 3, 1, 2, 4.

Jenže navigační pořadí je prohlížečem stále bráno podle HTML. Však to uvidíte ve videu:

Případně si to zkuste naživo v CodePenu: cdpn.io/e/JjXxRoJ.

Blbý, že?

Zachránce tabindex? Leda kulový

Někteří z vás si určitě řekli, že situaci může přeci zachránit tabindex, HTML atribut, který nastaví pořadí navigace pomocí tabulátorů:

<div class="container">
  <a class="item item--1" href="#" tabindex="2">
    Item 1
  </a>
  <a class="item item--2" href="#" tabindex="3">
    Item 2
  </a>
  <a class="item item--3" href="#" tabindex="1">
    Item 3
  </a>  
  <a class="item item--4" href="#" tabindex="4">
    Item 4
  </a>
</div>

V prohlížeči to po přidání atributů tabindex vypadá nadějně:

Pořadí navigace je nyní správné, protože odpovídá logickému uspořádání položek na obrazovce:

Typ řazení Pořadí
HTML, DOM 1, 2, 3, 4
Vizuální 3, 1, 2, 4
Navigační, logické 1, 2, 3, 4

Máme to vyřešeno? Nejspíš bohužel ne.

Otázka, která vyvstává, totiž zní – jak moc je tabindex pro tyto případy v praxi použitelný?

Atribut tabindex totiž nastavuje pořadí pro celý dokument, takže jakmile bychom takto zapsali samostatnou komponentu a tu pak vkládali na různá místa DOMu, napácháme s tabindex více škody než užitku.

Na druhou stranu – neumím si představit, že bychom kvůli jedné komponentě s order natvrdo měnili pořadí tabindex pro celou stránku.

Takže z mého pohledu je tabindex pro opravu tohoto problému jen málo použitelný.

Ale zkusit si to v CodePenu klidně můžete:

Pomůže aria-flowto?

Léonie Watson v článku „Flexbox & the keyboard navigation disconnect“ už před lety upozorňovala na vlastnost aria-flowto, která v rámci specifikace WAI-ARIA umožňuje právě lokální změnu navigačního pořadí. Je to prostě takový tabindex pro komponenty.

Hned jsem to vyzkoušel, ale zdá se, že stále platí to, co píše Léonie v článku z roku 2016: Tahle vlastnost má extrémně špatnou podporu v prohlížečích. Alespoň něco se v prohlížečích nemění.

Pomůže nám vůbec něco? Ani ne

Odlišení pořadí navigačního od vizuálního je možné ve flexboxu a teď i Gridu mnoha různými způsoby, tedy nejen vlastností order.

Bohužel se to zdá jako aktuálně nevyřešitelný problém, protože jej myslím nijak konkrétně neřeší specifikace, natož pak prohlížeče.

Pošlu vás na další zdroje, ale nic veselého se tam nedozvíte:

Komunitu, tedy vývojáře, lidi kolem webových specifikací a prohlížečů, zde ještě čeká dost práce. Jednoho by to v roce 2020 překvapilo.

Raději si na order dávejte pozor

Shrňme si to. Vlastnost order určitě může být v některých případech užitečná pro změnu vizuálního pořadí.

Je zde však nebezpečí, že uživatelům zároveň rozbijeme navigaci z klávesnice a zrakově postiženým čtení obsahu přes odečítače.

Takže s order prosím zacházejte opatrně, jako se zápalkami.

Komentáře

Váš názor? Vaše zkušenosti? Našli jste chybu?