Is there an equivalent to background-size: cover a

2019-01-02 16:51发布

I have a site with many pages and different background pictures, and I display them from CSS like:

body.page-8 {
    background: url("../img/pic.jpg") no-repeat scroll center top #000;
    background-size: cover;
}

However, I want to show different (fullscreen) pictures on one page using <img> elements, and I want them to have the same properties as the above background-image: cover; property (the images cant be displayed from CSS, they must be displayed from the HTML document).

Normally I use:

div.mydiv img {
    width: 100%;
}

Or:

div.mydiv img {
    width: auto;
}

to make the picture full and responsive. However the picture shrinks too much (width: 100%) when the screen gets too narrow, and shows the body's background-color in the bottom screen. The other method, width: auto;, only makes the image full size and does not respond to the screen size.

Is there a way to display the image the same way that background-size: cover does?

14条回答
其实,你不懂
2楼-- · 2019-01-02 17:21

With CSS you can simulate object-fit: [cover|contain];. It's use transform and [max|min]-[width|height]. It's not perfect. That not work in one case: if the image is wider and shorter than the container.

.img-ctr{
  background: red;/*visible only in contain mode*/
  border: 1px solid black;
  height: 300px;
  width: 600px;
  overflow: hidden;
  position: relative;
  display: block;
}
.img{
  display: block;

  /*contain:*/
  /*max-height: 100%;
  max-width: 100%;*/
  /*--*/

  /*cover (not work for images wider and shorter than the container):*/
  min-height: 100%;
  width: 100%;
  /*--*/

  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<p>Large square:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x1000"></span>
</p>
<p>Small square:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x100"></span>
</p>
<p>Large landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/2000x1000"></span>
</p>
<p>Small landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x100"></span>
</p>
<p>Large portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x2000"></span>
</p>
<p>Small portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x200"></span>
</p>
<p>Ultra thin portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x1000"></span>
</p>
<p>Ultra wide landscape (images wider and shorter than the container):
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x200"></span>
</p>

查看更多
梦该遗忘
3楼-- · 2019-01-02 17:22

Try setting both min-height and min-width, with display:block:

img {
    display:block;
    min-height:100%;
    min-width:100%;
}

(fiddle)

Provided your image's containing element is position:relative or position:absolute, the image will cover the container. However, it will not be centred.

You can easily centre the image if you know whether it will overflow horizontally (set margin-left:-50%) or vertically (set margin-top:-50%). It may be possible to use CSS media queries (and some mathematics) to figure that out.

查看更多
与风俱净
4楼-- · 2019-01-02 17:25

There is actually quite a simple css solution which even works on IE8:

.container {
  position: relative;
  overflow: hidden;
  /* Width and height can be anything. */
  width: 50vw;
  height: 50vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  /* The following values determine the exact image behaviour. */
  /* You can simulate background-size: cover/contain/etc.
     by changing between min/max/standard width/height values.
     These values simulate background-size: cover
  */
  min-width: 100%;
  min-height: 100%;
}
<div class="container">
    <img src="http://placehold.it/200x200" alt="" />
</div>

查看更多
爱死公子算了
5楼-- · 2019-01-02 17:25

No, you can't get it quite like background-size:cover but..

This approach is pretty damn close: it uses JavaScript to determine if the image is landscape or portrait, and applies styles accordingly.

JS

 $('.myImages img').load(function(){
        var height = $(this).height();
        var width = $(this).width();
        console.log('widthandheight:',width,height);
        if(width>height){
            $(this).addClass('wide-img');
        }else{
            $(this).addClass('tall-img');
        }
    });

CSS

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

http://jsfiddle.net/b3PbT/

查看更多
初与友歌
6楼-- · 2019-01-02 17:26

For IE you also need to include the second line - width: 100%;

.mydiv img {
    max-width: 100%;
    width: 100%;
}
查看更多
梦醉为红颜
7楼-- · 2019-01-02 17:32

Assuming you can arrange to have a container element you wish to fill, this appears to work, but feels a bit hackish. In essence, I just use min/max-width/height on a larger area and then scale that area back into the original dimensions.

.container {
  width: 800px;
  height: 300px;
  border: 1px solid black;
  overflow:hidden;
  position:relative;
}
.container.contain img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  max-width: 10%;
  max-height: 10%;
  -webkit-transform:scale(10);
  transform: scale(10);
}
.container.cover img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  min-width: 1000%;
  min-height: 1000%;
  -webkit-transform:scale(0.1);
  transform: scale(0.1);
}
<h1>contain</h1>
  <div class="container contain">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>
  <h1>cover</h1>
  <div class="container cover">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>

查看更多
登录 后发表回答