Подтвердить что ты не робот

Как эмулировать размер фона: обложка на <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. Но какая формула дает мне правильный новый размер для изображения, а слева + верхние позиции?

4b9b3361

Ответ 1

это может быть проще

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/

Ответ 2

Для чего это стоит: теперь это можно сделать с помощью CSS наедине с...

Новое соответствие CSS-свойств объекта (текущая поддержка браузера)

Просто установите object-fit: cover; на img

Вам даже не нужно оборачивать img в 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>

Ответ 3

Достаточно близкое, чистое 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>

Ответ 4

Кроме того, для того, что стоит, тот же эффект может быть создан вместо установки "width" и "height" (установка их может нарушить этот подход btw):

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;

на родительском

:)

Ответ 5

Идея состоит в том, чтобы создать дополнительную обертку для изображения:

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

Ответ 6

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

Ответ 7

Вот мой подход:

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

Ответ 8

При чтении принятого ответа мне кажется, что мы просто проверяем, является ли изображение "портретным" или "пейзаж":

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

Ответ 9

Это чистое решение 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

Ответ 10

Здесь приведена чистая функция 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 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
        } );
    } );
} );

Ответ 11

Если вы хотите, чтобы изображение было центрировано в поле без изменения размера изображения, просто используйте этот код:

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

Ответ 12

Для тех, кто сталкивается с этим ответом, как я это делал сегодня, ища решение, которое будет работать с пейзажными, портретными, прямоугольными, квадратными и т.д. изображениями и произвольными размерами контейнеров, я включил свой собственный код ниже.

Это также будет работать оперативно, вам просто нужно будет запускать его снова при каждом изменении размера окна.

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, которые делают то же самое, но я нашел это решение лучше для моих целей (без увеличения зависимостей, более легкого веса и т.д.).

Ответ 13

Я создал функцию ниже, которая должна это сделать. Я позаимствовал некоторую логику из принятого ответа и скорректировал его для работы с любым контейнером, создав соотношение для измерения размера изображения: размер контейнера, а затем сравнив, что больше, чем цифра какое измерение необходимо отрегулировать. Также добавлен аргумент "center" ( "истинные" центры, false устанавливает его вверх/влево).

Я использую CSS3 с translateX/Y, но могу заставить его работать без него достаточно легко.

Здесь код:

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/

Ответ 14

Я сделал что-то, что могло бы сработать для эмуляции фона: обложка и background-position: center.

Если вы хотите изменить позицию, просто измените стили " верх" и слева "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" });
     }
});

Эта функция должна быть активирована при событии "load" и "resize".