web-dev-qa-db-ja.com

background-sizeをエミュレートする方法:<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が必要であることを知っています。しかし、画像の適切な新しいサイズと左+上の位置を取得する式は何ですか?

62
Alex

これは簡単かもしれません

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/

10
FiLeVeR10

それが価値があることについては、これはCSSだけで今や行うことができます...

新しいCSSプロパティ object-fit現在のブラウザーサポート

imgobject-fit: cover;を設定するだけです

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 article をご覧ください。

また、上記の記事の フィドル は、object-fitプロパティのすべての値を示しています。

134
Danield

非常に優れたブラウザサポート(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>
47
Vlatko

また、「幅」と「高さ」を設定する代わりに、同じ効果が得られます(これらを設定すると、このアプローチが壊れる可能性があります)。

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
SirRodge

アイデアは、画像の追加ラッパーを作成することです:

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

3

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

2
MattDiamant

私のアプローチは次のとおりです。

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

フィドル

2
matewka

受け入れられた答えを読んでいる間、イメージが「ポートレート」か「ランドスケープ」かをテストするだけです。

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

これは純粋な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

1
Ruben Rizzi

これを行うためのクリーンな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
        } );
    } );
} );
1
Gavin

このスタイルを画像タグに使用できます: "object-fit:cover;"このリンクはあなたもサポートします https://css-tricks.com/almanac/properties/o/object-fit/

1
Mohamed Mamdouh

background-size:coverbackground-position:center

位置を変更したい場合は、スタイルを変更するだけです "top" an "left "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" });
     }
});

この関数は、「ロード」イベントおよび「サイズ変更」イベントでアクティブにする必要があります。

0
Santi Nunez

私はそれを行うべき以下の関数を作成しました。 受け入れられた答え からいくつかのロジックを借用し、イメージディメンション:コンテナディメンションの比率を作成することにより、任意のコンテナで動作するように調整し、調整するディメンションを計算するために大きい方を比較しました。また、「center」引数を追加しました(「true」センター、falseは上/左に設定します)。

私は、CSS3を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/

0
Cameron

画像のサイズを変更せずに画像をボックスの中央に配置するには、次のコードを使用します。

.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;を使用できます。

0
zsaat14

今日私が風景、ポートレート、長方形、正方形などの画像と任意のコンテナサイズで動作するソリューションを探していたときにこの答えに出くわした人のために、私は以下の独自のコードを含めました。

また、これはレスポンシブに機能します。ウィンドウのサイズが変更されるたびに再度実行するだけです。

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などのライブラリを使用することもできますが、このソリューションの方が私の目的には適していることがわかりました(依存関係の増加、軽量化など)。

0
Heath