fnord12
fnord12

Reputation: 145

Allowing images to shrink, but not stretch

I have a site with 4,000+ pages and 10 or more jpeg images per page, of varying sizes. I'm trying to make the site more mobile friendly. To that end, i want to make it possible for the images to shrink to fit on smaller screens. I know that i can do something like this to signal that the images can shrink:

img.bodyImg
{
 width: 100%;
 max-width: 357px;
 height: auto;
}

But what if not all images have a width of 357 (or whatever), and i don't want smaller images stretched beyond their true dimensions? And just to make things more fun, what if the images tags don't have height and width attributes specified?

My goal is to find a solution that doesn't require me to adjust tens of thousands of image calls manually, but i can do a search and replace. Images are currently wrapped in a div container and have a class, like so:

<div class="imgDiv"><img class="bodyImg" src="http://www.example.com/image.jpg"></div>

I'm also open to the possibility that i'm going about this in the wrong way entirely.

Upvotes: 12

Views: 10889

Answers (4)

Steve
Steve

Reputation: 21

Why not just:

max-width:100%; /*Ensure the width scales to the width of the parent container*/
width:auto; /* Not required, but sometimes is nice to ensure the width not being overridden by other factors like browser quirks */
height: auto; /*Ensure the image keeps its ratio*/

Upvotes: 1

showdev
showdev

Reputation: 29168

Using max-width is simple, effective, and requires no JavaScript.

The CSS below creates responsive images that shrink to fit the container's width but won't expand beyond their native sizes.

img.bodyImg {
    max-width:100%
}

In the demonstration below, both images are 300px X 75px. The first container is 200px wide and the second one is 400px wide. Notice that the first image shrinks to fit in the container, but the second image does not expand beyond its native size. Also note that the proportions of each image remain accurate.

div {
  background-color: #CCC;
  margin:0 0 .5em;
  padding:.25em;
}
div.one {
  width: 200px;
}
div.two {
  width: 400px;
}
img {
  display:block;
  max-width: 100%;
}
<div class="one">
  <img src="http://lorempixel.com/300/75/abstract/4/" />
</div>
<div class="two">
  <img src="http://lorempixel.com/300/75/abstract/4/" />
</div>

Additional Notes

  1. I've included display:block to remove the descender space below the image.
  2. If your images have specific height and width attributes (as they arguably should), you can add height:auto and/or width:auto to override those attributes.
  3. Bootstrap uses this method for responsive images.

Upvotes: 12

Kyle Darin
Kyle Darin

Reputation: 13

Try using max-width:100% and height: auto in your css. If you want to make your site mobile friendly I would suggest looking into bootstrap framework for more flexibility.

Upvotes: 0

JLF
JLF

Reputation: 2360

You can use a little jQuery to figure out each image's native width, and set perscriptive max-widths for each image afterward:

$('.bodyImg').each(function() {

  // Create new offscreen image to test
  var theImage = new Image();
  theImage.src = $(this).attr("src");

  // Get accurate measurements from that.
  var imageWidth = theImage.width;

  $(this).css({
    "max-width" : imageWidth
  });


}

UPDATE: And if you want each image to have a uniform width, you can store the smallest max width and apply it to all of the images:

var smallMax;
$('.bodyImg').each(function() {

  // Create new offscreen image to test
  var theImage = new Image();
  theImage.src = $(this).attr("src");

  // Get accurate measurements from that.
  var imageWidth = theImage.width;

  // if the variable exists and is bigger than
  // the current width, use the new max width
  if (smallMax !== undefined && smallMax > imageWidth) {
    smallMax = imageWidth;
  }
  // set the variable if it hasn't been set yet
  else if (smallMax == undefined) {
    smallMax = imageWidth;
  }
  // keep the old variable if it is defined and smaller
  else {}


  $(this).css({
    "max-width" : smallMax
  });


}

Upvotes: 1

Related Questions