javascript - online - videos para portada de facebook
simular tamaño de fondo: portada en<video> o<img> (18)
jsFiddle
Usar la cubierta de fondo está bien para las imágenes, al igual que el ancho 100%. Estos no son óptimos para <video>
, y estas respuestas son demasiado complicadas. No necesita jQuery o JavaScript para lograr un fondo de video completo.
Tenga en cuenta que mi código no cubrirá completamente un fondo con un video como lo hará la cubierta, sino que hará que el video sea lo más grande posible para mantener la relación de aspecto y cubrir todo el fondo. Cualquier exceso de video saldrá por el borde de la página, cuyos lados dependen de dónde anclas el video.
La respuesta es bastante simple.
Solo use este código de video HTML5 o algo similar a esto: (prueba en la página completa)
html, body {
width: 100%;
height:100%;
overflow:hidden;
}
#vid{
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1000;
overflow: hidden;
}
<video id="vid" video autobuffer autoplay>
<source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
La altura mínima y el ancho mínimo permitirán que el video mantenga la relación de aspecto del video, que generalmente es la relación de aspecto de cualquier navegador normal a una resolución normal. Cualquier exceso de video sangra por el costado de la página.
¿Cómo puedo simular la funcionalidad del background-size:cover
de background-size:cover
en un elemento html como <video>
o <img>
?
Me gustaría que funcionara como
background-size: cover;
background-position: center center;
Acabo de resolver esto y quería compartir. Esto funciona con Bootstrap 4. Funciona con img
pero no lo probé con video
. Aquí está el HAML y SCSS
HAML
.container
.detail-img.d-flex.align-items-center
%img{src: ''http://placehold.it/1000x700''}
SCSS
.detail-img { // simulate background: center/cover
max-height: 400px;
overflow: hidden;
img {
width: 100%;
}
}
/* simulate background: center/cover */
.center-cover {
max-height: 400px;
overflow: hidden;
}
.center-cover img {
width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="center-cover d-flex align-items-center">
<img src="http://placehold.it/1000x700">
</div>
</div>
Así es como hice esto. Un ejemplo de trabajo es en este jsFiddle .
var min_w = 300; // minimum video width allowed
var vid_w_orig; // original video dimensions
var vid_h_orig;
jQuery(function() { // runs after DOM has loaded
vid_w_orig = parseInt(jQuery(''video'').attr(''width''));
vid_h_orig = parseInt(jQuery(''video'').attr(''height''));
$(''#debug'').append("<p>DOM loaded</p>");
jQuery(window).resize(function () { resizeToCover(); });
jQuery(window).trigger(''resize'');
});
function resizeToCover() {
// set the video viewport to the window size
jQuery(''#video-viewport'').width(jQuery(window).width());
jQuery(''#video-viewport'').height(jQuery(window).height());
// use largest scale factor of horizontal/vertical
var scale_h = jQuery(window).width() / vid_w_orig;
var scale_v = jQuery(window).height() / vid_h_orig;
var scale = scale_h > scale_v ? scale_h : scale_v;
// don''t allow scaled width < minimum video width
if (scale * vid_w_orig < min_w) {scale = min_w / vid_w_orig;};
// now scale the video
jQuery(''video'').width(scale * vid_w_orig);
jQuery(''video'').height(scale * vid_h_orig);
// and center it by scrolling the video viewport
jQuery(''#video-viewport'').scrollLeft((jQuery(''video'').width() - jQuery(window).width()) / 2);
jQuery(''#video-viewport'').scrollTop((jQuery(''video'').height() - jQuery(window).height()) / 2);
// debug output
jQuery(''#debug'').html("<p>win_w: " + jQuery(window).width() + "</p>");
jQuery(''#debug'').append("<p>win_h: " + jQuery(window).height() + "</p>");
jQuery(''#debug'').append("<p>viewport_w: " + jQuery(''#video-viewport'').width() + "</p>");
jQuery(''#debug'').append("<p>viewport_h: " + jQuery(''#video-viewport'').height() + "</p>");
jQuery(''#debug'').append("<p>video_w: " + jQuery(''video'').width() + "</p>");
jQuery(''#debug'').append("<p>video_h: " + jQuery(''video'').height() + "</p>");
jQuery(''#debug'').append("<p>vid_w_orig: " + vid_w_orig + "</p>");
jQuery(''#debug'').append("<p>vid_h_orig: " + vid_h_orig + "</p>");
jQuery(''#debug'').append("<p>scale: " + scale + "</p>");
};
#video-viewport {
position: absolute;
top: 0;
overflow: hidden;
z-index: -1; /* for accessing the video by click */
}
#debug {
position: absolute;
top: 0;
z-index: 100;
color: #fff;
font-size: 12pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="video-viewport">
<video autoplay controls preload width="640" height="360">
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"type="video/mp4" />
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.webm"type="video/webm" />
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.ogv"type="video/webm" />
</video>
</div>
<div id="debug"></div>
CSS y pequeñas js pueden hacer que el video cubra el fondo y se centre horizontalmente.
CSS:
video#bgvid {
position: absolute;
bottom: 0px;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1;
overflow: hidden;
}
JS: (enlaza esto con el tamaño de ventana y llama una vez por separado)
$(''#bgvid'').css({
marginLeft : ''-'' + ($(''#bgvid'').width()/2) + ''px''
})
Chicos, tengo una mejor solución, es corta y me funciona perfectamente. Lo usé para video. Y emula perfectamente la opción de portada en css.
Javascript
$(window).resize(function(){
//use the aspect ration of your video or image instead 16/9
if($(window).width()/$(window).height()>16/9){
$("video").css("width","100%");
$("video").css("height","auto");
}
else{
$("video").css("width","auto");
$("video").css("height","100%");
}
});
Si voltea el if, de lo contrario obtendrá contenido.
Y aquí está el CSS. (No necesita usarlo si no desea el posicionamiento central, el div principal debe ser " posición: relativa ")
CSS
video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}
En base a las respuestas y comentarios de Daniel de Wit , busqué un poco más. Gracias a él por la solución.
La solución es usar object-fit: cover;
que tiene un gran support (todo el mundo está fuera de IE y Edge, pero actualmente está en consideration ). Si desea soportar IE y Edge, puede usar un polyfill como object-fit-images o github.com/anselmh/object-fit .
Demos:
img {
float: left;
width: 100px;
height: 80px;
border: 1px solid black;
margin-right: 1em;
}
.fill {
object-fit: fill;
}
.contain {
object-fit: contain;
}
.cover {
object-fit: cover;
}
.none {
object-fit: none;
}
.scale-down {
object-fit: scale-down;
}
<img class="fill" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="contain" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="cover" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="none" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="scale-down" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
y con un padre:
div {
float: left;
width: 100px;
height: 80px;
border: 1px solid black;
margin-right: 1em;
}
img {
width: 100%;
height: 100%;
}
.fill {
object-fit: fill;
}
.contain {
object-fit: contain;
}
.cover {
object-fit: cover;
}
.none {
object-fit: none;
}
.scale-down {
object-fit: scale-down;
}
<div>
<img class="fill" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="contain" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="cover" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="none" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="scale-down" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div>
Este enfoque solo usa css y html. En realidad puedes apilar un divs debajo del video fácilmente. Es tapa pero no centrado mientras cambias de tamaño.
HTML:
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</script>
</head>
<body>
<div id = "contain">
<div id="vid">
<video autoplay>
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4" />
</video>
</div>
</div>
</body>
</html>
CCS:
/*
filename:style.css
*/
body {
margin:0;
}
#vid video{
position: absolute;
right: 0;
top: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
}
#contain {
width:100%;
height:100%;
zoom:1%;/*Without this the video will be stretched and skewed*/
}
Esto es algo de lo que me saqué el pelo por un tiempo, pero encontré una gran solución que no usa ningún script, y puedo lograr una simulación de cubierta perfecta en video con 5 líneas de CSS (9 si cuentas selectores y corchetes) ) Esto tiene 0 edge-cases en los que no funciona perfectamente, salvo la compatibilidad con CSS3 .
Puedes ver un ejemplo aquí
El problema con la solución de Timothy es que no maneja la escala correctamente. Si el elemento circundante es más pequeño que el archivo de video, no se reduce. Incluso si le da un pequeño tamaño inicial a la etiqueta de video, como 16px por 9px, auto
termina forzándolo a un mínimo de su tamaño de archivo nativo. Con la solución actual de mayor votación en esta página, me fue imposible reducir la escala del archivo de video, lo que resultó en un efecto de zoom drástico.
Sin embargo, si se conoce la relación de aspecto de su video, como 16: 9, puede hacer lo siguiente:
.parent-element-to-video {
overflow: hidden;
}
video {
height: 100%;
width: 177.77777778vh; /* 100 * 16 / 9 */
min-width: 100%;
min-height: 56.25vw; /* 100 * 9 / 16 */
}
Si el elemento principal del video está configurado para cubrir toda la página (como la position: fixed; width: 100%; height: 100vh;
), el video también lo hará.
Si también desea que el video se centre, puede usar el enfoque de centrado seguro:
/* merge with above css */
.parent-element-to-video {
position: relative; /* or absolute or fixed */
}
video {
position: absolute;
left: 50%; /* % of surrounding element */
top: 50%;
transform: translate(-50%, -50%); /* % of current element */
}
Por supuesto, vw
, vh
y transform
son CSS3, por lo que si necesita compatibilidad con navegadores mucho más antiguos , necesitará usar script.
Justo después de nuestra larga sección de comentarios, creo que esto es lo que estás buscando, está basado en jQuery:
HTML:
<img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">
JS:
<script type="text/javascript">
window.onload = function(){
var img = document.getElementById(''img'')
if(img.clientHeight<$(window).height()){
img.style.height=$(window).height()+"px";
}
if(img.clientWidth<$(window).width()){
img.style.width=$(window).width()+"px";
}
}
</script>
CSS:
body{
overflow: hidden;
}
El código de arriba está usando el ancho y alto de los navegadores si haces esto dentro de un div, deberías cambiarlo a algo como esto:
Para Div:
HTML:
<div style="width:100px; max-height: 100px;" id="div">
<img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">
</div>
JS:
<script type="text/javascript">
window.onload = function(){
var img = document.getElementById(''img'')
if(img.clientHeight<$(''#div'').height()){
img.style.height=$(''#div'').height()+"px";
}
if(img.clientWidth<$(''#div'').width()){
img.style.width=$(''#div'').width()+"px";
}
}
</script>
CSS:
div{
overflow: hidden;
}
También debo decir que solo he probado esto es Google Chrome ... aquí hay un jsfiddle: http://jsfiddle.net/ADCKk/
La respuesta principal no reduce el tamaño del video cuando estás a un ancho de navegador inferior al ancho de tu video. Intenta usar este CSS (con #bgvid como la identificación de tu video):
#bgvid {
position: fixed;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
}
Las otras respuestas fueron buenas pero implican javascript o no centran el video horizontalmente Y verticalmente.
Puede usar esta solución completa de CSS para tener un video que simule el tamaño de fondo: propiedad de portada:
video {
position: fixed; // Make it full screen (fixed)
right: 0;
bottom: 0;
z-index: -1; // Put on background
min-width: 100%; // Expand video
min-height: 100%;
width: auto; // Keep aspect ratio
height: auto;
top: 50%; // Vertical center offset
left: 50%; // Horizontal center offset
-webkit-transform: translate(-50%,-50%);
-moz-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%); // Cover effect: compensate the offset
background: url(bkg.jpg) no-repeat; // Background placeholder, not always needed
background-size: cover;
}
Para responder el comentario de weotch que la respuesta de no explica el centrado de la cover
del fondo, ofrezco esta solución rápida de CSS:
CSS:
margin-left: 50%;
transform: translateX(-50%);
Agregar estas dos líneas centrará cualquier elemento. Aún mejor, todos los navegadores que pueden manejar video HTML5 también admiten transformaciones CSS3, así que esto siempre funcionará.
El CSS completo se ve así.
#video-background {
position: absolute;
bottom: 0px;
right: 0px;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1000;
overflow: hidden;
margin-left: 50%;
transform: translateX(-50%);
}
Habría comentado directamente la respuesta de Timothy, pero no tengo suficiente reputación para hacerlo.
También estoy publicando esta solución, ya que tuve este problema pero las otras soluciones no funcionaron para mi situación ...
creo que para simular correctamente el background-size:cover;
css en un elemento en lugar de una propiedad de imagen de fondo de elementos, tendría que comparar la relación de aspecto de las imágenes con la relación de aspecto de las ventanas actuales, por lo que no importa qué tamaño (y también si la imagen es más alta que más ancha) es el elemento que llena la ventana (y también lo centra, aunque no sé si era un requisito) ...
usando una imagen, solo por simplicidad, estoy seguro de que un elemento de video también funcionaría bien.
primero obtenga la relación de aspecto de los elementos (una vez que esté cargada), luego conecte el manejador de cambio de tamaño de la ventana, actívelo una vez para el tamaño inicial:
var img = document.getElementById( "background-picture" ),
imgAspectRatio;
img.onload = function() {
// get images aspect ratio
imgAspectRatio = this.height / this.width;
// attach resize event and fire it once
window.onresize = resizeBackground;
window.onresize();
}
luego, en su controlador de cambio de tamaño primero debe determinar si se debe rellenar el ancho o el alto de relleno comparando la relación de aspecto actual de la ventana con la relación de aspecto original de la imagen.
function resizeBackground( evt ) {
// get window size and aspect ratio
var windowWidth = window.innerWidth,
windowHeight = window.innerHeight;
windowAspectRatio = windowHeight / windowWidth;
//compare window ratio to image ratio so you know which way the image should fill
if ( windowAspectRatio < imgAspectRatio ) {
// we are fill width
img.style.width = windowWidth + "px";
// and applying the correct aspect to the height now
img.style.height = (windowWidth * imgAspectRatio) + "px";
// this can be margin if your element is not positioned relatively, absolutely or fixed
// make sure image is always centered
img.style.left = "0px";
img.style.top = (windowHeight - (windowWidth * imgAspectRatio)) / 2 + "px";
} else { // same thing as above but filling height instead
img.style.height = windowHeight + "px";
img.style.width = (windowHeight / imgAspectRatio) + "px";
img.style.left = (windowWidth - (windowHeight / imgAspectRatio)) / 2 + "px";
img.style.top = "0px";
}
}
Una vieja pregunta, pero en caso de que alguien vea esto, la mejor respuesta en mi opinión es convertir el video en un GIF animado. Esto le da mucho más control y puede tratarlo como una imagen. También es la única forma de que funcione en dispositivos móviles, ya que no puede reproducir videos automáticamente. Sé que la pregunta es pedir que lo haga en una etiqueta <img>
, pero realmente no veo la desventaja de usar un <div>
y hacer background-size: cover
object-fit: cover
es la mejor respuesta con este IE, Safari polyfill.
https://github.com/constancecchen/object-fit-polyfill
Es compatible con img
, video
y elementos de picture
.
@Hidden Hobbes
Esta pregunta tiene una recompensa abierta por valor de +100 reputación de Hidden Hobbes que termina en 6 días. Uso inventivo de unidades de ventana gráfica para obtener una solución flexible única de CSS.
Usted abrió una recompensa sobre esta pregunta para una solución de solo CSS, así que lo intentaré. Mi solución a un problema como este es usar una proporción fija para decidir el alto y el ancho del video. Normalmente uso Bootstrap, pero extraje el CSS necesario para que funcione sin él. Este es un código que he usado anteriormente para centrar un video embebido con la proporción correcta. Debería funcionar también para los elementos <video>
y <img>
Es el más relevante aquí, pero también te di los otros dos porque ya los tenía puestos. ¡La mejor de las suertes! :)
jsfiddle pantalla completa ejemplo
.embeddedContent.centeredContent {
margin: 0px auto;
}
.embeddedContent.rightAlignedContent {
margin: auto 0px auto auto;
}
.embeddedContent > .embeddedInnerWrapper {
position:relative;
display: block;
padding: 0;
padding-top: 42.8571%; /* 21:9 ratio */
}
.embeddedContent > .embeddedInnerWrapper > iframe {
position: absolute;
top: 0;
left: 0;
bottom: 0;
height: 100%;
width: 100%;
border: 0;
}
.embeddedContent {
max-width: 300px;
}
.box1text {
background-color: red;
}
/* snippet from Bootstrap */
.container {
margin-right: auto;
margin-left: auto;
}
.col-md-12 {
width: 100%;
}
<div class="container">
<div class="row">
<div class="col-md-12">
Testing ratio AND left/right/center align:<br />
<div class="box1text">
<div class="embeddedContent centeredContent">
<div class="embeddedInnerWrapper">
<iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&jqoemcache=eE9xf" width="425"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
Testing ratio AND left/right/center align:<br />
<div class="box1text">
<div class="embeddedContent rightAlignedContent">
<div class="embeddedInnerWrapper">
<iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&jqoemcache=eE9xf" width="425"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
Testing ratio AND left/right/center align:<br />
<div class="box1text">
<div class="embeddedContent">
<div class="embeddedInnerWrapper">
<iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&jqoemcache=eE9xf" width="425"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
La solución de M-Pixel es excelente ya que resuelve el problema de escalado de la respuesta de Timothy (el video se ampliará pero no bajará, por lo que si el video es muy grande, hay buenas posibilidades de que solo vea un pequeño zoom en parte). Sin embargo, esa solución se basa en suposiciones falsas relacionadas con el tamaño del contenedor de video, es decir, que es necesariamente el 100% del ancho y alto de la ventana gráfica. He encontrado algunos casos en los que no funcionó, así que decidí abordar el problema yo mismo, y creo que se me ocurrió la solución definitiva .
HTML
<div class="parent-container">
<div class="video-container">
<video width="1920" height="1080" preload="auto" autoplay loop>
<source src="video.mp4" type="video/mp4">
</video>
</div>
</div>
CSS
.parent-container {
/* any width or height */
position: relative;
overflow: hidden;
}
.video-container {
width: 100%;
min-height: 100%;
position: absolute;
left: 0px;
/* center vertically */
top: 50%;
-moz-transform: translate(0%, -50%);
-ms-transform: translate(0%, -50%);
-webkit-transform: translate(0%, -50%);
transform: translate(0%, -50%);
}
.video-container::before {
content: "";
display: block;
height: 0px;
padding-bottom: 56.25%; /* 100% * 9 / 16 */
}
.video-container video {
width: auto;
height: 100%;
position: absolute;
top: 0px;
/* center horizontally */
left: 50%;
-moz-transform: translate(-50%, 0%);
-ms-transform: translate(-50%, 0%);
-webkit-transform: translate(-50%, 0%);
transform: translate(-50%, 0%);
}
También se basa en la proporción del video, por lo que si su video tiene una proporción distinta a 16/9, querrá cambiar el% de relleno inferior. Aparte de eso, funciona de la caja. Probado en IE9 +, Safari 9.0.1, Chrome 46 y Firefox 41.
EDITAR (17 de marzo de 2016)
Desde que publiqué esta respuesta, he escrito un pequeño módulo de CSS para simular tanto el background-size: cover
background-size: contain
de <video>
: http://codepen.io/benface/pen/NNdBMj
Admite diferentes alineaciones para el video (similar a background-position
). También tenga en cuenta que la implementación contenida no es perfecta. A diferencia background-size: contain
, no escalará el video más allá de su tamaño real si el ancho y la altura del contenedor son más grandes, pero creo que todavía puede ser útil en algunos casos. También agregué clases especiales fill-width
fill-height
que puedes usar junto con contain
para obtener una combinación especial de contain
y cover
... ¡pruébalo y siéntete libre de mejorarlo!