问题
Consider the following
<div class="container">
<div class="grid">
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
....
</div>
</div>
Using images, basically what I have is something like this

As you can see the green blocks and the container are aligned to the left
What I want to acheive is something like this.

The .unit
elements have constant width
The .grid
element should expand with width (so that more unit
elements would fit into 1 line) while being always centered within .container
.
Any clue how to achieve that using only CSS (and maybe some html wrappers if necessary) ?
回答1:
Let me begin by saying that this is an interesting question and my first thought was that flexbox is the way to solve this. I have tried all manner of flexbox arrangements, but this type of solution eluded me. So, below is the solution that uses floating, clearing, and media queries.
For this example, I have assumed that each row would have at least 3 and no more than 9 boxes. However, you can extend this solution to handle anywhere between 1 and more than 9 boxes.
Here's HTML:
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Here's a CSS that (1) performs a mini-reset to eliminate browser-applied paddings and margins that may interfere with sizing and (2) formats the .grid
and its div
children:
* {
margin: 0;
padding: 0;
}
.grid {
display: table;
outline: 1px solid blue;
min-width: 330px;
margin: 0 auto;
}
.grid > div {
width: 100px;
height: 61px;
margin: 5px;
background-color: teal;
float: left;
}
The .container
block was eliminated because .grid
is displayed as a table. The latter is a block that shrinkwraps around its children and margin: 0 auto
can be applied to center it on the page. The .grid
's min-width
of 330px assures that a minimum of three blocks can fit per line. Whenever floating happens within a table
element, its margins do not collapse, therefore no explicit clearing of floats (e.g., via clearfix) is necessary.
Each .grid
div
child takes 110px of horizontal space (100px width + 10px in left and right margins). This number is important for the media queries code that follows below:
@media screen and (min-width: 330px) and (max-width: 439px) {
.grid > div:nth-of-type(3n + 1) {
clear: left;
}
}
@media screen and (min-width: 440px) and (max-width: 549px) {
.grid > div:nth-of-type(4n + 1) {
clear: left;
}
}
@media screen and (min-width: 550px) and (max-width: 659px) {
.grid > div:nth-of-type(5n + 1) {
clear: left;
}
}
@media screen and (min-width: 660px) and (max-width: 769px) {
.grid > div:nth-of-type(6n + 1) {
clear: left;
}
}
@media screen and (min-width: 770px) and (max-width: 879px) {
.grid > div:nth-of-type(7n + 1) {
clear: left;
}
}
@media screen and (min-width: 880px) and (max-width: 989px) {
.grid > div:nth-of-type(8n + 1) {
clear: left;
}
}
@media screen and (min-width: 990px) {
.grid > div:nth-of-type(9n + 1) {
clear: left;
}
}
The rationale behind the code is this: if there is enough space to include only n blocks per line, then every (n + 1)th block's left edge is cleared, which moves the block to a new line.
And, here's a fiddle: http://jsfiddle.net/5hWXw/. Resize the preview window to see the adjustments.
回答2:
In your CSS, make sure:
1. In the .grid
rule, text-align
is set to center
2. In the .unit
rule, display
is set to inline-block
. The div
element is a block-level element and so each new element is displayed on a new line. Giving the display
property a value of inline-block
forces all the div
s with class unit
to be displayed on the same line (until there's no more space). Also text-align : center
doesn't work with elements with display property set to block
, and block-level elements have a display value of block
by default.
回答3:
You have to just give value to your classes like this,
.grid { text-align:center; }
.unit { display:inline-block; }
I hope this will solve your issue.
If not, than please show your full code via Jsfiddle.
回答4:
@DRD's answer is nice but requires lots of media queries. If the following floats your boat however: don't look too far when it can be simple: set a padding-left/-right on your container...
.grid {
padding: 0 5%;
}
You'll notice the whitespace is not even when the width isn't a multiplication of the .unit
's entire box (padding, margin, border, width). Setting a %-based width can help here.
See this fiddle for a test case. I've added a tiny bit of Javascript to adjust the padding dynamically, remove it to see the CSS-only result. EDIT: @DRD created a jQuery function which works better than my JS, see it here (don't forget to include jQuery if you want to use it).
回答5:
It seems that a solution to this is similar to that in here Flex-box: Align last row to grid
First of all setting .grid
to inline
, then adding more div's with height: 0
would do the trick, number of extra div's should be atleast equal to max-number of units
in 1 line (minus 1).
This is a bit incontinent, but still easier than defining multiple @media
as @DRD suggested, and doesn't require javascript/window.resize() handling
<div class="container">
<div class="grid">
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
<div class="unit empty"></div>
</div>
</div>
.container {
display: block;
text-align: center;
}
.empty {
height: 0 !important;
}
.grid {
display: inline;
}
I still hope for a better solution using only css
来源:https://stackoverflow.com/questions/24728772/centering-a-variable-width-grid-while-aligning-its-elements-to-the-left