Search code examples
csstwitter-bootstrapgalleryresponsive-design

How can I create a good-looking responsive image gallery WITHOUT perfectly sized images?


I'm using Wordpress and user-uploaded images. I'm trying to build a responsive image gallery using Bootstrap but I'm running into some trouble with it:

Picture.png http://img339.imageshack.us/img339/6838/picturehq.png Also find it on jsfiddle, (make sure to set the output window big enough that they switch to multi-columns)

Some of the real-world challenges and some of my constraints:

  • The images aren't all going to be the same size
  • The images shouldn't have to all be the same size
  • The gallery needs to be responsive (images can shrink/grow, can change from 2,3,4 columns etc)
  • The captions may be any length, and should be auto-truncated / hidden / etc.
  • I want the images to have the proper aspect ratios, e.g. no width:100%; height:100%
  • The captions should somehow line up

What I've Tried

One of the tricky ways that I used to create image galleries before responsive design was to have Wordpress create two images sizes, one with a max-width and one with a max-height, both with a soft-crop, of the size I wanted the gallery thumbnails to be. When generating the gallery I would check to see which didn't overflow the bounds and then use that image for the thumbnail. The other way is to just use an image that is close to the size I want, and then set the image as a background-url for the containing element with position set to center/center. This works great for fixed-width designs, but it doesn't work well for responsive! :)

Plus, as far as I know with responsive design / css there is no way to set the scale of a background image. It also seems more semantically accurate to code up images using, well, an <img> tag instead of a <div> with a background-image set via CSS.

Without responsive design you might also have a fixed column count, so you can do a clear:left on every nth image to keep the weird wrap from happening. But with responsive design the column count may change from 2,3,4 etc.

Also, without responsive design you could use Javascript to loop through the images / thumbnail containers and standardize their heights. Doing this on a responsive design is not impossible, but you have to wait for the page to load completely as the heights are set as percentages to start with and may not be accurate until all the resources are loaded. Then you have to worry about what happens on a window resize or orientation change. This seems like a hack and not the right way to do it.

I also tried setting the min-height areas for the .thumbnail element and setting the <a> containing the image to display:block and setting that to have a min-height as well. Results are better, but still not great:

3 column: Picture.png http://img818.imageshack.us/img818/9472/picturemk.png

4 column:

Picture 1.png http://img525.imageshack.us/img525/706/picture1uh.png

So, how can I create a good-looking responsive image gallery WITHOUT perfectly sized images?


Solution

  • Though this doesn't require 'perfectly-sized images', it does, for a CSS-only solution, require specifically-sized li elements, with their overflow to hidden (so that the image doesn't have its ratio skewed, though it may be cropped by the parent li container).

    Setting the li elements to float: left; in conjunction with the defined width and height allows for a uniform presentation/distribution, with the gallery able to self-adapt and reflow according to the width of the window/parent-ul:

    li {
        width: 160px;
        height: 160px;
        padding: 4px;
        float: left;
        position: relative;
        overflow: hidden;
    }
    
    li p {
        position: absolute;
        color: #fff;
        opacity: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: 0 0 -1px 0;
    }
    
    li:hover p {
        opacity: 1;
        background-color: #000;
        background-color: rgba(0,0,0,0.5);
        -webkit-transition: all 1s linear;
    }
    

    JS Fiddle demo (with float: left;).

    (Removed the display: inline-block solution, since it doesn't appear to allow descendant elements to be absolutely-positioned with regard to the li with that display property.)

    If JavaScript solutions are possible, there's also jQuery-required Masonry (and non-jQuery Masonry) and Isotope (requires jQuery), among others.

    Although, if you're able to live with the restricted-width of the lis, and somewhat limited cross-browser support compatibility, you could use CSS columns:

    ul {
        -moz-column-width: 160px;
        -moz-column-gap: 0;
        -ms-column-width: 160px;
        -ms-column-gap: 0;
        -o-column-width: 160px;
        -o-column-gap: 0;
        -webkit-column-width: 160px;
        -webkit-column-gap: 0;
        column-width: 160px;
        column-gap: 0;
    }
    

    JS Fiddle demo.