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

Zdroják » Webdesign » CSS3 a detekce podporovaných vlastností pomocí pravidla @supports

CSS3 a detekce podporovaných vlastností pomocí pravidla @supports

Články Webdesign

Proti každému webdesignerovi stojí celá fronta prohlížečů s dosti rozličnou podporou kaskádových stylů. Existují různé strategie, jak se s tímto problémem vypořádat. Jedná se nejspíš o věčný problém a detekce podporovaných vlastností se dostává přímo do CSS3.

Tento text je překladem článku Native CSS feature detection via the @supports rule, jehož autorem je Chris Mills a je zde zveřejněn pod licencí CC-BY-3.0.

Úvod

Podpora standardů v dnes používaných prohlížečích se dosti liší (od moderních prohlížečů po  křápy jako IE6), a tak nám není proti srsti nabízet různým prohlížečům odlišný kód nabízející sice odlišný, ale stále přijatelný uživatelský zážitek. Dělá se to různými způsoby, obecně se spoléhá buď na (méně spolehlivou) detekci prohlížečů nebo na (chytřejší) detekci podporovaných vlastností.

Detekci vlastností obyčejně vykonáte vlastním kódem v JavaScriptu, kterým otestujete existenci patřičné vlastnosti, metody atd. nebo pomocí nějaké knihovny, jakou je např. skvělý Modernizr. Modernizr nabízí detekci řady vlastností HTML5 a CSS3 a mechanismus pro selektivní použití CSS a JavaScriptu na základě této detekce.

Je to užitečné, ale řada lidí se sháněla po nativním mechanismu. Dobrá zpráva je, že jsme na něm začali pracovat. Tento článek popisuje CSS pravidlo  @supports, které je součástí specifikace CSS3 Conditional Rules Module Level 3, která nabízí mechanismus pro selektivní použití kaskádových stylů na základě podporovaných vlastností. Podíváme se na základní syntaxi a ukážeme si příklad.

Pozn.: @supports je zatím podporován v Opeře 12.10 a Firefoxu Aurora; prohlížeče neznající @supports budou tento blok zcela ignorovat. To znamená, že tu už pro něj máme použití, ale pokud vám nestačí, zůstaňte zatím ještě u Modernizeru.

Syntaxe @supports

@supports má podobu at-rule bloku („zavináčového pravidla“), které spustí test a vykoná CSS pravidla uvnitř bloku na základě toho, zda test vrátil true nebo ne. V tomto případě test vždy sestává z jedné nebo vícero deklarací CSS a prohlížeč vrátí true, pokud uvedené deklarace podporuje, např.:

@supports (display:flex) {
  section { display: flex }
  ...
}

Pravidla uvnitř tohoto bloku budou použita, jen pokud prohlížeč podporuje  display: flex.

@supports také podporuje klíčové slovo not, můžeme tak použít styly pouze v případě, že daná vlastnosti není podporovaná. Mohli bychom tak nabídnout alternativní styl prohlížečům nepodporujícím  display:flex:

@supports not (display: flex) {
  // alternatiní layout
  // např. pomocí float
}

@supports také podporuje klíčová slova or a and, která zajistí aplikaci stylů jen v případě, že prohlížeč projde vícero testy nebo v případě, že test projde jedním z několika odlišných testů.

Kupříkladu flexbox je bez vendor prefixu podporovaný Operou a IE10. Pro otestování, zda prohlížeč podporuje vlastnost s prefixem nebo bez prefixu, můžete zapsat:

@supports (display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex) {
  section {
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    …
  }
}

A ještě příklad pro and: mohli byste chtít použít multi-column layout pouze v prohlížečích, které podporují neprefixované vlastnosti column-width a column-span (prohlížeče, které podporují multi-col s prefixem, prozatím nepodporují column-span, což je dost omezující):

@supports (column-width: 20rem) and (column-span: all) {
  div { column-width: 20rem }
  div h2 { column-span: all }
  div h2 + p { margin-top: 0; }
  ...
}

A nesmíme zapomenout uvést, že kombinace and, or a not je nutné uvádět s pomocí závorek, aby byly jasné jejich priority. Mohli byste chtít použít animaci zahrnující 3D transformaci pouze v prohlížečích podporujících animace a 3D transformace:

@supports ((-webkit-animation-name: my-animation) and (-webkit-transform: rotate3D(1,2,4,90deg))) or
          ((-moz-animation-name: my-animation) and (-moz-transform: rotate3D(1,2,4,90deg))) or
          ((-ms-animation-name: my-animation) and (-ms-transform: rotate3D(1,2,4,90deg))) or
          ((-o-animation-name: my-animation) and (-o-transform: rotate3D(1,2,4,90deg))) or
          ((animation-name: my-animation) and (transform: rotate3D(1,2,4,90deg))) {
  // sem přijde vaše skvělá animace
}

Malá ukázka

Abych vám předvedl použití @supports, upravím příklad z mé knihy Practical CSS3: develop and design — 3D rotující vizitka, která využívala Modernizr, aby nabídla alternativní zážitek prohlížečům bez podpory 3D a 2D transformací (jen jsem při hover zvětšil left padding, aby se odkryla zadní strana). Příklad pomocí Modernizeru si můžete zobrazit online. Na obrázcích 1 až 3 předvedu odlišný výsledek v závislosti na podpoře v prohlížečích.

Vizitka vytvořená pomocí CSS3. V prohlížečích podporujících 3D transformace se vizitka animovaně otočí

Obr. 1: V prohlížečích podporujících 3D transformace se vizitka animovaně otočí.

Vizitka vytvořená pomocí CSS3. V prohlížečích bez podpory 3D transformací, ale s podporou 2D transformací, se přední strana vizitky animovaně odsune, a tím se zobrazí i její zadní strana

Obr. 2: V prohlížečích bez podpory 3D transformací, ale s podporou 2D transformací, se přední strana vizitky animovaně odsune, a tím se zobrazí i její zadní strana.

Vizitka vytvořená pomocí CSS3. V prohlížečích bez podpory 3D a 2D transformací se přední strana vizitky bez animace posune, aby se zobrazila i zadní strana vizitky

Obr. 3: V prohlížečích bez podpory 3D a 2D transformací se přední strana vizitky jednoduše posune, aby se zobrazila i zadní strana vizitky.

V tomto příkladu jsem nabídl fallback kód prohlížečům bez podpory 3D transformací a následně i těm, které nepodporují ani 2D transformace. V našem příkladě za pomoci @supports budu postupovat opačně pomocí přístupu progressive enhancement. Napřed nabídnu základní funkčnost, která zobrazí obě dvě strany vizitky prakticky všem prohlížečům:

/* || Pro prohlížeče bez podpory 2D a 3D transformací */

#wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front {
  margin-left: -350px;
}

Starší prohlížeče použijí tento kód a další pravidla uvnitř @supports budou ignorovat.

Přidáme pravidla pro prohlížeče s podporou 2D transformací:

/* || Pro prohlížeče podporující 2D transformace */

@supports (-webkit-transform: rotate(-30deg)) or
          (-moz-transform: rotate(-30deg)) or
          (-ms-transform: rotate(-30deg)) or
          (-o-transform: rotate(-30deg)) or
          (transform: rotate(-30deg)) {


  #inner-wrapper #front {
    -webkit-transition: 0.8s all ease-in;
    -moz-transition: 0.8s all ease-in;
    -ms-transition: 0.8s all ease-in;
    -o-transition: 0.8s all ease-in;
    transition: 0.8s all ease-in;
  }

  #wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front {
    margin-left: 0;

    -webkit-transform: rotate(-30deg) translate(-50%,-100%);
    -moz-transform: rotate(-30deg) translate(-50%,-100%);
    -ms-transform: rotate(-30deg) translate(-50%,-100%);
    -o-transform: rotate(-30deg) translate(-50%,-100%);
    transform: rotate(-30deg) translate(-50%,-100%);
  }

}

A nakonec přidáme kód pro prohlížeče podporující 3D transformace:

/* || Pro prohlížeče podporující 3D transformace */

@supports (-webkit-transform: rotateX(0deg)) or
          (-moz-transform: rotateX(0deg)) or
          (-ms-transform: rotateX(0deg)) or
          (-o-transform: rotateX(0deg)) or
          (transform: rotateX(0deg)) {

  #front, #back {
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    -o-backface-visibility: hidden;
    backface-visibility: hidden;
  }

  #front {
    -webkit-transform: rotateX(0deg);
    -moz-transform: rotateX(0deg);
    -ms-transform: rotateX(0deg);
    -o-transform: rotateX(0deg);
    transform: rotateX(0deg);
  }

  #back {
    -webkit-transform: rotateX(180deg);
    -moz-transform: rotateX(180deg);
    -ms-transform: rotateX(180deg);
    -o-transform: rotateX(180deg);
    transform: rotateX(180deg);
  }

  #wrapper:hover #inner-wrapper, #wrapper:focus #inner-wrapper {
    -webkit-transform: rotateX(180deg);
    -moz-transform: rotateX(180deg);
    -ms-transform: rotateX(180deg);
    -o-transform: rotateX(180deg);
    transform: rotateX(180deg);
  }

  #wrapper:hover #inner-wrapper #front, #wrapper:focus #inner-wrapper #front {
    -webkit-transform: none;
    -moz-transform: none;
    -ms-transform: none;
    -o-transform: none;
    transform: none;
  }

}

Výsledek můžete vidět online.

window.supportsCSS();

Opera 12.10 je v tuhle chvíli jediný prohlížeč, který vedle supports podporuje i odpovídající javascriptové API, které umožňuje spouštět kód na základě podpory CSS vlastností. Přepíšu úvodní příklad do JavaScriptu:

var flexy = window.supportsCSS('display:flex');

if(flexy) {
  alert('Podporuji Flexbox!');
}

Ve specifikaci můžete najít syntaxi CSS.supports a nikoliv window.supportsCSS. To protože jsme implementovali starší verzi specifikace a navíc jsme se u použití globálního objektu CSS báli konfliktů se stávajícími weby. Ještě se ukáže, jak se tenhle problém vyřeší.

Shrnutí

A tím naše představení @supports končí. Jedná se rozhodně o zajímavou vlastnost pomocí které můžete spolehlivě detekovat podporované vlastnosti a nabízet dle toho příslušný CSS kód. Problémem jsou starší prohlížeče nepodporující @supports, kterým musíte nabídnout alternativní cestu. Doufáme, že to bylo pro vás přínosné a předpokládáme, že tahle vlastnost začne být časem mnohem víc užitečná. Dejte nám vědět, co si o ní myslíte, váš feedback nám můžete napsat do mailing listu www-style.

Komentáře

Odebírat
Upozornit na
guest
6 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře
VfB

Rozměry prvků v rem se předpokládám zadávají jen v designech určených pro prohlížení v noci. .)

Čelo

rem frčí docela dlouho

Futrál

Trochu mi to připomíná WordArt nebo weby, které se dělaly před pěknými pár lety. Taky jsem kdysi takové stránky měl, písmo v plamenech a dokonce to bylo animované. Jo, to byly časy :-)

Miro Hrončok

Zajímalo by mě, jestli jde tímto způsobem ověřit například, jestli bude fungovat použití SVG jako backround URL, takhle:

#kontakt { background: url("kontakt.png") center left no-repeat; }
@supports (background: url("kontakt.svg")) {
    #kontakt { background: url("kontakt.svg") center left no-repeat; }
}

Nebo jestli to jen ověří, že je podporovaná vlastnost background a projde to. Nemůžu to momentálně vyzkoušet.

Díky

Bubák

Zkoušel jsem v aktuální Opeře 12.11 a ta skrze supports hlásí, že podporuje, ať už do url() napíši cokoliv, třeba i „document.doc“. Netuším, zda jde je to problém specifikace, nebo implementace.

Když jsem zkoušel podporu pro „color: nesmysl;“ nebo „width: 100nesmysl“, tak se opera skrze supports hlásí, že nepodporuje, obdobně je to i pro další CSS vlastnosti.

Neužitečná zajímavost:
Všechny prohlížeče ve quirk režimu chápou nenulovou délku bez jednotky jako pixely, ale Opera skrze supports hlásí, že nepodporuje.

Přístupnost není jen o splnění norem: nový pohled na inkluzivní design

Přístupnost a inkluze možná nepatří mezi nejžhavější témata digitálního světa – dokud o nich nezačne mluvit Vitaly Friedman. Na WebExpo 2024 předvedl, že inkluzivní design není jen o splněných checkboxech, ale hlavně o lidech. S energií sobě vlastní obrátil zažité přístupy naruby a ukázal, že skutečně přístupný web je nejen možný, ale i nezbytný.

Efektivnější vývoj UI nebo API: Co si odnést z WebExpo 2025?

Různé
Komentáře: 0
Jak snadno implementovat moderní uživatelské rozhraní? Které funkce brzdí rychlost vašeho webu? A kdy raději sami přibrzdit, abychom využitím AI nepřekročili etické principy? Debatu aktuálních dev témat rozdmýchá sedmnáctý ročník technologické konference WebExpo, která proběhne v Praze od 28. do 30. května. Který talk či workshop si rozhodně nenechat ujít? Toto je náš redakční výběr z vývojářských hroznů.

Zapřáhněte AI jako nikdy předtím. Květnová konference WebExpo přivítá hvězdy technologického světa

Od 28. do 30. května 2025 promění pražský Palác Lucerna na tři dny technologická konference WebExpo. Na programu je více než 80 přednášek a workshopů od expertů z celého světa. WebExpo tradičně propojuje vývojáře, designéry, marketéry i byznysové lídry a nabízí praktické dovednosti, strategické myšlení a přináší nejnovější trendy nejen v oblasti AI.