Tutte le soluzioni che abbiamo visto finora hanno una cosa in comune: si esegue un'azione quando il criterio stabilito in una media query viene soddisfatto. Javascript offre per questo scopo un metodo nativo: matchMedia. Al momento il supporto sui vari browser è il seguente:
Per estendere il supporto possiamo usare un polyfill, matchMedia.js.
Come funziona matchMedia
Il funzionamento di matchMedia
è molto intuitivo:
if (window.matchMedia("(min-width: 600px)").matches) {
// esegui questa azione;
}
Che è equivale a dire:
se (la larghezza di questa finestra è >= 600px) {
// esegui questa azione;
}
Chiaramente, la parte relativa alla media query potrà essere valorizzata e strutturata con tutte le caratteristiche dei media previste dai CSS3.
Applicazione nel progetto
Una prima applicazione pratica di matchMedia
nel nostro progetto la troviamo nella gestione del video in evidenza.
Per ottimizzare i tempi di caricamento sugli smartphone, decidiamo di partire, nel codice HTML, da questa struttura:
<section id="video-evidenza">
<div id="frame-container">
<a href="http://www.youtube.com/watch?v=RdIh8GiVR9I" target="_blank">
<img src="video-frame.jpg" class="media--block scala" alt="">
</a>
<p class="didascalia">
<a href="http://www.youtube.com/watch?v=RdIh8GiVR9I" target="_blank">The Street Aesthetic of New York</a>
</p>
</div>
</section>
Non carichiamo direttamente il video, ma lasciamo un'immagine segnaposto che punta con un link al video. Inseriamo un link anche nella breve descrizione che segue.
Quando e se la finestra ha una larghezza minima di 600px, sostituiamo l'immagine con il video. Un caso ideale per usare matchMedia
.
Ecco lo script:
if (window.matchMedia("(min-width: 600px)").matches) {
(function (win) {
var doc = win.document;
var sez = doc.getElementById('video-evidenza');
var frame = document.getElementById("frame-container");
if (frame) {
sez.removeChild(frame);
var vidCont = document.createElement('div');
vidCont.setAttribute('class', 'video-container');
sez.appendChild(vidCont);
vidCont.innerHTML = '<iframe width="560" height="315" src="http://www.youtube.com/embed/RdIh8GiVR9I" frameborder="0" allowfullscreen></iframe>';
}
})(this);
}
La funzione che eseguiamo quando la media query corrisponde prevede nell'ordine:
- la rimozione del
div
conid#frame-container
(quello che racchiude l'immagine segnaposto); - la creazione di un nuovo
div
; - l'assegnazione a quest'ultimo della classe
.video-container
; - l'inserimento di questo
div
come figlio dell'elementosection
conid#video-evidenza
; - l'inserimento nel nuovo
div
come HTML del codice di embed preso da YouTube.
E così su tablet e desktop possiamo goderci il video direttamente nella finestra del browser.
Video fluido e flessibile
Un ultimo ritocco. Se provate a restringere e allargare la finestra del browser visualizzando la demo, noterete che il video è fluido, si adatta proporzionalmente alle dimensioni del suo contenitore. Per ottenere il risultato basta associare queste regole CSS al div
che contiene il video e che per noi ha la classe .video-container
:
/* Video responsivo */
.video-container {
position: relative;
margin-bottom: 15px;
padding-bottom: 56.25%;
width: 100%;
height: 0;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
In realtà sono regole necessarie solo per i video incorporati con un iframe
come quelli di YouTube. Se si usa l'elemento HTML video
, basterà usare, come per le immagini flessibili, max-width: 100%;
.