style fit div color javascript jquery math background-size

javascript - div - css background image size to fit



Cómo emular el fondo de pantalla: ¿tapa en<img>? (15)

¿Cómo puedo redimensionar y reposicionar la imagen dentro de un cuadro, de modo que cubra todo el cuadro, de forma similar a cómo funciona el background-size: cover ?

<div class="box" style="width: 100px; height: 100px;"> <img src="pic.jpg" width="413" height="325"> </div>

Sé que tengo que agregar el overflow:hidden al cuadro y la imagen necesita una position: absolute . ¿Pero cuál es la fórmula que me da el nuevo tamaño correcto para la imagen, y las posiciones superiores izquierda +?


Aquí está mi enfoque:

//collect the nodes var parent = $(''.box''); var img = $(''image'', box); //remove width and height attributes img.removeAttr(''width''); img.removeAttr(''height''); //set initial width img.attr(''width'', parent.width()); //if it''s not enough, increase the width according to the height difference if (img.height() < parent.height()) { img.css(''width'', img.width() * parent.height() / img.height()); } //position the image in the center img.css({ left: parseInt((img.width() - parent.width())/-2) + ''px'', top: parseInt((img.height() - parent.height())/-2) + ''px'' });

FIDDLE


Aquí hay una función de JavaScript limpia para hacer esto y un ejemplo de implementación:

function backgroundCover(elementSizes, containerSizes) { var elementRatio = elementSizes.width / elementSizes.height, containerRatio = containerSizes.width / containerSizes.height; width = null, height = null; if (containerRatio > elementRatio) { width = Math.ceil( containerSizes.width ); height = Math.ceil( containerSizes.width / elementRatio ); } else { width = Math.ceil( containerSizes.height * elementRatio ); height = Math.ceil( containerSizes.height ); } return { width, height }; }

Aquí hay un ejemplo de implementación:

HTML

<!-- Make sure the img has width and height attributes. The original image''s width and height need to be set in order to calculate the scale ratio. --> <div class="photo"><img src="photo.jpg" width="400" height="300"></div>

CSS

.photo { position: relative; overflow: hidden; width: 200px; padding-bottom: 75%; /* CSS technique to give this element a 4:3 ratio. */ } .photo img { position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); }

JavaScript

$( window ).on( ''resize'', function() { $( ''.cover-photo'' ).each( function() { var img = $( ''img'', this ), imgWidth = img.attr( ''width'' ), imgHeight = img.attr( ''height'' ), containerWidth = $( this ).width(), containerHeight = $( this ).height(), newSizes = backgroundCover( { width: imgWidth, height: imgHeight }, { width: containerWidth, height: containerHeight } ); img.css( { width: newSizes.width, height: newSizes.height } ); } ); } );


Creé una función a continuación que debería hacerlo. Tomé prestada parte de la lógica de la respuesta aceptada y la ajusté para que funcione con cualquier contenedor creando una relación para la dimensión de la imagen: dimensión del contenedor y luego comparé cuál es mayor para calcular qué dimensión ajustar. También se agregó un argumento ''centro'' (''verdadero'' centros, falso lo establece arriba / izquierda).

Estoy usando CSS3 con translateX / Y, pero podría hacerlo funcionar sin suficiente facilidad.

Aquí está el código:

var coverImage = function(wrap, center) { if (typeof center === ''undefined'') { center = true; } var wr = $(wrap), wrw = wr.width(), wrh = wr.height(); var im = wr.children(''img''), imw = im.width(), imh = im.height(); var wratio = wrw / imw; var hratio = wrh / imh; //Set required CSS wr.css({''overflow'' : ''hidden''}); im.css({''position'' : ''relative''}); if (wratio > hratio) { im.width(wrw); im.css({''height'' : ''auto''}); if (center) { im.css({ ''top'' : ''50%'', ''transform'' : ''translateY(-50%)'' }); } } else { im.height(wrh); im.css({''width'' : ''auto''}); if (center) { im.css({ ''left'' : ''50%'', ''transform'' : ''translateX(-50%)'' }); } } }

y revise el jsfiddle para verlo en acción: https://jsfiddle.net/cameronolivier/57nLjoyq/2/


Desde https://developer.mozilla.org/en-US/docs/Web/CSS/background-size :

cover This keyword specifies that the background image should be scaled to be as small as possible while ensuring both its dimensions are greater than or equal to the corresponding dimensions of the background positioning area.

Entonces, estás buscando hacer el width: 100% o la height: 100% , lo que creará una superposición dentro del div principal. Entonces podemos usar la siguiente lógica:

var makeBackgroundCover = function (div) { $(div + " img").css("height", "100%"); if ($(div + " img").width() < $(div).width()) { $(div + " img").css({ "height": "auto", "width": "100%" }); } }

El siguiente violín muestra esta función trabajando tanto en una imagen horizontal como vertical.

http://jsfiddle.net/2r5Cb/


Esta es una solución pura de CSS. Puede definir un contenedor con:

div.cover { position: fixed; top: -50%; left: -50%; width: 200%; height: 200%; }

y el img:

img.cover { position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; min-width: 50%; min-height: 50%; overflow-x: hidden; }

Aquí el ejemplo en vivo:

http://codepen.io/ErwanHesry/pen/JcvCw


Hice algo que podría funcionar para emular un fondo de tamaño: portada y posición de fondo: centro .

Si desea cambiar la posición simplemente cambie los estilos " arriba " y " izquierda " de la img

CSS

.box{ overflow:hidden; position:relative; } .box img{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); }

JS

$(''.box'').each(function() { //aspect ratio of container var boxRatio = $(this).height() / $(this).width(); //aspect ration of image var imageRatio = $(this).children(''img'').height() / $(this).children(''img'').width(); //set width or height 100% depend of difference if (imageRatio > boxRatio) { $(this).children(''img'').css({"width":"100%","height":"auto"}); } else { $(this).children(''img'').css({"height":"100%","width":"auto" }); } });

Esta función debe activarse en eventos de "carga" y "cambio de tamaño".


La idea es crear un contenedor adicional para la imagen:

<div class="wrap"> <div class="inner"> <img src="http://placehold.it/350x150"> </div> </div>

Y usa dicho CSS:

.wrap { position: relative; width: 100%; height: 200px; background: rgba(255, 0, 0, 0.3); overflow: hidden; } .inner { position: absolute; min-width: 100%; height: 100%; left: 50%; -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); -webkit-transform: translateX(-50%); transform: translateX(-50%); } .inner img { position: absolute; min-height: 100%; min-width: 100%; top: 50%; left: 50%; -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); }

Este es un ejemplo de trabajo: https://jsfiddle.net/kr60jroe/


Lo suficientemente cerca, la solución de CSS puro para la simulación de la cubierta de tamaño de fondo usando la etiqueta img con muy buena compatibilidad con el navegador (IE8 +):

.container { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden; } .container img { position: absolute; top: 50%; left: 50%; width: auto; height: auto; max-height: none; max-width: none; min-height: 100%; min-width: 100%; transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); }

<div class="container"> <img src="//lorempixel.com/400/200/sports/1/" /> </div>


Mientras leo la respuesta aceptada, me parece que simplemente probamos si la imagen es ''retrato'' o ''paisaje'':

if (ih>iw) {//if portrait

En el caso del OP, es correcto. Pero otros podrían estar tratando con rectángulos y deberían tener en cuenta la relación de aspecto del contenedor y la imagen "infantil":

var int_container_width = parseInt( $_container.width() ); var int_container_height = parseInt( $_container.height() ); var num_container_aspect = int_container_width/int_container_height; var int_image_width = parseInt( $_image.width() ); var int_image_height = parseInt( $_image.height()); var num_image_aspect = int_image_width/int_image_height; if ( num_image_aspect > num_container_aspect){ num_scale = int_container_width/int_image_width * 100; } else { num_scale = int_container_height/int_image_height * 100; }


Para cualquiera que encuentre esta respuesta como lo hice hoy buscando una solución que funcione con imágenes de paisajes, retratos, rectángulos, cuadrados, etc. y tamaños de contenedores arbitrarios, he incluido mi propio código a continuación.

Esto también funcionará de manera responsable, solo tendrá que ejecutarlo cada vez que la ventana cambie de tamaño.

JSFiddle :

http://jsfiddle.net/66c43ao1/

HTML

<div class="test"> <div class="cover"> <img src="http://d2ws0xxnnorfdo.cloudfront.net/character/meme/cool-dog.jpg" width="590" height="590"/> </div> </div>

CSS

/* modify the width and height below to demonstrate coverage */ .test { height: 300px; position: relative; width: 500px; } /* you will need the below styles */ .cover { height: 100%; left: 0; overflow: hidden; position: absolute; top: 0; width: 100%; z-index: 1; }

JS

$(''.cover'').each(function() { var containerHeight = $(this).height(), containerWidth = $(this).width(), image = $(this).children(''img''), imageHeight = image.attr(''height''), imageWidth = image.attr(''width''), newHeight = imageHeight, newWidth = imageWidth; if (imageWidth < containerWidth) { // if the image isn''t wide enough to cover the space, scale the width newWidth = containerWidth; newHeight = imageHeight * newWidth/imageWidth; } if (imageHeight < containerHeight) { // if the image isn''t tall enough to cover the space, scale the height newHeight = containerHeight; newWidth = imageWidth * newHeight/imageHeight; } var marginLeft = (newWidth - containerWidth)/2; var marginTop = (newHeight - containerHeight)/2; image.css({ marginLeft : ''-'' + marginLeft + ''px'', marginTop : ''-'' + marginTop + ''px'', height : newHeight, width : newWidth }); });

Por supuesto, puede utilizar bibliotecas como Backstretch que hacen lo mismo, pero esta solución me pareció mejor para mis propósitos (sin aumento de dependencias, menor peso, etc.).


Por lo que vale: esto ahora se puede hacer con CSS solo con ...

El nuevo object-fit propiedad CSS object-fit ( Soporte actual del navegador )

Solo establece object-fit: cover; en el img

¡Ni siquiera necesitas envolver el img en un div !

FIDDLE

img { width: 100px; height: 100px; } .object-fit { display: block; object-fit: cover; } .original { width: auto; height: auto; display: block; }

<img src="http://lorempixel.com/413/325/food" width="413" height="325"> <p>Img ''squashed'' - not good</p> <img class="object-fit" src="http://lorempixel.com/413/325/food" width="413" height="325"> <p>object-fit: cover - The whole image is scaled down or expanded till it fills the box completely, the aspect ratio is maintained. This normally results in only part of the image being visible. </p> <img class="original" src="http://lorempixel.com/413/325/food" width="413" height="325"> <p>Original ing</p>

Puede leer más sobre esta nueva propiedad en este artículo de plataforma web .

Además, aquí hay un violín del artículo anterior que muestra todos los valores de la propiedad de object-fit .



Si desea que la imagen esté centrada en el cuadro sin cambiar el tamaño de la imagen, simplemente use este código:

.box { width: 100px; height: 100px; overflow: hidden; position: relative; } .box img { width: 413px; height: 325px; position: absolute; left: 50%; top: 50%; }

Si está buscando cambiar el tamaño de la imagen para que quepa, use el siguiente código:

.box { width: 100px; height: 100px; } .box img { width: 100%; height: auto; }

Este código dejará algo de espacio en blanco si la imagen es más ancha que alta. Si ninguno de estos funciona, puede simplemente establecer la imagen como fondo y usar background-size: cover; .


También por lo que vale, se puede producir el mismo efecto en lugar de establecer "ancho" y "alto" (configurarlos podría romper este enfoque por cierto):

min-width: 100%; min-height: 100%;

o

min-width: (your desired percent of viewport width)vw; min-height: (your desired percent of viewport height)vh;

con

overflow: hidden;

en el padre

:)


esto puede ser más fácil

jQuery

$(''.box'').each(function() { //set size var th = $(this).height(),//box height tw = $(this).width(),//box width im = $(this).children(''img''),//image ih = im.height(),//inital image height iw = im.width();//initial image width if (ih>iw) {//if portrait im.addClass(''ww'').removeClass(''wh'');//set width 100% } else {//if landscape im.addClass(''wh'').removeClass(''ww'');//set height 100% } //set offset var nh = im.height(),//new image height nw = im.width(),//new image width hd = (nh-th)/2,//half dif img/box height wd = (nw-tw)/2;//half dif img/box width if (nh<nw) {//if portrait im.css({marginLeft: ''-''+wd+''px'', marginTop: 0});//offset left } else {//if landscape im.css({marginTop: ''-''+hd+''px'', marginLeft: 0});//offset top } });

css

.box{height:100px;width:100px;overflow:hidden} .wh{height:100%!important} .ww{width:100%!important}

Esto debería manejar cualquier tamaño / orientación, y no solo cambiará el tamaño, sino que compensará las imágenes. Todo sin posicionamiento relative o absolute .

hecho un violín: http://jsfiddle.net/filever10/W8aLN/