2

我在商店里展示产品。每个产品都有自己的盒子。我想将盒子放在一个网格中,每行 2 个。但是它们也将被划分为类别,因此我想在属于该类别的每组框上方放置一个全角标题。这是我的 HTML:

    <section class="product-listing">

        <h2>Category 1</h2>

        <section>first</section>
        <section>second</section>
        <section>third</section>

        <h2>Category 2</h2>

        <section>fourth</section>
        <section>fifth</section>

        <h2>Category 3</h2>

        <section>sixth</section>
        <section>seventh</section>
        <section>eighth</section>
        <section>ninth</section>
    </section>

和 CSS:

.product-listing {
    width:410px; height:100%
    background:#000;
}
.product-listing > section {
    float:left;
    width:200px;
    margin:10px 10px 0 0;
    background:#ff0000;
}
.product-listing > section:nth-of-type(2n+2){
    margin-right:0;
}

JS 小提琴

如您所见,网格工作正常,直到引入第二个 h2 元素,之后它分崩离析,因为如果最后一组具有奇数个框,则 2n+2 被丢弃。基本上我需要做的是在每个标题之后重置 2n+2 公式。

快速而肮脏的方法是将每组框包装在一个 div 中,但如果可以避免的话,我宁愿不向页面引入不必要的标记。

有更清洁的解决方案吗?

4

1 回答 1

0

注意:如果您想了解网格布局规范,请不要错过此答案的结尾。

一种只需要 1 个额外元素(可能)的方法是包装整个.product-list元素,并将显式宽度放在该包装器上。这样,您可以在 上使用负边距.product-list来说明section项目边距,而不必担心无论有多少元素交替边距声明 – JSBin 示例here

<div class="wrap">
  <section class="product-listing">

    <h2>Category 1</h2>

    <section>first</section>
    <section>second</section>
    <section>third</section>

    <h2>Category 2</h2>

    <section>fourth</section>
    <section>fifth</section>

    <h2>Category 3</h2>

    <section>sixth</section>
    <section>seventh</section>
    <section>eighth</section>
    <section>ninth</section>
  </section>
</div>

.wrap {
  width: 410px; /* put explicit width here */
}
.product-listing {
  margin: 0 -5px; /* "expand" the .product-listing section */
}
.product-listing > section {
  float:left;
  width:200px;
  margin:10px 5px 0; /* only put equal horizontal margin on items */
  background:#ff0000;
}
.product-listing > h2 {
  clear: both;
  margin-left: 5px; /* add side margins here too */
  margin-right: 5px;
}

对额外包装器的需求来自负边距,当它们具有明确的宽度时,它们不会在两个水平方向上扩展元素框——这是边距模型的一个奇怪技巧。

如果这不起作用,那么无聊的答案可能是围绕每个section项目集合的额外包装器不会那么糟糕——它会让你的 CSS 更加灵活,并且对你的 HTML 的消费者来说几乎不重要。毕竟,每个类别下都有许多项目——为什么不让每个集合成为一个ul或至少一个div(如果你觉得列表语义不合适)?

最后,您可以在没有额外元素和网格布局模块规范的情况下执行此操作,但支持仍处于试验阶段。由于此问题带有 标记css-grids,因此我将在此处包含该解决方案以供将来的访问者使用:

.product-listing {
  display: grid;
  grid-template-columns: 1fr 1fr; /* equal width columns */
  grid-column-gap: 10px;
}
.product-listing h2 {
  grid-column: span 2;
}

网格规范中内置的自动布局算法将负责其余的工作。在 Chrome Canary 中尝试上面的示例(2015 年 10 月 - 其他地方也很快:WebKit Nightlies 和 Firefox 在实施 Grid 方面也不甘落后)。JSBin 示例在这里

于 2015-10-18T16:21:25.560 回答