Using flexbox:
HTML:
<div class = "container">
<div class = "box a">1</div>
<div class = "box b">2</div>
<div class = "box c">3</div>
<div class = "box a">4</div>
<div class = "box b">5</div>
<div class = "box c">6</div>
<div class = "box a">7</div>
<div class = "box b">8</div>
<div class = "box c">9</div>
</div>
CSS:
.container {
display: flex;
align-content: flex-start;
flex-wrap: wrap;
width:80%;
background-color: #ccc;
margin: 0 auto;
}
.box {
min-width:100px;
max-width:150px;
min-height:30px;
flex-grow: 1;
}
.a { background-color: #fcc }
.b { background-color: #cfc }
.c { background-color: #ccf }
The size of the boxes can be changed using min-width
and max-width
. Only in extreme cases would the right margin appear, but this @media would solve (to eliminate max-width
of very narrow screens).
Demo: link
Using JavaScript:
This solution has been simplified to a fixed-width DIV in the boxes, but with some adjustments (and a bit of math: P) it can be adapted to flexible width:
We add a% reference external%, and div
to not allow floats to escape from span
:
HTML:
<div id="reference">
<div id="container">
<div class="box a">1</div>
<div class="box b">2</div>
<div class="box c">3</div>
<div class="box a">4</div>
<div class="box b">5</div>
<div class="box c">6</div>
<div class="box a">7</div>
<div class="box b">8</div>
<div class="box c">9</div>
<span class="clr"></span>
</div>
</div>
CSS:
#reference, #container, .box {
padding: 0;
margin: 0;
}
#reference {
position:relative;
background-color: #ffc;
}
#container {
position: relative;
background-color: #ccc;
}
.box {
float: left;
width:100px;
min-height:30px;
}
.clr {
display:block;
clear:both;
}
.a { background-color: #fcc }
.b { background-color: #cfc }
.c { background-color: #ccf }
So far, there's a traditional layout, with a margin left over from the right side. You lose some of the aesthetic you want if for some reason the person is browsing with JS disabled, but usability remains.
In order to give the final finish, centering container
, we solve with a small JS function, which should be called in container
, onload
(or after any layout changes made with JS or some framework ):
JS:
window.onresize = function() {
b2AdjustPadding();
}
function b2AdjustPadding() {
var boxSize = 100; // Ponha o mesmo width que estiver no CSS
var reference = document.getElementById('reference');
var remaining = reference.offsetWidth % boxSize;
var padLeft = Math.round( remaining / 2 );
var padRight = remaining - padLeft;
reference.style.paddingLeft = padLeft+"px";
reference.style.paddingRight= padRight+"px";
}
What we did here was basically this: By changing the width of the page, we calculated how much margin left over, using the module ( onresize
). Then we split this in the middle, rounding up, to add a left padding in our %
element. What remains, we put in the right padding, not to be left margin of any side.
Note that the margins are calculated separately, so that rounding problems do not leave a pixel left on the right side, which would happen in certain widths.
Remember to put the same width in the CSS and the reference
variable. If you prefer, you can get the size dynamically, but I find it somewhat exaggerated (unless you go to lib for this).
Demo: link