Feature queries CSS. Regola @supports
Feature Queries CSS. Regola @supports
Extrowebsite

Nonostante la maggior parte dei browsers abbia raggiunto un elevato grado di compatibilità per quanto riguarda l'interpretazione delle regole CSS, ci sono ancora delle discrepanze nel mostrare quello che un web designer prima progetta e poi trasferisce a video.

Mi riferisco ad una implementazione, nei fogli di stile, poco trattata: Feature Queries. Nello specifico la regola @supports.

La regola CSS @supports consente di eseguire il rilevamento delle funzioni del browser direttamente dal foglio di stile, invece di ricorrere a files esterni, di terze parti, come ad esempio Modernizr.

Cominciamo da un punto fermo: la regola @supports è anche conosciuta come Feature Queries.

La regola @supports la si potrebbe definire come un insieme di regole condizionali la cui peculiarità è quella di testare se il browser supporta determinate righe di codice CSS del tipo proprietà: valore.

I web designer possono scrivere tali regole, che utilizzano nuove funzionalità quando disponibili, nei propri fogli di stile. In mancanza del supporto da parte dello user agent si assiste ad una graceful degradation.

I CSS dispongono di "meccanismi", altrimenti conosciuti come "trucchi" per una graceful degradation. Ad esempio, riscrivere una regola per un determinato browser quando questo non interpreta una proprietà oppure un valore.

La sintassi della condizione nella regola @supports è leggermente più complicata rispetto alle altre regole appartenenti al gruppo "condizionale", nonostante abbia alcune somiglianze con le media queries.

Sintassi della regola @supports

@supports(proprietà: valore) {
 codice css...
}

Vediamo subito un esempio. Poniamo il caso che la regola display:flex, da tempo molto utilizzata, venga riconosciuta solo da un browser.

Siccome fa risparmiare molto codice, oltre al tempo, per allineare elementi di blocco in un layout, volendo adottare le Feature Queries, dovremmo scrivere:

@supports (display: flex) {
 /* codice che verrà eseguito solo se il CSS 
    è supportato dal browser */
 }

Il codice di esempio precedente controlla se il browser supporta la proprietà display avente valore flex.

Se è vero, cioè se la condizione restituisce true, verranno applicate le regole di stile dichiarate all'interno del blocco @supports.

La parola chiave not

Così come è possibile che una determinata regola CSS sia supportata, motivo per cui verrà eseguito il codice di esempio all'interno della regola @supports, allo stesso modo potrebbe esserci un browser che non interpreterà quel codice.

Sapendo questo, si possono escludere tutti quegli user agent, introducendo la parola chiave not e scrivendo codice CSS appositamente per essi.

Ad esempio, è possibile combinare il precedente codice di esempio, con supporto Flexbox, con un altro codice che fornisce stili alternativi per tutti i browser che non lo interpretano.

@supports not (display: flex) {
 div {
   float: left;
   ... 
  }
}

Il codice appena riportato è la dimostrazione di come ottenere un risultato simile a quello che si otterrebbe con la regola @supports. Ecco spiegata, con un esempio pratico, la graceful degradation.

Ricapitolando, si devono scrivere entrambi i blocchi di codice, distinti e separati, all'interno del foglio di stile, sia quando vogliamo utilizzare la regola @supports, sia il codice per tutti gli altri browsers.

@supports (display: flex) {
  div {
       display: flex;
       align-items: middle;
	   ......
    }
}
@supports not (display: flex) {
 div {
   float: left;
   .....
  }
}

Controlli multipli con gli operatori and e or

È possibile verificare il supporto di più funzionalità in una regola @supports utilizzando gli operatori and e or.

Per esempio, se una determinata proprietà è supportata con i prefissi in alcuni browser e senza di essi in altri, è possibile verificare il supporto per una versione precedente, con e senza. Il codice seguente controlla il supporto per Flexbox, incluso il controllo per il supporto per le versioni precedenti con i prefissi del produttore di browser.

@supports (display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex) {
    div {
        display: -webkit-flex;
        display: -moz-flex;
        display: flex;
        ....
    }
}

E' possibile verificare il supporto del browser per due funzionalità adottando la parola chiave and. Ad esempio, si vuole scrivere codice CSS che introduce le trasformazioni e le transizioni per creare effetti tridimensionali.

@supports (transform: rotate3d(1, 1, 0, 45deg)) and (transition: transform 4s) {
	codice css
}

E' possibile utilizzare le parole chiave or e and in una unica dichiarazione @supports, per poter eseguire contemporaneamente più rilevazioni delle funzionalità del browser. Vediamo un esempio.

@supports ((display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex)) and (-webkit-appearance: caret) {
		  codice CSS
}

E' possibile utilizzare le parole chiave or e and in una unica dichiarazione @supports, per poter eseguire contemporaneamente più rilevazioni delle funzionalità del browser. Vediamo un esempio.

@supports ((display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex)) and (-webkit-appearance: caret) {
		  codice CSS
}
/* stili per tutti i browsers */
.demo {
display:block;
margin:30px auto;
cursor: pointer;
}

Adesso applichiamo la regola @supports

@supports (-webkit-filter: blur(4px)) or (filter: blur(4px)) {

.demo {
      filter: blur(4px);
    }
	
.demo:hover {
        filter: blur(0);
		}
}

Il risultato è uniforme nei browsers conformi, tranne IE11. Infatti abbiamo nel primo esempio:

Immagine con effetto blur
Immagine con effetto blur

e nel caso in cui un browser, come IE11, non supporti l'effetto blur, mostrerà a video l'immagine normale:

Immagine senza effetto blur
Immagine senza effetto blur

Note sulla corretta sintassi della regola @supports

Uno spazio è obbligatorio dopo la dichiarazione not e su entrambi i lati degli operatori and e or.

La proprietà che deve essere applicata deve essere sempre scritta tra parentesi tonde. Per esempio il codice seguente non è valido.

@supports display: flex {
...
}

La sintassi @supports consente di aggiungere parentesi supplementari anche quando non sono necessarie. Il codice seguente è a tutti gli effetti valido.

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

Se nella dichiarazione è presente not con gli altri operatori, non è necessario racchiudere il not tra parentesi se si trova al livello superiore (se è la prima regola da eseguire).

Le parentesi sono abbligatorie se l'operatore not non è la prima condizione da verificare.

/* DICHIARAZIONE VALIDA */
@supports not (...) and ((...) or (...)) 
{ 
....
}
/* DICHIARAZIONE NON VALIDA */
@supports (...) or (...) not (...) 
{ 
....
}
/* DICHIARAZIONE VALIDA */
@supports (...) or (...) (not (...)) 
{
...
}