I have a bunch of same-size blocks set to display:inline-block
inside a div that has text-align:center
set to align the blocks.
| _____ _____ _____ _____ |
| | | | | | | | | |
| | 1 | | 2 | | 3 | | 4 | |
| |_____| |_____| |_____| |_____| |
| _____ _____ _____ _____ |
| | | | | | | | | |
| | 5 | | 6 | | 7 | | 8 | |
| |_____| |_____| |_____| |_____| |
| |
The blocks fill the div horizontally, and as the browser window shrinks, some blocks break to new lines, creating more rows and less columns. I want everything to still remain centered, with the last row aligned flush to the left, like this :
| _____ _____ _____ |
| | | | | | | |
| | 1 | | 2 | | 3 | |
| |_____| |_____| |_____| |
| _____ _____ _____ |
| | | | | | | |
| | 4 | | 5 | | 6 | |
| |_____| |_____| |_____| |
| _____ _____ |
| | | | | |
| | 7 | | 8 | |
| |_____| |_____| |
| |
What currently happens is this:
| _____ _____ _____ |
| | | | | | | |
| | 1 | | 2 | | 3 | |
| |_____| |_____| |_____| |
| _____ _____ _____ |
| | | | | | | |
| | 4 | | 5 | | 6 | |
| |_____| |_____| |_____| |
| _____ _____ |
| | | | | |
| | 7 | | 8 | |
| |_____| |_____| |
| |
I cannot add extra filler divs like one suggestion, because there could be any number of blocks, and the amount of rows and columns will vary depending on browser width. I also cannot style block #7 directly, for the same reason. The blocks must always remain centered no matter how many columns.
Here is a pen to better demonstrate:
http://codepen.io/anon/pen/IDsxn
Is this possible? I feel like it sure should be. I would prefer not to use flexbox as it is only ie10+, and I'd like ie9+. I would really like a pure CSS solution, but if you tell me JS is the only way, I'd love to see that in action.
For reference - similar questions, though none were thoroughly explained:
How to align left last row/line in multiple line flexbox
CSS - Left align the last row of images in a centered div
Center multiple inline blocks with CSS and align the last row to the left
This adaptive grid is much simpler : less markup and less CSS so it will be easier to implement in a production site and adapt to your exact needs.
=>> DEMO <<= (resize the result window to see the effect)
html, body {
margin:0;
padding:0;
}
#container{
font-size:0;
margin:0 auto;
width:1000px;
}
.block {
font-size:20px;
width: 150px;
height: 150px;
margin:25px;
background: gold;
display:inline-block;
}
@media screen and (max-width: 430px) {
#container{
width:200px;
}
}
@media screen and (min-width: 431px) and (max-width: 630px) {
#container{
width:400px;
}
}
@media screen and (min-width: 631px) and (max-width: 830px) {
#container{
width:600px;
}
}
@media screen and (min-width: 831px) and (max-width: 1030px) {
#container{
width:800px;
}
}
<div id="container">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
<div class="block">9</div>
<div class="block">10</div>
<div class="block">11</div>
<div class="block">12</div>
<div class="block">13</div>
</div>
It involves :
4 media queries for 200px wide blocks and a container expandable to 1000px. Depending on the width of your grid elements and the total width of your container you may have to make less or more
removing white-spaces between inline-block elements (in the following demo I used the font-size technique but you can use other ones (see How to remove the space between inline-block elements? for other techniques)
fixed margins between blocks
The number of blocks in one line adapts to the size of the container. The text-align
property stay to default value left
so the last items are aligned to the left.
=>> DEMO <<= (you need to resize the result window under 750px to see it in action)
html, body {
margin:0;
padding:0;
min-width:150px;
}
.wrap {
float:left;
position:relative;
}
.foto {
width: 150px;
height: 150px;
background: gold;
position:absolute;
}
#warning{display:none;}
@media screen and (min-width: 631px) {
.wrap {
width:20%;
padding-bottom:25%;
}
.wrap:nth-child(4n+2), .wrap:nth-child(4n+3){
}
.wrap .foto {
top:-75px;
margin-top:100%;
right:-30px;
}
.wrap:nth-child(4n+2){
margin:0 5% 0 7.5%;
}
.wrap:nth-child(4n+3){
margin-right:7.5%;
}
.wrap:nth-child(4n+2) .foto{
left:50%;
margin-left:-75px;
}
.wrap:nth-child(4n+3) .foto{
right:50%;
margin-right:-75px;
}
.wrap:nth-child(4n) .foto{
left:-30px;
}
#container{
margin-top:-45px;
}
}
@media screen and (min-width: 481px) and (max-width: 631px) {
.wrap {
width:25%;
padding-bottom:33.3%;
}
.wrap:nth-child(3n+2){
margin:0 12.5%;
}
.wrap .foto {
top:-75px;
margin-top:100%;
right:-37px;
}
.wrap:nth-child(3n+2) .foto{
left:50%;
margin-left:-75px;
}
.wrap:nth-child(3n) .foto{
left:-37px;
}
#container{
margin-top:-37px;
}
}
@media screen and (min-width: 331px) and (max-width: 480px) {
.wrap {
width:33.3%;
padding-bottom:50%;
clear:left;
}
.wrap:nth-child(even) {
float:right;
clear:right;
}
.wrap .foto {
top:-75px;
margin-top:100%;
right:-50px;
}
.wrap:nth-child(even) .foto {
left:-50px;
}
.wrap:nth-child(4n+3) .foto, .wrap:nth-child(4n+4) .foto {
bottom:-75px;
margin-bottom:100%;
}
#container{
margin-top:-25px;
}
}
@media screen and (max-width: 330px) {
.wrap {
width:50%;
padding-bottom:100%;
clear:left;
}
.wrap:nth-child(odd) .foto {
right:-75px;
bottom:0;
bottom:-75px;
margin-bottom:100%;
}
.wrap:nth-child(even) .foto {
top:0px;
right:-75px;
top:-75px;
margin-top:100%;
}
}
@media screen and (min-width: 751px) {
#warning{
color:#fff;
display:block;
position:fixed;
width:100%;
height:50%;
top:25%;
left:0;
background:#000;
text-align:center;
font-size:30px;
}
<div id="container">
<div class="wrap"><div class="foto">1</div></div>
<div class="wrap"><div class="foto">2</div></div>
<div class="wrap"><div class="foto">3</div></div>
<div class="wrap"><div class="foto">4</div></div>
<div class="wrap"><div class="foto">5</div></div>
<div class="wrap"><div class="foto">6</div></div>
<div class="wrap"><div class="foto">7</div></div>
<div class="wrap"><div class="foto">8</div></div>
<div class="wrap"><div class="foto">9</div></div>
<div class="wrap"><div class="foto">10</div></div>
<div class="wrap"><div class="foto">11</div></div>
<div class="wrap"><div class="foto">12</div></div>
<div class="wrap"><div class="foto">13</div></div>
<div class="wrap"><div class="foto">14</div></div>
<div class="wrap"><div class="foto">15</div></div>
</div>
<!-- FOLLOWING JUST FOR THE DEMO -->
<div id="warning">I haven't written the code for windows bigger than 751px.<br/>
You must resize this window under 751px.</div>
This technique involves :
position:absolute;
:nt-child()
css selectorIt centers the blocks in their container and gives the same margin on the top/left/tight/bottom of all the blocks + sides of the container. As this solution uses floats, the last row is aligned to the left.
The number of blocks in one line adapts to the width of the window.