Reputation: 27474
Here's the effect I want: I have a set of tiles that I want to arrange in a grid on the screen, as many across as will fit given the screen size. Then, I want the whole block centered, i.e. whatever space is left over after fitting as many tiles as possible, I want split half left and half right. Or, if there aren't enough tiles to fill the width, I want the remaining space divided.
For example, let's represent each tile as "XXXX". We have some space between them, which I'll represent with an "-". Let's say we have five tiles. So, on a very wide screen, we might see this:
---XXXX-XXXX-XXXX-XXXX-XXXX---
On a narrower screen:
--XXXX-XXXX-XXXX-XXXX---
--XXXX------------------
Narrower still:
-XXXX-XXXX-XXXX-
-XXXX-XXXX------
Etc.
The tiles are div's with various stuff inside. For purposes here, we can treat them as an atomic unit.
I can get the tiles to wrap easily enough by making them float's or inline-blocks. I thought I could then just wrap them in a larger div, then center that div within an outer div. But no.
If I make them float's, it centers fine as long as they all fit on one row. But once it takes two rows, they all go flush left. It looks like CSS's layout engine calculates the width of the row as if there was no wrapping, uses that to calculate centering, makes left and right margin 0, and THEN wraps within the inner block.
The closest I've come is to make them inline-blocks and put text-align: center on an outer block. But then, the last row is centered under the first row, instead of being flush-left under the first row.
See http://jsfiddle.net/vaLLsudh/ for that last, almost solution.
Upvotes: 0
Views: 79
Reputation: 27474
ChristopherThomas's answer has merit. But I ended up doing it with JavaScript:
In a function that gets called during load (not showing the whole load process because there's a bunch of stuff not relevant here, or in any rational universe for that matter):
tileMargins();
$(window).resize(tileMargins);
And then:
function tileMargins() {
var w1 = $(".outer").width();
var wtile = $(".inner .tile").outerWidth(true);
var x = Math.floor(w1 / wtile);
var margin;
if (x < 1) {
margin = 0;
}
else {
var maxx = $(".inner").children().length;
if (x > maxx) x = maxx;
margin = (w1 - wtile * x) / 2;
}
$(".inner").css("margin-left", margin + "px");
}
That seems like an awful lot of code just to center a block. If someone can show me a simpler way, I'm interested.
Upvotes: 1
Reputation: 372
I've only done this with three blocks because I'm working on kind of a small screen but, Is this what you mean?
http://jsfiddle.net/vaLLsudh/3/
I've used some rough values but you could do the maths properly. This also assumes you are always going to be working with blocks of fixed widths.
You would have to write (max number of horizontal blocks - 1) media queries, but that might not be all that painful depending on what sort of limits you are thinking of imposing.
If you are pre-compiling your CSS with LESS or SASS also, you could probably output them as a loop for a single point of maintenance.
.outer {
text-align: center;
}
.inner {
display: inline-block;
width: 700px;
text-align: left;
}
.tile {
display: inline-block;
text-align: left;
width: 200px;
height: 100px;
border: 10px solid black;
margin: 0 10px 10px 0;
}
@media(max-width:800px) {
.inner {
width: 500px;
}
}
@media(max-width:600px) {
.inner {
width: 220px;
}
}
Upvotes: 2