I have DIV with flexible width set e.g. min-width:800px and max-width:1400px. In this DIV, there are many boxes with fix width 200px and display:inline-block. So depending o
quite old but worth trying since multiple rows and text-align: justify; in the #container creates gaps when last row has less divs. I wanted everything to be floated left. So my idea was to use 2 wrappers.
<div class="wrapper">
<div class="wrapper2">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="clear"></div>
</div>
</div>
as well as overflow: hidden; in css
.wrapper {
width:620px;
border:3px solid red;
margin:0 auto; overflow:hidden;
}
.wrapper2 {
width:630px;
}
div.clear {
clear:both;
}
.box {
width:200px; background:#000; height:100px; margin-bottom:10px; float:left; overflow:hidden; margin-right:10px;
}
drawback: margins are not auto set...
DEMO: http://jsfiddle.net/hexagon13/2avwf/52/
Try this:
div.wrapper {
display: flex;
align-items: stretch;
width: 100%;
height: 100%;
justify-content: space-between;
/* justify-content will give the auto margin you looking for
it will place the auto margin only between each div.box
make sure the div.wrapper has "display: flex;"
*/
}
div.box {
display: inline-flex; /* inline-flex will make the boxes all in the same line */
width: 200px; /* notice you don't need width to be a % for this to work */
height: 100%;
margin: auto; /* gives you the auto margin for the first and last box from the border of your wrapper */
}
Try this jsFiddle: http://jsfiddle.net/MKuxm/
Just make the window larger and smaller to size the div, you'll see that the margin between the red boxes will size accordingly. I am aware that the red boxes are no longer 200px wide, but I'm afraid that isn't possible with pure css because you should not mix percentage widths and fixed pixel width.
HTML
<div>
<span>TEXT</span>
<span>TEXT</span>
<span>TEXT</span>
<span>TEXT</span>
</div>
CSS
div {
width: 95%;
}
span {
float: left;
background: red;
width: 20%;
margin-left: 2.5%;
margin-right: 2.5%;
}
This is as close as IE7-compatible CSS can get: http://jsfiddle.net/thirtydot/79mFr/
If this still isn't right, it's time to look at using JavaScript and hopefully also jQuery. If you define your requirements properly, it should be trivial to get this perfect with JavaScript.
HTML:
<div id="container">
<div></div>
<div></div>
..
<span class="stretch"></span>
</div>
CSS:
#container {
border: 2px dashed #444;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 800px;
max-width: 1400px
}
#container > div {
margin-top: 16px;
border: 1px dashed #f0f;
width: 200px;
height: 200px;
vertical-align: top;
display: inline-block;
*display: inline;
zoom: 1
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0
}
The extra span
(.stretch
) can be replaced with :after
.
This still works in all the same browsers as the above solution. :after
doesn't work in IE6/7, but they're using distribute-all-lines
anyway, so it doesn't matter.
See: http://jsfiddle.net/thirtydot/79mFr/2/
There's a minor downside to :after
: to make the last row work perfectly in Safari, you have to be careful with the whitespace in the HTML.
Specifically, this doesn't work:
<div id="container">
<div></div>
<div></div>
</div>
And this does:
<div id="container">
<div></div>
<div></div></div>
On my project I have faced with the same problem and I came to the next decision - the best way for me is to go with js, in my case you can have xxx count of block inside container, if there is enough space in 1st row the block from 2nd row goes up to the 1st row, and so on. here is an example http://jsfiddle.net/gVAjN/11/
$(function() {
// Call function when DOM is ready
settingsAlignment();
$(window).resize(function() {
// Call function on window resize
settingsAlignment();
})
$('#new_div').click(function() {
box_number = $('.element').size();
box_add = box_number + 1;
$('.container').append($('<div class="element">Box'+ box_add + '</div>'))
settingsAlignment();
})
function settingsAlignment() {
// calculation of ul's padding-left and li's margin-right
var settingsUl = $('.container');
settingsLi = $('.element');
ul_width = settingsUl.outerWidth(true);
item_width = settingsLi.width();
min_gap = 7;
effective_item_width = item_width + min_gap;
items_in_row = Math.floor((ul_width - min_gap) / effective_item_width);
gaps_sum = ul_width - items_in_row * item_width;
new_gaps = gaps_sum / (items_in_row + 1);
item_margin = Math.floor(new_gaps);
row_width = (item_width + item_margin) * items_in_row - item_margin;
console.log(row_width + '= row_width');
console.log(ul_width + '= ul_width');
ul_left_padding = Math.ceil((ul_width - row_width) / 2);
console.log(ul_left_padding + '=ul_left_padding');
settingsUl.css('padding-left', ul_left_padding + 'px');
settingsLi.css('margin-right', item_margin + 'px');
console.log(settingsLi);
}
});
You can float them and just apply a wrapper to the .box
which will allow you to margin:auto;
the .box
relative to the floated wrapper.
CSS:
div.wrapper {
width:100%;
border:3px solid red;
}
div.clear {
clear:both;
}
div.box-wrapper {
float:left;
margin:10px 0;
height:100px;
width:20%;
}
div.box {
border:1px solid black;
width:80px;
height:100px;
margin:auto;
}
HTML:
<div class="wrapper">
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="clear"></div>
</div>
Demo: http://jsfiddle.net/2avwf/
I didn't make them 200px wide for the sake of the fiddle window. Just swap that width:80px
out with the width you desire.
If you want to make this a dynamic solution, in which the number of boxes in a row will vary from user to user based off their screen size, etc., simply make 3 or 4 width-defining box-wrapper classes:
.box-wrapper-25 {
width:25%;
}
.box-wrapper-33 {
width:33%;
}
Then with JQuery you can easily detect the width of .wrapper
and assign an override class to the box wrappers:
$('.box-wrapper').each(function(){
$(this).removeClass().addClass('box-wrapper box-wrapper-25'); // only need 4 per row
});
Something like this: http://jsfiddle.net/RcDky/