admin管理员组

文章数量:1317572

I'm looking for an easy solution to implement the below. Thumbnails will not be cropped but the container they are in will always be the same height/width.

The idea is that images larger than the container would be responsive (ie. scale down), while images that are smaller than the container will be shown "as is."

The problem I'm having is three-fold:

  1. How to handle the responsive element, since we need to account for various aspect ratios (ie. horizontal vs vertical vs square)
  2. How to vertical align when necessary
  3. Images that aren't larger than their container natively shouldn't scale up

Obviously, it would be great if this could be done with CSS only, but I understand javascript might be needed. If that's the case, I'm looking for a lightweight solution since the grid of thumbnails could get quite lengthy.

Any thoughts?

I'm looking for an easy solution to implement the below. Thumbnails will not be cropped but the container they are in will always be the same height/width.

The idea is that images larger than the container would be responsive (ie. scale down), while images that are smaller than the container will be shown "as is."

The problem I'm having is three-fold:

  1. How to handle the responsive element, since we need to account for various aspect ratios (ie. horizontal vs vertical vs square)
  2. How to vertical align when necessary
  3. Images that aren't larger than their container natively shouldn't scale up

Obviously, it would be great if this could be done with CSS only, but I understand javascript might be needed. If that's the case, I'm looking for a lightweight solution since the grid of thumbnails could get quite lengthy.

Any thoughts?

Share Improve this question asked Dec 13, 2013 at 22:28 ndimatteondimatteo 4985 silver badges22 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 6

A pure CSS solution:

demo

.container {
  display: inline-block;
  position: relative;
  width: 8em; height: 10em;
}
.container img {
  position: absolute;
  top: 50%; left: 50%;
  width: auto; height: auto;
  max-width: 100%; max-height: 100%;
  transform: translate(-50%, -50%);
}

The images keep their natural size (width: auto; height: auto;) unless they are bigger than the container (max-width: 100%; max-height: 100%;), in which case they are going to take the size of the container that they exceed and scale the other one accordingly.

Positioning the images in the middle of the container: give them position: absolute and put their top left corner in the middle of the container (top: 50%; left: 50%;). Then translate them left and up by half their puted dimensions, whatever those would be (transform: translate(-50%, -50%);).

This solution works in browsers supporting 2D transforms. Sadly, this excludes IE8 and older and Opera Mini.


A better patibility solution (that I cannot actually test right now in IE8, so I'm just assuming it should work there too) would be:

demo

.container {
  display: inline-block;
  width: 8em; height: 10em;
  text-align: center;
  white-space: nowrap;
}
.container img {
  display: inline-block;
  width: auto; height: auto;
  max-width: 100%; max-height: 100%;
  vertical-align: middle;
}
.container:after {
  display: inline-block;
  height: 100%; width: 0;
  vertical-align: middle;
  content: "";
}

First of all, give images display: inline-block;.

Set text-align: center; on container so that images that are less wide than the container get centred horizontally.

Now to make sure they are in the middle vertically as well. Give them vertical-align: middle;, but that's not enough. inline-block elements are vertically aligned with respect to their inline-block siblings and we have no siblings in this case. So we also need another middle vertically-aligned inline-block element that has the same height as the container. Or a pseudo-element on the container, it's the same thing.

This pseudo-element is going to have height: 100%; so that its vertical middle coincides to that of its parent and width: 0; so that it doesn't affect the horizontal alignment of the image (when the image's natural width < the container's width). It's also going to have display: inline-block; and vertical-align: middle; just like the image.

We also need white-space: nowrap; on the container to prevent the pseudo-element from moving below (and not affect the vertical alignment of the image this way) when the image occupies the entire width of the container.

This is actually the first question I asked on Stackoverflow! Now I know Ana has already e up with a working solution, I thought I'd also post mine that works IE8 onward:

http://jsfiddle/crtpq2jg/

Basic Markup:

<div class='container'>
  <img src='http://www.lorempixel./100/200' />
</div>

CSS:

.container {
  float: left;
  width: 180px;
  height: 210px;
  text-align: center; /* to center align horizontally */
  line-height: 210px; /* Equal to container height */
  font-size: 0; /* This is to eliminate a weird ~2px vertical offset on the images. But you can just specify the font-size for any children elements that may contain text. */
  }
  .container > img {
    width: auto; height: auto;
    max-width: 100%; max-height: 100%;
    vertical-align: middle;
    }

This will work in IE 8 (demo) Html from ana's answer

The trick is to use the after pseudo element to extend the containers line-height to its own height.

This way you can use regular text-align and vertical-align along with max-width and max-height.

.container {
  display: inline-block;
  position: relative;
  border: solid .25em deeppink;
  width: 8em;
  height: 10em;
  text-align: center;
  vertical-align: middle;
  white-space: nowrap;
}
.container img {
  display: inline-block;
  vertical-align: middle;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}

.container:after {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
  width: 0px;
}

Have a look at this jsfiddle: http://jsfiddle/jQN4L/

The max-width and max-height cause the image to scale down if needed, but not scale up. Horizontal centering is done with text-align. Vertical centering is done with line-height and vertical-align, although this method does require that the container has a known height.

HTML:

<div id="d1">
    <img src="http://i.imgur./VAZNIev.jpg" />
</div>
<div id="d2">
    <img src="http://i.imgur./VAZNIev.jpg" />
</div>

CSS:

img {
    max-width: 100%;
    max-height: 100%;
    vertical-align: middle;
}
div {
    text-align: center;
    font-size: 0;
}
#d1 {
    width: 200px;
    height: 100px;
    line-height: 100px;
    background: red;
}
#d2 {
    width: 100px;
    height: 200px;
    line-height: 200px;
    background: green;
}

Changing my answer- should have read the question better!

html:

<div class="img_wrapper">
  <img class ='full_width' src="1.png" />
  <img class ='full_width' src="2.png" />
  <img class ='full_width' src="3.png" />
</div>

css:

.img_wrapper {
 width: 860px;
 margin: 30px;
 }
.full_width {
 width: 200px;
 height: 200px;
 float: left;
 margin: 10px;
 vertical-align: middle;
}
.full_width img {
 max-width: 100%;
 max-height: 100%;

}

本文标签: