Questa è la traduzione dell'articolo Creating Intrinsic Ratios for Video di Thierry Koblenz, pubblicato originariamente su A List Apart il 26 Maggio 2009. La traduzione viene qui presentata con il consenso dell'editore (A List Apart Magazine) e dell'autore.
Avete mai voluto ridimensionare al volo un video scalandolo come se fosse un'immagine? Usando un rapporto di dimensioni intrinseco per i video è possibile. Questa tecnica consente ai browser di determinare le dimensioni del video basandosi sulla larghezza del suo blocco contenitore. Con dimensioni intrinseche, una nuova larghezza fa scaturire automaticamente un nuovo calcolo per l'altezza, consentendo ai video di ridimensionarsi e dando ad essi la possibilità di scalare allo stesso modo delle immagini. Ecco il primo esempio.
Il concetto
L'idea è quella di creare un box con il giusto rapporto di dimensioni (per esempio 4:3 o 16:9), quindi far sì che il video all'interno del box si adatti per riempire pienamente le dimensioni del box. È così semplice.
Il trucco
La proprietà padding
è la magia che ci consente di creare un box con un rapporto di dimensioni intrinseco. Ciò avviene perché imposteremo il padding in percentuale basandoci sulla larghezza del blocco contenitore.
Le regole CSS qui sotto illustrano come applicare uno stile all'elemento parente e a quello figlio per creare un "contenitore magico", ovvero un contenitore che si ridimensiona proporzionalmente in base alla larghezza del suo elemento parente. Ecco il secondo esempio.
Ed ecco il codice:
.wrapper-with-intrinsic-ratio { /* Contenitore con rapporto di dimensioni intrinseco */ position: relative; padding-bottom: 20%; height: 0; } .element-to-stretch { /* elemento da adattare */ position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: teal; }
Rivediamo la dichiarazione regola per regola, iniziando dall'elemento con classe .wrapper-with-intrinsic-ratio
.
position: relative
Dichiarando position: relative
tutti gli elementi figli si posizioneranno in relazione al loro contenitore.
padding-bottom: 20%
Questa dichiarazione dà al box un formato specifico. Usando il valore 20% per il padding rendiamo l'altezza del box uguale al 20% della sua larghezza.
Usiamo volutamente padding-bottom
invece che padding-top
. Questo perché IE5 rimuove lo spazio creato con padding-top
dal flusso normale. In altre parole, usando padding-top: 20%
creeremo il layout che vogliamo, ma il box si comporterebbe come un elemento posizionato assolutamente, sovrapponendosi gli elementi successivi nel flusso del documento.
height: 0
Specificando un'altezza pari a 0 assegniamo a questo elemento un "layout", facendo in modo che IE5 e IE6 dimensioneranno in modo corretto il box all'interno. Per saperne di più si può leggere l'articolo On having layout.
Nota: poiché IE5 e IE6 trattano la larghezza come larghezza minima, non dovreste usare width: 100%
come modo per attivare il layout. Ciò causa un'espansione del box per riempire il suo contenitore piuttosto che rispettare la larghezza che impostiamo per il contenitore.
Ora consideriamo le dichirazioni all'interno dell'elemento con classe .element-to-stretch
.
position: absolute
Ciò libera l'elemento dai limiti in altezza del suo contenitore. In questo modo esso può essere posizionato sopra l'area del padding.
top: 0
Impostiamo top: 0
per posizionare il box vicino al lato superiore del suo elemento parente.
left: 0
Questa dichiarazione posiziona il box in prossimità del lato sinistro del suo elemento parente.
width: 100%
Dichiarando width: 100%
facciamo sì che il box si adatti per riempire con le sue dimensioni la larghezza del suo contenitore.
height: 100%
Questa dichiarazione fa adattare il box all'altezza del suo contenitore.
background: teal
Applichiamo un colore di sfondo per mostrare il layout del box.
La vera questione
Il terzo esempio usa un video di YouTube, con il markup di YouTube, così abbiamo bisogno di creare spazio per l'interfaccia con i controlli del player video. Notate che l'altezza del player è statica: è alta 25px, a prescindere dalle dimensioni del video. Cambiamo anche il valore del padding per mostrare il video in formato widescreen (16:9):
#containingBlock { width: 50%; } .videoWrapper { position: relative; padding-bottom: 56.25%; padding-top: 25px; height: 0; } object, embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
Diamo un'occhiata ai nostri nuovi selettori, iniziando dal selettore #containingBlock
.
width: 50%
Si tratta di un semplice contenitore per dimostrare il ridimensionamento del video in base alla larghezza del viewport del browser. Nell'esempio precedente il blocco contenitore era invece l'elemento body.
Ora esaminiamo un paio di dichiarazioni per il selettore .videoWrapper
.
padding-bottom: 56.25%
Per creare l'aspetto in 16:9, dobbiamo dividere 9 per 16 (0,5625 o 56,25%).
padding-top: 25px
Per evitare problemi con il box model usiamo padding-top
invece che height
per creare spazio per l'interfaccia con i controlli del player.
Infine, usiamo il selettore object embed
perché, mentre alcuni browser usano object
(Safari), altri hanno bisogno di embed
(FIrefox).
Fatto. Nella prossima parte vedremo di aggiustare le cose per Internet Explorer.
Correzioni per Internet Explorer
Per fare funzionare tutto su Internet Explorer, abbiamo bisogno di aggiungere un container aggiuntivo. Si veda il quarto esempio. Ecco il codice:
#containingBlock { width: 50%; } .videoWrapper { position: relative; padding-top: 25px; padding-bottom: 56.25%; height: 0; } * html .videoWrapper { margin-bottom: 45px; margin-bottom: 0; } .videoWrapper div, .videoWrapper embed, .videoWrapper object { position:absolute; width: 100%; height: 100%; left: 0; top: 0; }
Esaminiamo da vicino i nostri nuovi selettori e le nuove dichiarazioni, partendo da .videoWrapper
.
height: 0
Come abbiamo visto nel secondo esempio, IE5 e IE6 hanno bisogno di un "layout". Ora, consideriamo il selettore * html .videoWrapper
. È chiamato "star html hack". Questo selettore ha una sua funzione solo per le versioni di IE dalla 6 in giù, perché solo queste versioni interpretano le seguenti dichiarazioni:
margin-bottom: 45px
Come si è visto nel secondo esempio, padding-top
crea dei problemi su IE5. Qui usiamo un valore arbitrario per compensare lo spazio che perdiamo usando padding-top
. Ciò è per impedire al video di sovrapporsi agli elementi che seguono.
margin-bottom: 0
La notazione CSS di escape (il carattere backslash) all'interno del nome della proprietà agisce da filtro per impostare un valore differente per IE6. IE6 vede questa dichiarazione, mentre IE5 la ignora. Se preferite usare i commenti condizionali piuttosto che tali filtri, siete liberi di spostare queste dichiarazioni in un foglio di stile specifico per IE.
Infine, il selettore .videoWrapper div, .videoWrapper embed, .videoWrapper object {}
piuttosto che .videoWrapper *
per impedire di applicare stili ad altri contenuti.
Rifiniture
Per rendere questa soluzione più versatile, rimuoviamo le dichiarazioni con padding-top
dalle regole precedenti e le associamo con delle classi. In questo modo, possiamo facilmente applicare stili a video con rapporti di dimensioni differenti e con diverse interfacce con i controlli. Ecco il quinto esempio e il codice:
#containingBlock { width: 50%; } .videoWrapper { position: relative; height: 0; } * html .videoWrapper { margin-bottom: 45px; margin-bottom: 0; } .videoWrapper div, .videoWrapper embed, .videoWrapper object { position: absolute; width: 100%; height: 100%; left: 0; top: 0; } .wideScreen { padding-bottom: 56.25%; } .fourBYthree { padding-bottom: 75%; } .chrome_25 { padding-top: 25px; } .chrome_35 { padding-top: 35px; }
Esaminiamo anche questa volta i punti più rilevanti.
.wideScreen
Usiamo questa classe per video contenuti nell'elemento div.videoWrapper
con un aspetto di 16:9
.fourBYthree
Usiamo questa classe per video contenuti nell'elemento div.videoWrapper
con un aspetto di 4:3
.chrome_25
Questa classe crea uno spazio per controlli del player alti 25px
.chrome_35
Questa classe crea uno spazio per controlli del player alti 25px
Bene così. Nella terza e ultima parte affronteremo il problema della validazione e un approccio su Javascript.
La questione della validazione
Quando si tratta di video, supportare gli standard web non è facile. Per prima cosa, molti browser non codificano il segno &. Mosto spesso poi, utilizzano per incorporare il video il tag non standard embed
.
Per rendere il nostro markup aderente agli standard, dobbiamo innanzitutto sostituire tutte le & presenti nell'URL con &
. Poi dobbiamo implementare un metodo per usare un solo tag object
per incorporare il video, invece di annidare più elementi. Diversamente dal metodo con i tag annidati, questa tecnica offre agli user agent un oggetto singolo, come si vede nello snippet di codice riportato qui sotto. Ecco il sesto esempio.
<div id="containingBlock"> <div class="videoWrapper"> <div> <!--[if IE]> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" » width="480" height="295"> <param name="movie" value="http://www.youtube.com/v/mDRYnaajUcY » &hl=en&fs=1&showinfo=0" /> <![endif]--> <!--[if !IE]>--> <object type="application/x-shockwave-flash" data="http://www. » youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" width="480" » height="295"> <!--<![endif]--> <param name="quality" value="high" /> <param name="wmode" value="opaque" /> <p><a href="http://www.adobe.com/go/getflashplayer"><img alt= » "Get Adobe Flash player" src="http://www.adobe.com/images/shared/ » download_buttons/get_flash_player.gif"/></a></p> </object> </div> </div> ... </div>
Il bonus
Poiché abbiamo un elemento posizionato assolutamente all'interno del box, possiamo nascondere del contenuto dietro al video. Nel nostro caso (esempio 7) abbiamo una breve descrizione del video. Ecco il codice:
<div id="containingBlock"> <div class="videoWrapper"> <div> <!--[if IE]> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" » width="480" height="295"> <param name="movie" value="http://www.youtube.com/v/ » mDRYnaajUcY&hl=en&fs=1&showinfo=0" /> <![endif]--> <!--[if !IE]>--> <object type="application/x-shockwave-flash" data="http://www. » youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" width= » "480" height="295"> <!--<![endif]--> <param name="quality" value="high" /> <param name="wmode" value="opaque" /> <p><a href="http://www.adobe.com/go/getflashplayer"> <img » alt="Get Adobe Flash player" src="http://www.adobe.com/images/shared/ » download_buttons/get_flash_player.gif"></a></p> </object> </div> <p>The following is the description of the video embeded in this document.</p> <p>This short clip is about YouTube widescreen formatting. It shows the two main formats (16:9, 4:3) and also explains the best way to create a Flash movie according to the new widescreen format.</p> </div> ... </div>
L'approccio basato sullo script SWFObject
Per rendere automatico questo metodo possiamo usare lo script SWFOBject per aggiungere la classe .videoWrapper
di cui abbiamo bisogno per applicare gli stili e anche per attivare il contenitore aggiuntivo per IE. Ecco l'esempio 8 (si noti che in questo esempio le dimensioni del blocco contenitore sono impostate in em).
Per aggiungere il codice che ci serve, sostituiamo la seguente riga nello script SWFObject (intorno alla riga 117)
n.innerHTML = this.getSWFHTML();
con questa porzione di codice:
n.className += " videoWrapper"; if(typeof document.documentElement.style.zoom != "undefined"){ var wrapper4ie = document.createElement("div"); n.appendChild(wrapper4ie); wrapper4ie.innerHTML = this.getSWFHTML(); }else{ n.innerHTML = this.getSWFHTML(); };
Ecco tutto. Con un po' di CSS, è possibile ridimensionare e scalare al volo anche i video!