66

我如何调整图像的大小和重新定位框内的图像,使其覆盖整个框,类似于background-size: cover工作原理。

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

我知道我必须添加overflow:hidden到盒子和图像需要position: absolute。但是,让我获得正确的图像新尺寸和左+上位置的公式是什么?

4

15 回答 15

172

对于它的价值:现在可以单独使用 CSS 来完成......

新的 CSS 属性object-fit当前浏览器支持

刚刚设置object-fit: cover;img

您甚至不需要imgdiv!

小提琴

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>

您可以在此webplatform 文章中阅读有关此新属性的更多信息。

此外,这是上述文章中的一个小提琴object-fit,它演示了该属性的所有值。

于 2014-10-06T14:18:00.620 回答
57

足够接近的纯 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>

于 2016-03-03T23:17:11.453 回答
10

这可能更容易

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}

这应该处理任何大小/方向,并且不仅会调整大小,还会偏移图像。全部无relativeabsolute定位。

做了一个小提琴:http: //jsfiddle.net/filever10/W8aLN/

于 2013-11-04T21:05:58.593 回答
5

同样对于它的价值,可以通过而不是设置“宽度”和“高度”来产生相同的效果(设置它们可能会破坏这种方法):

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;

在父母身上

:)

于 2015-07-25T17:44:41.557 回答
3

这个想法是为图像制作额外的包装器:

<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/

于 2017-01-06T08:06:39.883 回答
2

这是我的方法:

//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'
});

小提琴

于 2013-11-04T21:26:56.807 回答
2

来自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%,无论哪个会在 parent 中创建重叠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/

于 2013-11-04T21:07:39.647 回答
2

这是一个干净的 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
        } );
    } );
} );
于 2017-10-06T04:09:25.860 回答
1

在阅读接受的答案时,令我震惊的是,我们只是测试图像是“肖像”还是“风景”:

   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;
    }
于 2014-08-27T09:21:10.620 回答
1

这是一个纯 CSS 解决方案。您可以定义一个包装器:

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

和img:

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

于 2015-06-20T17:31:47.507 回答
1

您可以将此样式用于图像标记:“object-fit:cover;” 此链接也将为您提供支持https://css-tricks.com/almanac/properties/o/object-fit/

于 2017-01-12T15:13:40.950 回答
0

如果您希望图像在框中居中而不调整图像大小,只需使用以下代码:

.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;.

于 2013-11-04T20:59:04.240 回答
0

对于像我今天所做的那样遇到这个答案的任何人,我正在寻找一个适用于风景、肖像、矩形、正方形等图像和任意容器大小的解决方案,我在下面包含了我自己的代码。

这也将响应式地工作,您只需要在窗口调整大小时再次运行它。

JSF中

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 之类的库来做同样的事情,但我发现这个解决方案更适合我的目的(不增加依赖项,更轻的重量等)。

于 2015-04-21T14:36:45.797 回答
0

我做了一些可以模拟background-size:coverbackground-position:center 的东西。

如果要更改位置,只需更改img的样式“ top ”和“ left ”

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" });
     }
});

此功能应在“加载”和“调整大小”事件时激活。

于 2016-10-10T11:18:26.180 回答
0

我在下面创建了一个应该这样做的函数。我从接受的答案中借用了一些逻辑,并通过为图像尺寸创建一个比率来调整它以与任何容器一起使用:容器尺寸,然后比较哪个更大以找出要调整的尺寸。还添加了一个 'center' 参数('true' 中心,false 将其设置为顶部/左侧)。

我正在使用带有 translateX/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/

于 2015-12-14T13:05:25.347 回答