Detekce polohovacích zařízení

Pomocí @media můžete vytvořit responzivní layout v závislosti na šířce obrazovky, čímž můžete celkem dobře poznat, jestli uživatel pracuje na mobilu, tabletu nebo desktopu a podle toho uzpůsobit další prvky (např. větší ikony na mobilu).

V posledních letech ale narážíme na zařízení, která se této definici vymykají. Např. Note zařízení, která mají mobilní displej (320px), ale jdou ovládat hodně přesným perem. Nebo naopak dotykové monitory, které mají 4k rozlišení, ale ovládají se pouze prstem (takže na 16x16px ikonu se prakticky nedá kliknout). Navíc některá zařízení jsou již schopna detekovat ukázání prstem (hover) nebo sílu stisku (3D touch).

CSS na tohle myslí a přibližně od poloviny roku 2015 přibyla do prohlížečů podpora pro detekci typu kurzoru a také schopnost odlišit zařízení s podporou akce hover (ukázání).

Poznámka: Podpora je v prohlížečích Webkit (Chrome, Opera, iOS a Safari na MacOS) a Edge (Windows 10). Bohužel není v IE a dokonce ani ve Firefoxu, což je ale v současnosti minimum uživatelů.

Typ kurzoru

Odlišit dotykové ovládání můžete pomocí @media podmínky:

.icon { width: 32px }
@media (pointer: coarse) {
    .icon { width: 1cm; }
}

Hodnota coarse (hrubý nebo nepřesný; neplést s course, což je směrový) platí v okamžiku, kdy uživatel ovládá stránku nepřesným ovládáním, tedy dotykem nebo jiným podobným způsobem (např. máváním rukou nebo ovladačem na PS4 nebo Xbox). Stránka by pak měla zareagovat tím, že zvětší ovládací prvky a umožní jejich stisknutí i v případě, že nelze ukázat na konkrétní pixel.

Pokud máte naopak mobile-first layout, můžete naopak otestovat, jestli má uživatel k dispozici přesné ovládání:

.icon { width: 1cm }
@media (pointer: fine) {
 .icon { width: 32px; }
}

Hodnota fine (přesný nebo jemný) naopak platí, pokud uživatel používá polohovací zařízení schopné přesně označit konkrétní pixel, na který chce kliknout. To může zahrnovat myš, touchpad, grafické pero neboli stylus (např. Samsung Note nebo Wacom tablet) nebo ovládání dotykem, které ale řídí pozici kurzoru (např. vzdálení plocha přes mobil).

Navíc existuje ještě třetí hodnota none:

.icon { display: block; }
.icon-text { display: none; }
@media (pointer: none) { 
    .icon { display: none; }
    .icon-text { display: inline; }
}

Tato hodnota platí na zařízeních, které nelze ovládat pomocí kurzoru a mají k dispozici pouze např. ovládání klávesnicí nebo šipkami. Na to je potřeba pamatovat, že podmínka pointer detekuje pouze polohovací ovládání a neříká nic o dalších možnostech ovládání (např. klávesnice, kolečko myši, posouvání prsty, asistenční služby, ovládání hlasem, atd.).

Ukázání

Schopnost ukázat na prvek (hover) jde také testovat pomocí @media dotazu:

.icon { border-color: transparent; }
@media (hover) {
    .icon:hover { border-color: blue; } 
} 
@media (hover: none) {
    .icon:active { border-color: blue; }
}

Pomocí hover bez hodnoty aplikujete styl v okamžiku, kdy uživatel používá ovládání pomocí zařízení, které je schopno hover detekovat (myš, pero, apod.). S hodnotou none naopak aplikujete styl tam, kde není možno hover provést a je tedy potřeba použít alternativu (např. klik).

Všechny možnosti ovládání

Důležité je uvědomit si, že detekce typu ukazatele a schopnosti ukázat uvedené výše platí jen pro primární způsob ovládání daného zařízení, takže hover:none se bude aplikovat na všech mobilních zařízeních, i když použijete pero nebo připojíte myš, které toho schopny jsou.

I na to ale CSS myslí a nabízí předponu any-*, kterou můžete připsat k výše uvedeným podmínkám a detekovat tak všeobecnou schopnost daného zařízení.

 
.icon { width: 32px } 
@media (any-pointer: coarse) { 
    .icon { width: 1cm; } 
}

Podmínku any-pointer: coarse bude splňovat kterékoliv zařízení, které má k dispozici dotykové (tedy nepřesné) ovládání nezávisle na tom, zda je jeho primární polohovací zařízení myš, touchpad nebo stylus. Na takovém zařízení byste tedy měli vždy udělat větší ikony, aby nebyl uživatel nucen vzít do ruky myš nebo vytáhnout pero jen proto, že chce kliknout na ikonu.

Naopak podmínka any-cursor: fine bude platit na jakémkoliv mobilním zařízení, které má k dispozici pero nebo je k němu připojena myš.

Stejně tak any-hover bude platit na všechny zařízeních, které mají alespoň jedno polohovací zařízení schopné ukázat na prvek:

.icon { border-color: transparent; }
.icon:active { border-color: blue; }
@media (any-hover) {
 .icon:hover { border-color: blue; } 
}  /* přidá hover jen tam, kde dává smysl */

Podmínka any-hover má ještě jednu hodnotu, která platí na zařízeních, které jsou sice schopné vyvolat událost hover, ale dochází k ní pomocí nějaké simulace nebo emulace (např. tím, že daný prvek déle podržíte nebo více stisknete). Zpravidla pak hover nedává smysl, protože je jednodušší kliknout než ukázat:

 
@media (any-hover: on-demand) { 
    /* ... styl pro emulovaný hover */
} 

Všechny, které nemají dané ovládání

Nejčastěji vás ale pravděpodobně bude zajímat negace výše uvedených podmínek:

 
@media not all and (any-pointer: fine) { 
 .drawing { display: none; } 
}

Toto pravidlo skryje prvky, které je nutno ovládat přesným zařízením a tudíž nedávají smysl tam, kde je jen dotykové (nebo žádné) ovládání.

 
.icon { width: 64px; } 
@media not all and (pointer: coarse) { 
    .icon { width: 16px; } 
}

Toto pravidlo zobrazí dotykové ikony všude kromě zařízení, které nemají žádnou možnost dotykového ovládání a tudíž nemá smysl zobrazovat velké ikony. Pozor na to, že toto zahrnuje i zařízení zcela bez polohovacího ovládání!

 
.icon { border-color: transparent; }
.icon:active { border-color: blue; } 
@media not all and (any-hover: none) {
    .icon:hover { border-color: blue; }
}

Toto pravidlo přidá hover styl na všech zařízeních, které jsou schopny ho vyvolat kterýmkoliv způsobem ovládání.

Poznámka: pokud vám přijde podivná podmínka not all and (...), tak vězte, že je použita proto, že not v CSS má nejnižší prioritu a  nelze ho kombinovat se závorkou. Hodnota all odpovídá TRUE (tedy cokoliv), takže celá podmínka se v CSS vyhodnotí jako !(TRUE && (...)) což je, podle Booleovy algebry, to samé jako FALSE || !(...) což odpovídá !(...).

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *