如何模拟背景大小:在<img>上覆盖
How to emulate background-size: cover on <img>?
如何调整框内图像的大小和位置,使其覆盖整个框,类似于background-size: cover
的工作方式。
<div class="box" style="width: 100px; height: 100px;">
<img src="pic.jpg" width="413" height="325">
</div>
我知道我必须在框中添加overflow:hidden
,并且图像需要position: absolute
。但是,是什么公式可以让我为图像提供正确的新尺寸,以及左+顶部位置?
对于它的价值:这现在可以单独使用 CSS 来完成......
新的 CSS 属性对象适合(当前浏览器支持)
只需在img
上设置object-fit: cover;
您甚至不需要将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>
您可以在这篇网络平台文章中阅读有关此新属性的更多信息。
此外,这是上面文章中的小提琴,它演示了 object-fit
属性的所有值。
足够接近的纯CSS解决方案,使用具有非常好的浏览器支持的img标签进行背景尺寸封面模拟(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>
这可能更容易
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}
这应该处理任何大小/方向,并且不仅会调整大小,还会偏移图像。所有这些都没有relative
或absolute
定位。
做了一个小提琴:http://jsfiddle.net/filever10/W8aLN/
同样对于它的价值,可以通过而不是设置"宽度"和"高度"来产生相同的效果(顺便说一句,设置它们可能会破坏这种方法):
min-width: 100%;
min-height: 100%;
或
min-width: (your desired percent of viewport width)vw;
min-height: (your desired percent of viewport height)vh;
跟
overflow: hidden;
在父级上
:)
这个想法是为图像制作额外的包装器:
<div class="wrap">
<div class="inner">
<img src="http://placehold.it/350x150">
</div>
</div>
并使用这样的 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%);
}
这是工作示例:https://jsfiddle.net/kr60jroe/
从 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.
因此,您要么考虑制作width: 100%
,要么考虑height: 100%
,以在父div
中创建重叠为准。所以我们可以使用以下逻辑:
var makeBackgroundCover = function (div) {
$(div + " img").css("height", "100%");
if ($(div + " img").width() < $(div).width()) {
$(div + " img").css({
"height": "auto",
"width": "100%"
});
}
}
下面的小提琴显示了此函数在水平和垂直图像上的工作。
http://jsfiddle.net/2r5Cb/
这是我的方法:
//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'
});
小提琴
这里有一个干净的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 };
}
下面是一个实现示例:
.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
} );
} );
} );
在阅读公认的答案时,我突然想到,我们只是简单地测试图像是"纵向"还是"横向":
if (ih>iw) {//if portrait
在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;
}
这是一个纯粹的 css 解决方案。您可以使用以下命令定义包装器:
div.cover {
position: fixed;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
}
和图像:
img.cover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
min-width: 50%;
min-height: 50%;
overflow-x: hidden;
}
这是现场示例:
http://codepen.io/ErwanHesry/pen/JcvCw
您可以将此样式用于图像标记:"对象适合:封面;"此链接还将支持您 https://css-tricks.com/almanac/properties/o/object-fit/
如果您希望图像在框中居中而不调整图像大小,只需使用以下代码:
.box {
width: 100px;
height: 100px;
overflow: hidden;
position: relative;
}
.box img {
width: 413px;
height: 325px;
position: absolute;
left: 50%;
top: 50%;
}
如果要调整图像大小以适合,请使用以下代码:
.box {
width: 100px;
height: 100px;
}
.box img {
width: 100%;
height: auto;
}
如果图像宽于高度,此代码将留下一些空白。 如果这些都不起作用,您可以将图像设置为背景并使用 background-size: cover;
.
我今天一样遇到这个答案的任何人,他们正在寻找一种适用于横向、纵向、矩形、正方形等图像和任意容器大小的解决方案,我在下面包含了我自己的代码。
这也将以响应方式工作,您只需在窗口调整大小时再次运行它。
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
});
});
您当然可以使用诸如 Backstretch 之类的库来做同样的事情,但我发现这个解决方案更适合我的目的(不增加依赖项、更轻的重量等)。
我在下面创建了一个应该可以做到这一点的函数。我从接受的答案中借用了一些逻辑,并通过为图像尺寸创建一个比率来调整它以适用于任何容器:容器尺寸,然后比较哪个更大以计算要调整的维度。还添加了一个"中心"参数("真"中心,false 将其设置为上/左)。
我正在使用带有翻译X/Y的CSS3,但是可以在没有它的情况下轻松使其工作。
代码如下:
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%)'
});
}
}
}
并查看JSFIDDLE以查看其实际效果:https://jsfiddle.net/cameronolivier/57nLjoyq/2/
我做了一些可以模拟背景大小:封面和背景位置:中心的东西。
如果要更改位置,只需更改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" });
}
});
此功能应在"加载"和"调整大小"事件时激活。
- 在循环中分配json值时,值被覆盖
- 谷歌地图固定位置覆盖
- 如何更改<svg>标记为<img>用js标记
- 有没有一种方法可以防止img get请求使用css或js发生
- 只覆盖箭头键滚动事件
- Javascript:使用绝对路径设置img src
- Setting default onclick behavior for <img> tag in gene
- JQuery覆盖不更改单选选项
- 如何覆盖锚点元素's href目标,并在我点击转到目标javascript时删除其他错误
- 将添加一个相同类型的事件附加或覆盖以前添加的具有相同名称的事件
- 传单中如何在更改基层时启用/禁用覆盖层
- 点击(右键点击)使用传单地图库获取图像覆盖的像素坐标
- HTML/CSS-用于拖放的全页面覆盖
- 让javascript知道epub3电子书中何时播放媒体覆盖
- 如何在页面加载中使用Jquery/Javascript确定img源
- 图像可以从源<img src=""/>.TEXT可以在没有javascript的情况下从外部
- 覆盖函数中的函数
- 无法覆盖CSS伪元素:before
- 在覆盖和关闭按钮或链接中为img添加边框
- 用AngularJS指令覆盖img和a的默认行为