how to give image a dynamic width and height when using bootstrap responsive grid system

Problem

I am using bootstrap's grid system and here's my website. The issue is that on initial load the item card looks pretty crappy like this:

enter image description here

and here's what it looks like after it loads:

enter image description here

As you can see the issue is because I am not supplying the image's width and height and hence before it load I am seeing this weird layout which is not good. The issue why I am not supplying a width and height is because this is responsive, such that when I resize the width of the browser then the width of the card also changes, and hence supplying a constant width and height doesn't work. What's the best solution out of this?

Problem courtesy of: adit

Solution

You can calculate your image ratio if it's known then set its padding to the ratio

Check out the js fiddle:

http://jsfiddle.net/J8AYY/7/

<div class="img-container">
    <img src="">
</div>

.img-container {
    position:relative;
    padding-top:66.59%;
}

img {
    position: absolute;
    top: 0;
    left: 0;
    width:100%;
}

So if your image has width 2197 pixels and height 1463 pixels

then set the container that contain the image to have padding-top 1463/2197*100% then set your image to position absolute now your image can be responsive and worry free of collapsing container

Solution courtesy of: Chihung Yu

Discussion

You need to put your thumbnails in a dynamically sized container, whose height is proportional to it's width. You can do this by matching width and padding-bottom on the container, as well as a few other specifics as in the Bootply and example below:

Bootply

Example:

CSS:

.thumbnail_container {
     position: relative;
     width: 100%;
     padding-bottom: 100%; <!-- matching this to above makes it square -->
     float:left;
}

.thumbnail {
    position:absolute;
    width:100%;
    height:100%;
}
.thumbnail img {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

img{
    max-height:100%;
    max-width:100%;
}

HTML:

<div class="container-fluid"> <!-- this makes your images scale constantly, between breakpoints as welll. removing -fluid makes then jump in size at breakpoints -->
  <div class="row">

  <div class="col-md-3 col-sm-4 col-xs-6">
    <div class="thumbnail_container">
      <div class="thumbnail">
          <img src="http://placehold.it/400x600">
      </div>
    </div>
</div>
<div class="col-md-3 col-sm-4 col-xs-6">
    <div class="thumbnail_container">
      <div class="thumbnail">
        <img src="http://placehold.it/600x600">
      </div>
    </div>  
</div>
<div class="col-md-3 col-sm-4 col-xs-6">
    <div class="thumbnail_container">
      <div class="thumbnail">
          <img src="http://placehold.it/600x400">
      </div>
    </div>
</div>
<div class="col-md-3 col-sm-4 col-xs-6">
    <div class="thumbnail_container">
      <div class="thumbnail">
        <img src="no-photo" /> <!-- No Photo, but it still scales -->
      </div>
    </div>  
</div>

You'll notice that in the last thumbnail, even though there is no file loaded, the container is square. This is the key that will fix your specific issue.

Note: matching padding-bottom to width will give you a square thumbnail container, but you can make it any proportion you want, by adjusting the padding-bottom %.

Note2: because you haven't shared your code, you'll probably have to do a bunch of class renaming and testing to get this to work. I had to guess at your setup based on what I saw on your site. Hope it helps!

Discussion courtesy of: Shawn Taylor

If you're working with images that are all the same size, you can set a min-height on the image element for each step of the responsive page. You would have to find out how tall the images are at each step of the responsive page design, but it could look something like this:

.item-card img {
  min-height: 100px;
}

// Small screen
@media (min-width: 768px) {
  .item-card img {
    min-height: 150px;
  }
}

// Medium screen
@media (min-width: 992px) {
  .item-card img {
    min-height: 200px;
  }
}

// Large screen
@media (min-width: 1200px) {
  .item-card img {
    min-height: 250px;
  }
}
Discussion courtesy of: theJoeBiz

As far as I understand your question you want the image to auto adjust when the browser is resized. We can achieve this using the css below.

.image-box img {
    width: 100%; 
}

If we only specify the width of the image the height will be auto calculated. It will maintain the aspect ratio for the image. Width 100% will exactly fit the container of the image. This code may not work for background image.

Discussion courtesy of: kundan Karn

Your problem is that at load time, the img has a height=0 and width=100%. So, you have an empty image when the page loads.

You can consider using an Image Preloader:

If you want all the images to have the same height, then use the Fake Crop jQuery plugin. Actually, it doesn't crop the image file, but the image gets a "cropped" effect using CSS Positioning properties.

Also, you can assign a min-height to the container:

 .product-view .img-responsive {min-height:352px; background:#fff;}

You can also look into Lazy Loading:

Discussion courtesy of: Wissam El-Kik
   use bootstrap or @media queries

  /* Small devices (tablets, 768px and up) */
  @media (min-width: @screen-sm-min) { ... }

 /* Medium devices (desktops, 992px and up) */
  @media (min-width: @screen-md-min) { ... }

   /* Large devices (large desktops, 1200px and up) */
    @media (min-width: @screen-lg-min) { ... }

      We occasionally expand on these media queries to include a max-width to limit CSS to a narrower set of devices.

    @media (max-width: @screen-xs-max) { ... }
    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { ... }
    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { ... }
    @media (min-width: @screen-lg-min) { ... }

     http://getbootstrap.com/css/#grid 
Discussion courtesy of: Kisspa

This recipe can be found in it's original form on Stack Over Flow.