Fer
Fer

Reputation: 4196

Is there an img (javascript) equivalent to background-size:cover?

I'm working on a responsive design that showcases photos in a grid. The photos themselves can be in all aspect ratios and sizes. Furthermore, the grid cells in which they are placed are also not of a fixed width, they scale as you resize the browser. Further, each grid cell, although dynamic in width and height, is of the same size, regardless of the image inside it.

To properly show photos in this highly dynamic situation, I have found a working recipe: each photo is basically a div with the image set as the background image. To properly scale the unknown width/height of the image inside a dynamically sized grid, I'm making use of CSS3's background-size:cover feature.

The end result is fabulous, it does exactly what I want in terms of UI and display. Still, I'm not pleased with the reduced accessibility of this solution: it's not SEO friendly and not plugin friendly (think of social plugins). Therefore, I'm trying to reproduce the working situation I have but this time using good old img tags instead of CSS backgrounds.

I know there are IE8 and below polyfills for background-size:cover, but I'm not looking for that, I'm looking for a solution based on img tags. I also found articles using absolute positioning techniques as well as CSS's clip property, but keep in mind nothing about my design is absolute in size.

I guess what I'm looking for is a javascript routine that has the logic of background-size:cover for dynamic sizing, in a situation where both the source (image dimensions) and target (display box) are dynamic in size.

Is there such a javascript equivalent to background-size:cover that works on img tags?

Upvotes: 8

Views: 5301

Answers (4)

opohjola
opohjola

Reputation: 9

I found a nice way to cover a container with an image using css and javascript:

HTML:

<div class="container">
  <img src="image.jpg"/>
</div>

CSS:

img {
  position: absolute;
  min-width: 100%;   // To cover container
  min-height: 100%;  // To cover container
  top: 50%;          // To move image corner to center of container
  left: 50%;         // To move image corner to center of container
}

Javascript:

$('img').css({
  'margin-top': -$('img').height()/2,   // To move to center of image
  'margin-left': -$('img').width()/2    // To move to center of image
});

Make sure to run the javascript after image has loaded.

Upvotes: 0

phazei
phazei

Reputation: 5438

This is old, but I recently found a novel solution.

Instead of making the img you want to display the background image of a div, create an image:

<div>
    <img src="mypic.jpg"/>
</div>
<style>
    div {
        width:200px;
        height:200px;
    }
    img {
        box-sizing:border-box;
        width:100%;
        height:100%;
        background: url(mypic.jpg) no-repeat center center;
        background-size:cover;
        padding:50%;
    }
</style>

Set a containing div to be the width/height you want the image. Then put the image inside as 100% width/height and set the src to the img you want. Also set the img you want as the background image of the img. Set the background-size to cover, and the padding at 50%.

The trick is the padding at 50%. The img width/height is fixed, so as you increase the padding, the image gets smaller and smaller. 50% is exactly how much is needed for it to be hidden, and now you just see the background image of the image displayed how you want, but it's still accessible!

http://jsfiddle.net/t72xgbw0/

Upvotes: 4

miguelr
miguelr

Reputation: 1344

Thinking of accesibility and SEO, I created a solution to a very similar problem using jQuery, it doesn't reproduce the logic of background cover, it makes use of it.

The images in fact become the role of the container with the background and the background cover gets added programatically.

$imagesContainer.find('img').each(function(i, elem){
  $(elem).css({
    backgroundSize : 'cover',
    backgroundImage : 'url("' + $(elem).attr('src') + '")',
    backgroundPosition : 'center',
    display : 'block',
    height : '100%', // Or any size needed.
    width : '100%'
  });
  $(elem).removeAttr('src');
});

Upvotes: 2

joehand
joehand

Reputation: 391

I believe there are two things you want to do:

  1. Have an image fill the window
  2. Make sure the image is centered vertically and horizontally.

The trouble is (if you want to keep the aspect ratio of the image) is that you have to both center it vertically and horizontally depending on the image and browser size.

You can make a pure CSS solution using a combination of display:table and margin:0 auto, along with smart height/width settings.

See the fiddle: http://jsfiddle.net/5yVYM/3/

.wrapper {
    display:table;
    text-align: center;
    margin:0 auto;
    width:100%;
    height:100%;
}

.wrapper div {
    display:table-cell;
    vertical-align:middle;
    max-width:100%;
    max-height:100%;
}

img {
    width:100%;
    height:auto;
}

Upvotes: -1

Related Questions