¿Alguna vez has querido redimensionar un video sobre la marcha, tal como lo harías con una imagen? Con dimensiones intrínsecas es posible. Esta técnica permite que los navegadores determinen las dimensiones del video, con base en el tamaño del ancho del bloque contenedor.
Con dimensiones intrínsecas, una nueva anchura provoca un nuevo cálculo de la altura, permitiendo a los videos ser redimensionados, dándoles la habilidad de escalar de la misma manera que lo hacen las imágenes. Revisa el primer ejemplo.
El Concepto#section1
La idea es crear un contenedor con la proporción correcta (4:3, 16:9, etc.), y luego hacer que el video dentro del contenedor se extienda para ajustarse a las dimensiones del contenedor. Es así de simple.
El Truco#section2
La propiedad padding
es la magia que le da estilo al contendor con una proporción intrínseca. Esto es porque definiremos el padding
en un porcentaje, con base en la anchura del bloque contenedor.
Las reglas CSS de abajo, ilustran cómo le damos estilo al padre y al hijo, para crear una “envoltura mágica”─un contenedor que se redimensiona a sí mismo de manera proporcional dependiendo dela medida del ancho de su padre. Revisa el segundo ejemplo.
.wrapper-with-intrinsic-ratio {
position: relative;
padding-bottom: 20%;
height: 0;
}.element-to-stretch {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: teal;
}
Repasemos las declaraciones en cada regla, comenzando con .wrapper-with-intrinsic-ratio
.
position: relative
Al declararposition: relative
todos los elementos descendientes se posicionarán a sí mismos en relación a este contenedor.
padding-bottom: 20%
Esta declaración le da al contenedor un formato específico. Utilizando 20% para elpadding
hace que la altura del contenedor sea igual al 20% de su anchura. Específicamente elegimos utilizarpadding-bottom
en vez depadding-top
. Esto es porque IE5 remueve el “espacio” creado por medio depadding-top
del flujo. En otras palabras, utilizandopadding-top: 20%
crearía el diseño que queremos, pero el contenedor actuaría como un elemento absolutamente posicionado, superponiéndose a los siguientes elementos en el flujo.
height: 0 Al especificar una altura de0
le damos a este elemento un “diseño” con el cuál tanto IE5 como IE6 dimensionarán el contenedor interior de manera correcta. Para aprender más, visita “On having layout”. Nota: ya que IE5 y IE6 tratanwidth
como si fuera la anchura mínima, no deberías utilizarwidth: 100%
para desencadenar algo en el diseño. Esto causa que la caja se expanda para rellenar su contenedor, en vez de respetar la anchura que definimos para el contenedor.
Ahora, consideremos cada declaración dentro de nuestra regla .element-to-stretch
.
position: absolute
Esto libera al elemento de la altura límite de su padre. De esta manera, puede ser posicionado sobre el “área del padding
”.
top: 0
Definimos top: 0
para posicionar el contenedor cerca de la parte superior de su padre.
left: 0 Esta declaración posiciona el contenedor cerca del lado izquierdo de su padre.
width: 100%
Al declarar width: 100%
hacemos que la caja se estire para rellenar la anchura de su contenedor.
height: 100% Esta declaración hace que la caja se expanda para completar la altura de su contenedor.
background: teal Aplicamos un color para revelar el diseño del contenedor.
El Trato Real#section3
El tercer ejemplo utiliza un video de YouTube (con markup de YouTube), por lo que necesitamos hacer espacio para el wrapper. Nótese que la altura del wrapper es estática: tiene 25 píxeles de alto, sin importar las dimensiones del video. También cambiamos el valor del padding
para desplegar el video en un formato de pantalla amplia (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%;
}
Echémos un vistazo más de cerca a nuestros nuevos selectores y declaraciones, comenzando por el selector #containingBlock
.
width: 50% Este es únicamente un contenedor para mostrar el cambio de tamaño del video, con respecto al ancho de la ventana.
Ahora, es momento de examinar un par de declaraciones bajo el selector .videoWrapper
.
padding-bottom: 56.25% Para crear una proporción de 16:9, debemos dividir 9 entre 16 (0.5625 o 56.25%).
padding-top: 25px Para evitar problemas con el modelo de caja rota (IE5 o IE6 en modo quirks), utilizamospadding-top
en vez deheight
para hacer espacio para el wrapper.
Finalmente, utilizamos el selector object, embed
porque algunos navegadores dependen de object
(por ejemplo, Safari), mientras que otros utilizan embed
(por ejemplo, Firefox).
Nota: Estoy utilizando el markup de YouTube por ahora, pero al final del artículo estaré utilizando markup válido y necesitaré utilizar embed
.
Las Soluciones para Internet Explorer#section4
Para lograr que esto funcione en Internet Explorer, simplemente añadiremos un contenedor extra. (Nunca dije que sería bello y limpio). Mira el ejemplo cuatro.
#containingBlock {
width: 50%;
}.videoWrapper {
position: relative;
padding-top: 25px;
padding-bottom: 56.25%;
height: 0;
}* html .videoWrapper {
margin-bottom: 45px;
margin-bot\tom: 0;
}.videoWrapper div,
.videoWrapper embed,
.videoWrapper object {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
Veamos más de cerca a nuestros nuevos selectores y declaraciones, comenzando con el selector .videoWrapper
.
height: 0 Tal como lo vimos con el ejemplo dos, IE5 y IE6 necesitan “diseño”.
Ahora, veamos nuestro selector * html .videoWrapper
. Llamado el “star html hack”, este selector tiene sentido solo en IE6 y menor, puesto que solo estas versiones traducen las siguientes declaraciones:
margin-bottom: 45px Como en el ejemplo dos,padding-top
crea algunos problemas en IE5. Aquí utilizamos un valor arbitrario (que debería funcionar con varios wrappers) para compensar por el “espacio” perdido al utilizarpadding-top
. Esto es para prevenir que el video se sobreponga a los elementos subsecuentes.
margin-bottom: 0
La notación de escape (carácter de barra invertida) con el nombre de la propiedad, actúa como un filtro para definir un valor diferente para IE6. IE6 “ve” esta declaración, mientras que IE5 la ignora. Si prefieres utilizar comentarios condicionales en lugar de los filtros anteriores, siéntete libre de mover estas declaraciones a hojas de estilo específicas para IE, o elementos style
en la cabecera del documento.
Finalmente, el selector .videoWrapper div
es el envoltorio extra que necesitamos para hacer funcionar las cosas en las versiones 5, 6 y 7 de Internet Explorer.
Nota: Utilizamos .videoWrapper div, .videWrapper embed,
y .videoWrapper object {}
en vez de .videoWrapper * {}
para prevenir darle estilo a contenido alternativo.
La Limpieza#section5
Para lograr que esta solución sea más versátil, removemos las declaraciones padding-top
de las reglas anteriores y las asociamos con clases. De esta manera, podemos fácilmente darle estilo a videos con proporciones distintas y/o wrappers. Mira el ejemplo cinco.
#containingBlock {
width: 50%;
}.videoWrapper {
position: relative;
height: 0;
}* html .videoWrapper {
margin-bottom: 45px;
margin-bot\tom: 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;
}
Ahora veamos las nuevas clases, comenzando con .wideScreen
.
.wideScreen
Utilizamos esta clase para darle estilo a div.videoWrapper
con una proporción 16:9.
.fourBYthree
Utilizamos esta clase para darle estilo a div.videoWrapper
con una proporción 4:3.
.chrome_25 Esta clase le da espacio al contenedor que tiene 25 píxeles de alto.
.chrome_35 Esta clase le da espacio al contenedor que tiene 35 píxeles de alto.
El Problema con la Validación#section6
Cuando se trata de videos, soportar estándares web no es cosa fácil. Primero, la mayoría de los provedores no codifican et’s (símbolo &). Aún más comúnmente, la mayoría depende del método twice-cooked(Utilizando el elemento no estándar embed
).
Para lograr que nuestro markup esté acorde al estándar, primero debemos reemplazar todos los et’s en las URLs con “&
”. Luego, debemos implementar un método de único objecto. A diferencia del método de objetos anidados, esta técnica proporciona con un único objeto a los agentes de usuario, como el código de ejemplo siguiente. Ve el ejemplo seis.
<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>
La técnica de único objeto facilita la generación de código según se va “retomando” en un solo lugar el elemento <object>
en vez de en dos lugares <object>
y </object>
.
El Bonus#section7
Puesto que tenemos un elemento posicionado absolutamente dentro de la caja, podemos esconder el contenido “detrás” del video. Nota: este contenido se encuentra fuera del objeto. No es “contenido alternativo” por así decirlo. Mira el ejemplo siete.
<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>
El Enfoque del Script SWFObject#section8
Para automatizar este método, podemos utilizar el script SWFObject para añadir la clase .videoWrapper
que necesitamos para dar estilo y también para conectar el wrapper que necesitamos para IE. Revisa el ejemplo ocho. (Nota: en este último ejemplo, la anchura del bloque contenedor está definida en em
s).
Para añadir el código que necesitamos, reemplazamos la siguiente línea en SWFObject v1.5 (cerca de la línea 117):
n.innerHTML = this.getSWFHTML();
Con las siguientes líneas:
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();
};
Y eso es todo. Con un poco de CSS y tu nuevo know-how, también tú puedes redimensionar y escalar videos sobre la marcha. Ve lo que puedes hacer con el método de proporción intrínseca y comparte tus resultados en los comentarios.
No Comments
More from ALA
En Defensa de los Lectores
Introducción a RDFa (Parte 2)
Trabajando Desde Casa: Los Lectores Responden
Entendiendo la Mejora Progresiva
Mejora Progresiva con Javascript