Centering a variable width grid while aligning its elements to the left

感情迁移 提交于 2020-01-14 09:34:08

问题


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 divs 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!