1

I have a div-container, which has one main image and optional multiple smaller images: http://jsfiddle.net/h5kc8ybm/

The multiple smaller images are generated dynamically, so there can be just 1 or 10 of them. On my JFiddle you can see, that the images are just displayed in one single row.

What I want to achieve is, that there are filled up 'by colomns':

  1. First image on top next to the main image (like shown in this example)
  2. Second image below that (not right of it, like in the example)
  3. Third image right of first image (top)
  4. Fourth image below third image

...and so on.

Is it possible to do that just with CSS?

Update

To avoid misunderstanding: All smaller images should be positioned right of the main image. But these small images should be displayed in two rows, filled up from first row to second row.

The main div-element will never change its height, but only its width.

Example

enter image description here

HTML

<div class="tnwrapper">
    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail">
    </div>

    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>

    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>  
</div>

LESS

.tnwrapper {
    background-color: #f5f5f5;
    padding: 5px 5px 5px 9px;
    border-radius: 4px;
    display: inline-block;
    .tn {
        display: inline-block;
        vertical-align:top;
        position: relative;
        margin-right: 5px;
        .thumbnail {
            display: block;
            padding: 4px;
            margin-bottom: 20px;
            line-height: 1.42857143;
            background-color: #fff;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        .thumbnail.child {
            width: 40px;
        }
    }
}
Community
  • 1
  • 1
user3142695
  • 15,844
  • 47
  • 176
  • 332
  • have a look at the css `columns` property, or perhaps `display:flex` – Pete Dec 02 '15 at 09:44
  • This would certainly require a change in the HTML structure from what I can see. – Paulie_D Dec 02 '15 at 09:51
  • [columns example](http://jsfiddle.net/h5kc8ybm/4/) – Pete Dec 02 '15 at 09:52
  • @Paulie_D What would you suggest? – user3142695 Dec 02 '15 at 09:52
  • @Pete: If the part with the small images would be rotated 90°, it would be exactly what I need: If there are 10 small images, they should be displayed by two lines (each five images) right to the main image. – user3142695 Dec 02 '15 at 09:53
  • 1
    Maybe you can achieve what you want by using `:nth-child(even)` and set the even images at the bottom – Simon M. Dec 02 '15 at 09:56
  • 1
    @user3142695 See this [example](http://jsfiddle.net/h5kc8ybm/5/), this is not what you want but you can play with `:nth-child(even)` and set the even images at the top – Simon M. Dec 02 '15 at 10:09
  • @SimonM. As you said, it isn't working like it is needed. But it is a good idea. I will have a look at it, maybe I can modify it... – user3142695 Dec 02 '15 at 10:11

5 Answers5

4

I was able to do this with the following steps:

  • wrap the smaller children in a div and make it position:relative
  • apply position:absolute on even items and reposition them
  • float them left

http://jsfiddle.net/0neukb08/

The downside of this approach is that it hardcodes the image's size in the "reposition" step

Additionally, the reason I chose not to use flex-box here was this issue with growing its width (I also didn't like the highest voted answer), but flexbox is a good option if you know the container's width in advance.

Community
  • 1
  • 1
Eduardo Wada
  • 2,606
  • 19
  • 31
  • Turns out the absolute positioned elements where being assigned a margin, even though they are not considered in the document's flow when position is absolute, their margins are. just add `.children .tn:nth-child(even){ margin-right: 0px; }` and it will reset their margins – Eduardo Wada Dec 02 '15 at 12:46
0

You probably can do this by

Rotate the container -90deg and reflect it:

.tnwrapper {
  ...
  transform: rotate(-90deg) scaleX(-1);
}

then apply the reverse transformation for the thumbnails:

.tnwrapper .tn {
  ...
  transform: rotate(90deg) scaleX(-1);
}

JSFiddle: http://jsfiddle.net/h5kc8ybm/1/

Note though that the height limit of the container is now width, not height (because it was rotated -90deg.

AVAVT
  • 7,058
  • 2
  • 21
  • 44
  • I think you misunderstood me. All smaller images should be positioned right of the main image. But these small images should be displayed in two rows, filled up from first row to second row – user3142695 Dec 02 '15 at 09:49
  • Oh I see. Would have to think of another solution then ^^' – AVAVT Dec 02 '15 at 09:59
0

CSS flexbox styling should do the trick:

.tnwrapper {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 200px;
}

.tn:first-child {
  height: 192px;
  width: 192px;
}
<div class="tnwrapper">
    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail">
    </div>

    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>

    <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>  
  
      <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>  
  
      <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>  
  
      <div class="tn">
            <img src="http://placehold.it/96x96" alt="" class="thumbnail child">
    </div>  
</div>

EDIT: Sorry, the above snippet doesn't quite answer the question after all. This snippet places each subsequent image in left-to-right then top-to-bottom order, rather than top-to-bottom then left-to-right order as the question asked. I think adding a div around the first image would be the cleanest way to accomplish what you want.

dwhieb
  • 1,706
  • 19
  • 29
0

This is solution with flexbox and since you said that height of main-div wont change this should work http://jsfiddle.net/h5kc8ybm/13/

CSS

.tnwrapper {
  background-color: #000;
  padding: 5px 5px 5px 9px;
  border-radius: 4px;
  display: -webkit-flex;
  display: flex;
}

.child-images {
   display: -webkit-flex;
   display: flex;
   -webkit-flex-direction: column;
   flex-direction: column;
   -webkit-flex-wrap: wrap;
   flex-wrap: wrap;
   margin: 0 10px;  
   height: 170px;
}

.tnwrapper .tn .thumbnail {
  padding: 4px;
  margin: 10px;
  line-height: 1.42857143;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.child-images .tn img {
  width: 40px;
}
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

I'm not quite clear on the order of the thumbnails but I think you wanta column format for those.

I that case wrap the main image and the thumbnails in separate divs and then flexbox can do the rest.

.wrap {
  display: flex;
  margin: 1em auto;
  height: 280px;
}
.hero {
  padding: 10px;
}
.sidekicks {
  flex: 1;
  padding: 10px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: flex-start;
}
.sidekicks .item {
  width: 96px;
  height: 96px;
  margin: 10px;
  background: lightblue;
  line-height: 96px;
  text-align: center;
}
<div class="wrap">
  <div class="hero">
    <img src="http://lorempixel.com/image_output/city-h-c-240-250-5.jpg" alt="" />
  </div>
  <div class="sidekicks">
    <div class="item">Item1</div>
    <div class="item">Item2</div>
    <div class="item">Item3</div>
    <div class="item">Item4</div>
    <div class="item">Item5</div>
    <div class="item">Item6</div>
    <div class="item">Item7</div>
    <div class="item">Item8</div>
  </div>

</div>

Codepen Demo

Paulie_D
  • 107,962
  • 13
  • 142
  • 161