Items grid with inner padding only

2019-01-15 09:56发布

What techniques are there for creating a products grid that has padding between each item, but only within the grid? For example, what I am trying to achieve is the below:

enter image description here

Sample markup:

<div id="container">
    <div class="item">
         <!-- content -->
    </div>
</div>

CSS:

#container { width: 100%; min-width: 960px; }
.item { float: left; width: 300px; height: 100px; }

(in the above, .item is going to be output 9 times).

The solution would need to be IE8+ compatible and preferably using a technique that isn't a hack. I have tried using display: table with border-spacing property - but this outputs the padding on the outer sides too.

I know I can also add specific classes to items to control whether the padding is shown for that item, but I was hoping for a more 'automated' solution.

Edit: The padding width should be calculated dynamically, so for example if the container is 960px, the padding is going to be 30px wide.

Secondly, if there are less than 3 items on the last row, these should not appear centered on the row, i.e. if there are only two items then the last 'cell' should just be empty.

EDIT: All the solutions so far insist on specfying the width of the gap/padding. I want to have the padding calculated dynamically. The only width I need to specify is that of .item, which is currently a fixed with of 300px.

8条回答
走好不送
2楼-- · 2019-01-15 10:55

Following your specification, this is:

  • Grid of items based on Divs;
  • Dynamically calculated spacing between items;
  • Cross Browser;
  • Specific item and container widths;
  • No hardcoded item classes to specific to the grid layout.

You can achieve that with this set of styles:

/* ensures the height correctness for the parent of .item, the #products. */
.clearfix{ clear:both } 
#products{ border:1px solid gray; width:960px;}

.item{ 
    float:left; 
    background-color:silver; 
    border:1px solid blue; 
    width:300px; 
    height:100px; 
    margin-left:2.5%;
    margin-top:2.5%;
}

/* fixes top margin. */
.item:first-child, .item:first-child + *, .item:first-child + * + *{
    margin-top:0px;
}

/* fixes margin of first divs on the left. */
.item:first-child,
.item:first-child + * + * + *,
.item:first-child + * + * + * + * + * + *,
.item:first-child + * + * + * + * + * + * + * + * + * {
    margin-left:0px;
}

HTML

<div id="products">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>

    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>

    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>

    <div class="clearfix"></div>
</div>

You can watch this on JSFiddle.

Assumptions

  • I've added a div to the end of the container to ensure that it's height as in consideration the floated div's height. You can adjust this based on your specific overall disposition of html elements.

  • The margin-left fix implemented through this kind of rules .item:first-child + * + * + * is due to the cross browser requisite. I used the first-child selector with the '*' selectors, because it is supported by all main browsers (IE6+, FF, Chrome, SF, Opera). It's in fact hardcoded, but my idea about it, is that, if you want something less hardcoded then you can replace those rules by a rule targeting .item-head (the class that should be on all items next to the left border).

Anyway, I think that based on my simple solution, you can very easily evolve it to your desired solution. Have Fun!

查看更多
【Aperson】
3楼-- · 2019-01-15 10:56

Here is one approach using :nth-child. (example)

Just give each element a top/left border, then remove the top border for the first three and then remove the left border for the first, fourth, and seventh elements.

.item {
    float: left;
    width:300px;
    height: 100px;
    background:lightgrey;
    border-left: 30px solid #fff;
    border-top: 30px solid #fff;
}
.item:nth-child(-n+3) {
    border-top:none;
}
.item:nth-child(3n + 1) {
    border-left:none;
}

The padding width should be calculated dynamically, so for example if the container is 960px, the padding is going to be 30px wide.

You could use calc() for that.

Something like width:calc(33.333% - 20px) would work. This would limit the support to IE9 though.

Full Screen Example

Secondly, if there are less than 3 items on the last row, these should not appear centered on the row, i.e. if there are only two items then the last 'cell' should just be empty.

This should work as expected - example with the ninth item removed.

查看更多
登录 后发表回答