【问题标题】:Items grid with inner padding only仅具有内部填充的项目网格
【发布时间】:2014-06-13 06:39:44
【问题描述】:

有哪些技术可以创建在每个项目之间具有填充但仅在网格内的产品网格?例如,我想要达到的目标如下:

示例标记:

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

CSS:

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

(在上面,.item 将被输出 9 次)。

解决方案需要与 IE8+ 兼容,并且最好使用非 hack 的技术。我曾尝试将 display: tableborder-spacing 属性一起使用 - 但这也会输出外侧的填充。

我知道我还可以为项目添加特定的类来控制是否为该项目显示填充,但我希望有一个更“自动化”的解决方案。

编辑:应动态计算填充宽度,例如,如果容器为 960 像素,则填充将是 30 像素宽。

其次,如果最后一行的项目少于 3 个,则这些项目不应出现在该行的中心,即如果只有两个项目,那么最后一个“单元格”应该是空的。

编辑:到目前为止,所有解决方案都坚持指定间隙/填充的宽度。 我想动态计算填充。我需要指定的唯一宽度是.item,目前是固定的300px。

【问题讨论】:

  • 我刚刚意识到我的答案不符合您的要求...这更适合您吗? jsfiddle.net/webtiki/USNMK/8
  • 你好网络提基。我以前见过这种技术 - 除了最后一行的项目较少之外,它工作得很好,它们不会彼此对齐。

标签: html css responsive-design grid-layout fluid-layout


【解决方案1】:

响应式网格

  1. 流体宽度项目
  2. 它们之间的内部流体间隙
  3. IE8+ 支持(至少)

DEMO

  1. 为具有百分比宽度的项目添加一般百分比边距,确保elements widths + left/right magins = 100%;
  2. 通过在容器上设置相同值的负边距来补偿外部边距(容器和项目之间)
  3. 使用overflow:hidden; 添加通用包装器

这很简单,并且不使用 IE8 不支持的任何属性。如果您删除边框和 box-sizing 属性,我很确定它可以在 IE7 中获得不错的输出。
只是为了确保,负边距不是“黑客”:

允许边距属性为负值source : w3.org

HTML:

<div id="wrapper">
    <div id="container">
        <div class="item"></div>
        <div class="item"></div>
        ...
    </div>
</div>

CSS:

#wrapper {
    overflow:hidden;
}
#container {
    margin: -1.5%;
    background:lightgrey;
}
#container:after {
    content:'';
    display:block;
    clear:both;  /* clear the floats */
}
.item {
    margin:1.5%;
    width:30.3333%;
    padding-bottom:10%;  /* to simulate height on the empty items */
    background:grey;
    border: 1px solid #000;
    float:left;

    /* following only if you want to add borders to the items */
    box-sizing:border-box;
}

之后,您只需使用媒体查询更改.items 的宽度,即可在所需断点处重新排列一行中的元素数。

例子:

@media screen and (max-width: 600px) {
    .item {
        width:47%;
    }
}

【讨论】:

  • 不错的完美解决方案:thumbsup:
  • 这太棒了。我一直在研究网格,使用各种类(第五、第四、第三、第二等)来匹配规则和媒体查询。这可以大大降低复杂性。
  • 如果盒子的高度不同,您知道如何让物品对齐吗?示例:jsfiddle.net/USNMK/6
  • @AndyM 当您的意思是对齐时,您的意思是所有块都应该具有相同的高度,或者您的意思是它们应该在每一行中垂直对齐?
  • 我明白了!非常感谢。
【解决方案2】:

测试这段代码:

body {
   margin:0;
   padding:0;
 }
 #wrapper {
  overflow:hidden;
  width:1200px;
  margin:100px auto;
  padding:10px;
  display:table;
  }
  #container {
   display:table-row;
  }
 .item {
   width: 33.3333%;
   min-height: 20px;
   height: auto !important;
   max-height: 200px;
   word-wrap: break-word;
   border-right:1px solid #ddd;
   display:table-cell;
   padding:10px;
   border-bottom:1px solid #ddd;
   border-top:1px solid #fff;
  }
  #container .item:first-child{
  border-left:1px solid #ddd;
  }
  #container:first-child .item{
    border-top:1px solid #ddd;
  }

// use the html 

  <div id="wrapper">
    <div id="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
    <div id="container">
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
    </div>
    <div id="container">
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
    </div>
    <div id="container">
        <div class="item">10</div>
        <div class="item">11</div>
        <div class="item">12</div>
    </div>
</div>

【讨论】:

    【解决方案3】:

    按照您的规范,这是:

    • 基于 Div 的项目网格;
    • 动态计算项目之间的间距;
    • 跨浏览器;
    • 具体项目和容器宽度;
    • 没有特定于网格布局的硬编码项目类。

    您可以使用这组样式来实现:

    /* 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>
    

    您可以在JSFiddle 上观看。

    假设

    • 我在容器的末尾添加了一个 div,以确保它的高度与浮动 div 的高度相同。您可以根据您对 html 元素的特定整体配置进行调整。

    • 通过这种规则.item:first-child + * + * + * 实现的margin-left 修复是由于跨浏览器的必要性。我将第一个子选择器与“*”选择器一起使用,因为所有主要浏览器(IE6+、FF、Chrome、SF、Opera)都支持它。它实际上是硬编码的,但我的想法是,如果你想要一些不那么硬编码的东西,那么你可以用一个针对 .item-head 的规则替换这些规则(应该在左边框旁边的所有项目上的类)。

    无论如何,我认为基于我的简单解决方案,您可以非常轻松地将其演变为您想要的解决方案。玩得开心!

    【讨论】:

      【解决方案4】:

      text-align: justify 用于容器,display:inline-block 用于没有浮动的项目(无论如何它都是浮动的……它现在是内联的)。

      简单,响应迅速,适用于许多旧版浏览器

      编辑:忘了说“还有一个额外的 div,在最后清除,也显示内联,但 100% 宽度”

      http://jsfiddle.net/qFEB7/1/

      【讨论】:

        【解决方案5】:

        我有一些解决方案,但它不是完全您正在寻找的,因为我认为如果没有使用 :nth- 的解决方案就无法完成您想要的工作孩子(原生或使用 JS polyfill)。

        看看我的示例:http://jsfiddle.net/ncA64/1/

        我已经多次构建过这样的产品网格。它为您在每个图块周围提供 30 像素的固定边距,并且每个图块的宽度会弯曲以适应父对象的宽度。

        代码,供参考。 HTML:

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

        和 CSS:

        /* basic box model reset */
        * {
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            padding: 0;
            margin: 0;
            border: none;
        }
        
        #container {
            min-width: 960px;
            margin: -30px -15px 0;
            overflow: hidden;
        }
        
        .item {
            width: 33.333333%;
            float: left;
            background: #fff;
        }
            .item .inner {
                min-height: 100px;
                margin: 30px 15px 0;
                border: 1px solid #000;
                background: #ffc;
            }
        

        【讨论】:

          【解决方案6】:

          我想我会在Bootstrap 中提供一个快速响应的示例。

          使用Bootstrap's grid system,以下 CSS 将删除 3 列(每行)网格的外部接触列上的任何边距:

          .tight-grid div[class*='col-']{
            margin-top:15px;
            margin-bottom:15px;
          }
          
          .tight-grid .row:first-child div[class*='col-'] {
            margin-top:0;
          }
          
          .tight-grid div[class*='col-']:nth-child(3n+3){
            margin-right:0;
          } 
          .tight-grid div[class*='col-']:nth-child(3n + 1) {
            margin-left:0;
          }
          
          .tight-grid .row:last-child div[class*='col-'] {
            margin-bottom:0;
          }
          

          请记住,列已经由引导程序应用了左右填充(15px 值)。因此,如果这不是所需的数量,请在上述 css sn-p 的第一个样式规则中覆盖它。


          DEMO | CODE

          注意:我知道 OP 没有特别要求引导程序。我只是想提供一个简单的方法就是使用引导程序来玩 :)

          【讨论】:

            【解决方案7】:

            这是使用:nth-child 的一种方法。 (example)

            只需给每个元素一个top/left 边框,然后删除前三个元素的top 边框,然后删除第一个、第四个和第七个元素的left 边框。

            .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;
            }
            

            应动态计算填充宽度,例如,如果容器为 960px,则填充将是 30px 宽。

            你可以使用calc()

            width:calc(33.333% - 20px) 这样的东西会起作用。不过这会限制support to IE9

            Full Screen Example

            其次,如果最后一行的项目少于 3 个,则这些项目不应出现在该行的中心,即如果只有两个项目,那么最后一个“单元格”应该是空的。

            这应该可以正常工作 - example with the ninth item removed

            【讨论】:

            • nth-child 不支持 IE8,所以这会让你的答案无用)
            • @AlexPrinceton 虽然答案可能无法满足 OP 的所有要求,但我不会认为它完全没用,因为它确实回答了这个问题。将来可能对人们有用。这不是 Stack Overflow 的目标吗?另外,IE8支持什么?
            【解决方案8】:

            请不要认为这是一个正式的答案。乔希的显然很优雅。

            我喜欢这类问题,因为它让我有机会思考解决问题的各种方法。我已经使用表格和浮动 div 来提供总共 4 种其他方法来做到这一点。如果我能想到更多,我会添加它们。

            FIDDLE

            HTML 中的第一个表格,只是为了满足 SO 要求。

            HTML

            <table class='table1'>
                <tr><td></td><td></td><td></td></tr>
                <tr><td></td><td></td><td></td></tr>
                <tr><td></td><td></td><td></td></tr>
            </table>
            

            “表格不优雅”-(表格数据除外)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-11-10
              • 2018-05-20
              • 2016-08-10
              • 2020-09-07
              • 2019-06-23
              • 2021-12-10
              • 1970-01-01
              相关资源
              最近更新 更多