jQuery 如何模拟背景大小:<img> 上的封面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19776670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to emulate background-size: cover on <img>?
提问by Alex
How can I resize and reposition the image inside a box, in such way that it covers the entire box, similar to how background-size: cover
works.
如何调整框内图像的大小和位置,使其覆盖整个框,类似于background-size: cover
工作原理。
<div class="box" style="width: 100px; height: 100px;">
<img src="pic.jpg" width="413" height="325">
</div>
I know I have to add overflow:hidden
to the box and the image needs position: absolute
. But what's the formula that gets me the right new size for the image, and left + top positions?
我知道我必须添加overflow:hidden
到框和图像需要position: absolute
。但是让我获得正确的图像新尺寸和左+顶部位置的公式是什么?
采纳答案by FiLeVeR10
this may be easier
这可能更容易
jQuery
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
css
.box{height:100px;width:100px;overflow:hidden}
.wh{height:100%!important}
.ww{width:100%!important}
This should handle any size/orientation, and will not only resize, but offset the images. All without relative
or absolute
positioning.
这应该处理任何大小/方向,并且不仅会调整大小,还会偏移图像。所有没有relative
或absolute
定位。
made a fiddle: http://jsfiddle.net/filever10/W8aLN/
做了一个小提琴:http: //jsfiddle.net/filever10/W8aLN/
回答by Danield
For what it's worth: this can now be done with CSS alone with...
值得一提的是:现在可以单独使用 CSS 完成...
The new CSS property object-fit(Current browser support)
新的 CSS 属性object-fit(当前浏览器支持)
Just set object-fit: cover;
on the img
只需设置object-fit: cover;
在img
You don't even need to wrap the img
in a div
!
您甚至不需要将 包装img
在div
!
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>
You can read more about this new property in this webplatform article.
您可以在此网络平台文章中阅读有关此新属性的更多信息。
Also, here is a fiddlefrom the above article which demonstrates all the values of the object-fit
property.
此外,这是上述文章中的一个小提琴,它演示了该object-fit
属性的所有值。
回答by Vlatko
Close enough, pure CSS solution for background size cover simulation using img tag with very good browser support (IE8+):
使用具有非常好的浏览器支持(IE8+)的 img 标签进行背景大小覆盖模拟的足够接近的纯 CSS 解决方案:
.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>
回答by SirRodge
Also for what it's worth, the same effect can be produced by instead of setting "width" and "height" (setting them could break this approach btw):
同样对于它的价值,可以通过代替设置“宽度”和“高度”来产生相同的效果(顺便说一下,设置它们可能会破坏这种方法):
min-width: 100%;
min-height: 100%;
min-width: 100%;
min-height: 100%;
or
或者
min-width: (your desired percent of viewport width)vw;
min-height: (your desired percent of viewport height)vh;
min-width: (your desired percent of viewport width)vw;
min-height: (your desired percent of viewport height)vh;
with
和
overflow: hidden;
overflow: hidden;
on the parent
在父母身上
:)
:)
回答by Paulius Kripaitis
The idea is to make additional wrapper for image:
这个想法是为图像制作额外的包装器:
<div class="wrap">
<div class="inner">
<img src="http://placehold.it/350x150">
</div>
</div>
And use such CSS:
并使用这样的 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%);
}
This is working example: https://jsfiddle.net/kr60jroe/
这是工作示例:https: //jsfiddle.net/kr60jroe/
回答by MattDiamant
From https://developer.mozilla.org/en-US/docs/Web/CSS/background-size:
来自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.
So, you're either looking at making the width: 100%
or the height: 100%
, whichever will create an overlap within the parent div
. So we can use the following logic:
因此,您要么正在考虑制作width: 100%
要么height: 100%
,无论哪个都会在 parent 中创建重叠div
。所以我们可以使用以下逻辑:
var makeBackgroundCover = function (div) {
$(div + " img").css("height", "100%");
if ($(div + " img").width() < $(div).width()) {
$(div + " img").css({
"height": "auto",
"width": "100%"
});
}
}
The following fiddle shows this function working on both a horizontal and vertical image.
下面的小提琴显示了这个函数在水平和垂直图像上工作。
回答by matewka
Here is my approach:
这是我的方法:
//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'
});
回答by Ideogram
While reading the accepted answer, it strikes me that we simply test on whether the image is 'portrait' or 'landscape':
在阅读已接受的答案时,让我吃惊的是我们只是简单地测试图像是“纵向”还是“横向”:
if (ih>iw) {//if portrait
In the case of the OP, that's right. But others might be dealing with rectangles and should take the aspect ratio of the container and the 'child'-image into consideration:
在 OP 的情况下,这是正确的。但是其他人可能正在处理矩形,并且应该考虑容器和“子”图像的纵横比:
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;
}
回答by Mohamed Mamdouh
You can use this style to the image tag :"object-fit:cover;" This link will support you also https://css-tricks.com/almanac/properties/o/object-fit/
您可以将此样式用于图像标签 :"object-fit:cover;" 此链接也将为您提供支持https://css-tricks.com/almanac/properties/o/object-fit/
回答by Gavin
Here's a clean JavaScript function to do this and an example of implementation:
这是一个干净的 JavaScript 函数来执行此操作以及一个实现示例:
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 };
}
Here's an example of implementation:
下面是一个实现示例:
HTML
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
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
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
} );
} );
} );