CSS Floating Divs at Variable Heights

I have an infinite number of divs with a width of 100px that can fit into the parent width of 250px. Regardless of height, I need divs to display in rows, as shown in the image. I tried to resolve this, but the div height seems to screw it.

enter image description here

I am very grateful for your help. Thank:)

<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 jsfiddle

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

+72
html css css-float
Mar 08 '11 at 15:45
source share
10 answers

As far as I know, there is no way to fix this problem with pure CSS (which works in all common browsers):

  • Floats do not work .
  • display: inline-block does not work .
  • position: relative with position: absolute manual pixel adjustment is required. If you use the server language and work with images (or with a predicted height), you can process the pixel setting "automatically" using the server-side code.

Use jQuery Freemasonry instead.

+63
Mar 08 '11 at 15:53
source share

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

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

if it is 3 lines, then nth-child(3n+1)

+31
Mar 08 2018-11-11T00:
source share

I provide this answer because even when there are good ones that provide a solution ( using Freemasonry ) it is still not crystal clear why this cannot be achieved using floats.

(this is important - # 1 ).

An element with a floating point moves as far left or right as it can in the position in which it was originally

So put it like this:

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 will be lower than others

enter image description here

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

/*the lines are just for illustrate*/

enter image description here

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

Now add another div to 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 it

enter image description here

If we set clear: right to div5 , we force it to take the line below div4

enter image description here

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

Now let’s use as an example the question that brought me here due to duplicating forcing the div stack from left to right

Here is a 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 stored next to div.3 , because in its line (given by the field of the line div.4 ), which is as far as possible, div.1* , div.2* , etc. d. also float to the left of div.5 , but since they do not fit on this line, they go to the line below (defined by the line field of div.5 )

Now notice that when we decrease the height of div.2* to be smaller than div.4* , how can it go to div.5* :

enter image description here

Hope this helps to find out why this cannot be achieved with floats. I am only clarifying the use of float (not inline-block) because of the heading “Floating Divs CSS at variable heights”, and because now the answer is rather long.

+28
Aug 20 '15 at 3:32
source share

As was rightly pointed out, this is not possible with CSS only ... fortunately, now I have found a solution at http://isotope.metafizzy.co/

The problem seems to be completely resolved.

+8
May 4 '11 at 11:28
source share

With a little help from this comment ( CSS Block float left ) I understood the answer.

In each "line" I create, I add a class name of left .
On every other "line" that I create, I add the class name right .

Then I float left and float right for each of these class names!

The only complication is that my content order changes to the “correct” lines, but this can be solved using PHP.

Thanks for the help!

 #holder{ width:200px; border:1px dotted blue; display:inline-block; } .box{ width:100px; height:150px; background-color:#CCC; float:left; text-align:center; font-size:45px; } .one{ background-color:#0F0; height:200px; } .two{ background-color:#0FF; } .three{ background-color:#00F; float:right; } .four{ background-color:#FF0; float:right; } .left{float:left;} .right{float:right;} 
 <div id="holder"> <div class="box one left">1</div> <div class="box two left">2</div> <div class="box four right">4</div> <div class="box three right">3</div> </div> </body> 
+4
Mar 08 '11 at 16:15
source share

Thanks to thirty years of experience, I realized that my previous answer did not help solve the problem. Here is my second attempt, which uses jQuery as a CSS-only solution, seems impossible:

 <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> <script type="text/javascript" language="javascript"> $(document).ready(function() { var numberOfColumns = 3; var numberOfColumnsPlusOne = numberOfColumns+1; var marginBottom = 10; //Top and bottom margins added var kids = $('#holder:first-child').children(); var add; $.each(kids, function(key, value) { add = numberOfColumnsPlusOne+key; if (add <= kids.length){ $('#holder:first-child :nth-child('+(numberOfColumnsPlusOne+key)+')').offset({ top: $('#holder:first-child :nth-child('+(key+1)+')').offset().top+$('#holder:first-child :nth-child('+(key+1)+')').height()+marginBottom }); } }); }); </script> <style> #holder{ width:270px; border:1px dotted blue; display:inline-block; /* Enables the holder to hold floated elements (look at dotted blue line with and without */ } .box{ width:80px; height:150px; background-color:#CCC; margin:5px; text-align:center; font-size:45px; } .one{ height:86px; } .two{ height:130px; } .three{ height:60px; } .four{ clear:both; height:107px; } .five{ height:89px; } .six{ height:89px; } .left{float:left;} .right{float:right;} </style> </head> <body> <div id="holder"> <div class="box one left">1</div> <div class="box two left">2</div> <div class="box three left">3</div> <div class="box four left">4</div> <div class="box five left">5</div> <div class="box six left">6</div> </div> </body> </body> 

The only problem that remains for my solution is what happens when the field has a width of two windows instead of one. I am still working on this solution. I will send a message after completion.

+1
Mar 14 '11 at 11:55
source share

If someone is still looking for alternatives, here is one. Try using the column width property (-moz - / - webkit-). He takes care of changing the height of a variable height. However, the column width adds a new div to the end of the column.

Else, jQuery Masonry works best.

+1
May 08 '14 at 6:34
source share

This may not be the exact solution for everyone, but I believe that (literally) thinking outside the box works in many cases: instead of displaying fields from left to right, in many cases you can fill in the left column first, than go to the middle, fill it out boxes and finally fill the right column with boxes. Then your image will look like this:

filling order :

If you use a scripting language such as php, you can also fill columns from left to right by adding a new field to it and display when all columns are filled. for example (unverified php code):

 $col1 = '<div class="col1"> <div>box1</div>'; $col2 = '<div class="col2"> <div>box2</div>'; $col3 = '<div class="col3"> <div>box3</div>'; $col1 .= '<div>box4</div> </div>'; //last </div> closes the col1 div $col2 .= '<div>box5</div> </div>'; $col3 .= '<div>box6</div> </div>'; echo $col1.$col2.$col3; 

$ col1, $ col2 and $ col3 can have float: left and width: 33%, set the fields inside the div to full width and not float.

Obviously, if you use javascript / jquery to dynamically load mailboxes, you are also better off putting them as described in other answers on this topic.

0
Aug 13 '15 at 14:40
source share

to display, just put this css in your div and then you have the layout you need. No need to connect or JS.

  .Your_Outer { background-color: #FFF; border: 1px solid #aaaaaa; float: none; display:inline-block; vertical-align:top; margin-left: 5px; margin-bottom: 5px; min-width: 152.5px; max-width: 152.5px; } 

You can edit the code according to your requirements :)

0
Aug 28 '15 at 12:44
source share

In modern browsers, you can simply:

 display: inline-block; vertical-align: top; 
-2
Aug 21 2018-12-12T00:
source share



All Articles