Categories
css css-float html

CSS Floating Divs At Variable Heights [duplicate]

87

I have infinite number of divs of a 100px width, which can fit into a 250px width parent. Regardless of height, I need the divs to be displayed in rows, as shown in the image. I’ve tried resolving this, but the div height seems to be screwing it up.

enter image description here

I’d really appreciate your help. Thanks 🙂

        <style>
            #holder{
            width:250px;
            border:1px dotted blue;
            display:inline-block;
        }
        .box{
            width:100px;
            height:150px;
            background-color:#CCC;
            float:left;
            text-align:center;
            font-size:45px;
            display:inline-block;
        }
        .one{
            background-color:#0F0;
            height:200px;
        }

        .two{
            background-color:#0FF;
        }

        .three{
            background-color:#00F;
        }

        .four{
            background-color:#FF0;
        }
    </style>

    <div id="holder">
        <div class="box one">1</div>
        <div class="box two">2</div>
        <div class="box three">3</div>
        <div class="box four">4</div>
    </div>

Here is the jsfiddle

Here is what I did and achieved using javascript
https://jsfiddle.net/8o0nwft9/

1

70

To my knowledge, there’s no way to fix this problem with pure CSS (that works in all common browsers):

  • Floats don’t work.
  • display: inline-block doesn’t work.
  • position: relative with position: absolute requires manual pixel tuning. If you’re using a server-side language, and you’re working with images (or something with predictable height), you can handle the pixel tuning “automatically” with server-side code.

Instead, use jQuery Masonry.

5

  • 3

    @stevenmc: No problem, but you certainly have not found a solution to the question you asked: "I have infinite number of divs of a 100px width, which can fit into a 250px width parent. Regardless of height, I need the divs to be displayed in rows, as shown in the image.".

    – thirtydot

    Mar 8, 2011 at 19:23

  • 1

    Nowadays you can do it quite reasonably with CSS columns, for example: w3bits.com/css-masonry

    – thirtydot

    Aug 7, 2017 at 3:15

  • 2

    CSS columns won’t solve the issue completely, if the alignment should happen like numbered above. CSS columns will lead to a layout where column 1 will contain items 1,2,3 and column 2 contain items 4,5,6.

    Oct 6, 2017 at 7:39

  • Can the same be accomplished with flexbox?

    – iChido

    Oct 24, 2018 at 19:36

  • 1

    @iChido: I don’t think flexbox helps particularly with this problem, but I’m not certain. I haven’t tried to do this with only CSS in a long time, I always end up using JavaScript because it just works. The Masonry library in my answer doesn’t even rely on jQuery any more. Whether or not CSS alone can do it depends on your precise requirements.

    – thirtydot

    Oct 24, 2018 at 19:54


40

on the assumption that your needs are more like your colored example code then:

.box:nth-child(odd){
    clear:both;
}

if it’s going to be 3 rows then nth-child(3n+1)

5

  • I don’t want to “clear” on any.

    – stevenmc

    Mar 8, 2011 at 16:12

  • 3

    This is the best working css only solution.

    Nov 30, 2012 at 17:17

  • This solved my issue since I actually wanted a different layout, but it’s not really an answer to this SO question. Edit: PS: No ie8 support for nth-child.

    – Eirik H

    Dec 16, 2013 at 9:18


  • I had 2 columns, for me, this was the best solution 🙂

    – Ruub

    Jan 19, 2015 at 9:29

  • An example of this can be found here ( for 3 columns ) codepen.io/anon/pen/dPZvbb

    – veganista

    Feb 6, 2015 at 12:18


39

I’m providing this answer because even when there are good ones which do provide a solution(using Masonry) still isn’t crystal clear why it isn’t possible to achieve this by using floats.

(this is important – #1).

A floated element will move as far to the left or right as it can in
the position where it was originally

So put it in this way:

We have 2 div

<div class="div5">div5</div>
<div class="div6">div6</div>

.div-blue{
    width:100px;
    height:100px;
    background: blue;
}

.div-red{
    width:50px;
    height:50px;
    background: red;
}

without float they’ll be one below the other

enter image description here

If we float: right the div5, the div6 is positioned on the line where the div5 was ,

/*the lines are just for illustrate*/

enter image description here

So if now we float: left the div6 it will move as far to the left as it can, “in this line” (see #1 above), so if div5 changes its line, div6 will follow it.

Now let’s add other div into the equation

<div class="div4">div4</div>
<div class="div5">div5</div>
<div class="div6">div6</div>

.div-gree{
    width:150px;
    height:150px;
    background: green;

    float:right;
}

We have this

enter image description here

If we set clear: right to the div5, we are forcing it to take the line bellow div4

enter image description here

and div6 will float in this new line wether to the right or to the left.

Now lets use as example the question that brought me here due to a duplicate Forcing div stack from left to right

Here the snippet to test it:

div{
    width:24%;
    margin-right: 1%;
    float: left;
    margin-top:5px;
    color: #fff;
    font-size: 24px;
    text-align: center;
}

.one{
    background-color:red;
    height: 50px;
}

.two{
    background-color:green;
    height:40px;
}

.three{
    background-color:orange;
    height:55px;
}

.four{
    background-color:magenta;
    height:25px;
}

.five{
    background-color:black;
    height:55px;
}
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
<div class="five">5</div>

<div class="one">1*</div>
<div class="three">2*</div>
<div class="four">3*</div>
<div class="two">4*</div>
<div class="five">5*</div>

enter image description here

In the above image you can see how div.5 is stocked just next to div.3 that is because in its line (defined by the line box of div.4) that is as far it can go, div.1*, div.2*, etc, also float left of div.5 but as they don’t fit in that line they go to the line bellow (defined by the line box of div.5)

Now notice that when we reduce the height of div.2* enough to be less than div.4* how it let pass to div.5*:

enter image description here

I hope this helps to clarify why this can not be achieved using floats. I only clarify using floats (not inline-block) because of the title “CSS Floating Divs At Variable Heights” and because right now the answer is quite long.

0