Layout theory for a thumbnail gallery [closed]

痞子三分冷 提交于 2019-11-28 08:50:26

Have a look at

var fixedwidth = 50 + 1, //the +1 is for 1px horizontal margin
    gallery = $('#gallery'), // cache a reference to our container
    imagelist = gallery.children(); // cache a reference to our image list


function layoutImages(){
    var columncount = parseInt(gallery.width()/fixedwidth,10),  // find how many columns fit in container
        columns = [];

    for (var i =0;i<columncount;i++){ // initialize columns (0 height for each)
        columns.push(0);
    }

    imagelist.each(function(i,image){
         var min = Math.min.apply(null, columns), // find height of shortest column
             index = columns.indexOf(min), // find column number with the min height
             x = index*fixedwidth; // calculate horizontal position of current image based on column it belongs

        columns[index] += image.height +1; //calculate new height of column (+1 for 1px vertical margin)
        $(image).css({left:x, top:min}).delay(i*200).animate({opacity:1},100); // assign new position to image and show it
    });
}

$(window).resize(layoutImages).trigger('resize');

Demo at http://jsfiddle.net/gaby/DL8Vr/6/


Assumptions

  • 50 pixels fixed width for each image (parameterized by the fixedwidth variable)
  • all images are in a common container (with id gallery in this case)

The demo has some CSS animations, and also repositions the images when the window is resized..

Demo html

<div id="gallery">
    <img src="http://dummyimage.com/50x42/7c6c4c/000000.gif&amp;text=img0">
    <img src="http://dummyimage.com/50x89/2c6c2c/000000.gif&amp;text=img1">
    ....
    <img src="http://dummyimage.com/50x62/2c5c6c/000000.gif&amp;text=img29">
    <img src="http://dummyimage.com/50x58/2c3c9c/000000.gif&amp;text=img30">
</div>

Demo css

#gallery{
    position:relative;
    width:100%;
}
#gallery img{
    position:absolute;
    -ms-transition:all 1s;
    -o-transition:all 1s;
    -webkit-transition:all 1s;
    -moz-transition:all 1s;
    transition:all 1s;
    opacity:0;
}

The technique works exactly as you described:

fill the first (from the left or right, doesn't matter) shortest column

The part about finding the first shortest is necessary as a tie-breaker in case there are several columns of the same length and all of them are the shortest.

The part about filling in the shortest first is obvious: doing it otherwise would cause blank white space to randomly accumulate.

To understand why the columns are necessary you have to first understand how the <img> tag works in HTML:

The <img> tag

From the earliest days, HTML was supposed to be a way to format text. So when images was introduced it was designed to be placed inline with the text without any fancy layout (css later allows you to do fancy layout). The height of an image always occupies a line of text. So for example this:

<pre>
  text text text
  text <img> text
  text text text
</pre>

ends up looking like this:

text text text
     .------.
     | img  |
     |      |
text '______' text
text text text

Notice that the height of the second line is automatically increased to fit the image.

Image gallery layout problems and solutions

So, a series of image tags with different heights like this:

<pre>
    <img> <img> <img>
    <img> <img> <img>
    <img> <img> <img>
</pre>

may end up looking like this:

 ______
|      |           ______
|      |  ______  |      |
|      | |      | |      |
'______' '______' '______'
          ______
 ______  |      |  ______
|      | |      | |      |
|      | |      | |      |
'______' '______' '______'
                   ______
 ______           |      |
|      |  ______  |      |
|      | |      | |      |
'______' '______' '______'

..with ugly gaps of blank space.

One solution to this is to use CSS floats. But experienced developers would recognize me typing the words "float" and "css" together and recall nightmares of trying to get multiple floats to play nice with each other.

Another solution (which I often use) is to fix the height of the images instead of the width and let the images flow normally. This often leads to layouts that looks something like this:

 _______   _______   ______
|       | |       | |      |
|       | |       | |      |
'_______' '_______' '______'
 ______   ____   ________
|      | |    | |        |
|      | |    | |        |
'______' '____' '________'
 _____   ______   ___________
|     | |      | |           |
|     | |      | |           |
'_____' '______' '___________'

Which is a lot better since it gets rid of a lot of the blank gaps. But the problem with this is the uneven right edge of the gallery which some people don't like.

The column solution

Which leads us to the solution you've come accross. Use HTML elements like <div>s or <table>s to group the images into columns and place the images into the columns using the above stated algorithm. You'll still end up with an uneven edge but at least it's at the bottom of the gallery which is preferable to some people.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!