跨越多行+列的动态网格图块

时间:2013-03-01 15:52:33

标签: html css

如果没有看到结果,这可能很难解释,所以请看一下这些例子:

JSFiddle Example 1 - looks okay
JSFiddle Example 2 - broken

来自小提琴的代码:

HTML:

<ul id="homepage-grid">
        <li id="tile11" class="col1 row1 sizex1 sizey1">
            <a href="#" title="test">
                <img src="http://placehold.it/295x160" alt="test" title="test" style="width: 295px;height: 160px" />
            </a>
        </li>
        <li id="tile8" class="col2 row1 sizex2 sizey1 last">
            <a href="#" title="test">
                <img src="http://placehold.it/602x160" alt="test" title="test" style="width: 602px;height: 160px" />
            </a>
        </li>
        <li id="tile1" class="col1 row2 sizex1 sizey1">
            <a href="#" title="testing">
                <img src="http://placehold.it/295x160" alt="testing" title="testing" style="width: 295px;height: 160px" />
            </a>
        </li>
        <li id="tile4" class="col2 row2 sizex2 sizey1 last">
            <a href="#" title="test3">
                <img src="http://placehold.it/602x160" alt="test3" title="test3" style="width: 602px;height: 160px" />
            </a>
        </li>
        <li id="tile10" class="col1 row3 sizex1 sizey2">
            <a href="#" title="test">
                <img src="http://placehold.it/295x332" alt="test" title="test" style="width: 295px;height: 332px" />
            </a>
        </li>
        <li id="tile12" class="col2 row3 sizex1 sizey2">
            <a href="#" title="test">
                <img src="http://placehold.it/295x332" alt="test" title="test" style="width: 295px;height: 332px" />
            </a>
        </li>
        <li id="tile2" class="col3 row3 sizex1 sizey1 last">
            <a href="#" title="testing2">
                <img src="http://placehold.it/295x160" alt="testing2" title="testing2" style="width: 295px;height: 160px" />
            </a>
        </li>
        <li id="tile9" class="col3 row4 sizex1 sizey1 last">
            <a href="#" title="test">
                <img src="http://placehold.it/295x160" alt="test" title="test" style="width: 295px;height: 160px" />
            </a>
        </li>
    </ul>

CSS:

#homepage-grid {
    width:910px;
    position:relative;
    padding:0;
    overflow: hidden;
}

#homepage-grid li {
    list-style:none;
    float:left;
    padding:0 12px 12px 0;
    display:block;
}

#homepage-grid li.last {
    list-style:none;
    float:left;
    padding:0 0 12px 0;
}

#homepage-grid li a {
    display:block;
}

基本上我想要创建的是一个动态网格,它由数据库填充(数据库部分目前工作正常)。在网格中,每个磁贴最多可以跨越3列,但是可以跨越无限行,这似乎是我遇到问题的地方。

我在使用HTML / CSS时遇到了如此动态的问题。正如您所看到的,从示例1到示例2的一个小变化并且它打破了大部分网格,因为应该向上推动左下方的平铺以填充空间,并且应该向上移动右平铺以填充该空间。

但是,我可以完全控制代码,因此HTML / CSS可以根据需要进行更改(即添加类/内联样式/等)。

我想这可以(相对)轻松地使用表格,但由于它不是表格内容,我真的不想走这条路。

有没有办法让CSS变得动态?
我是否需要使用更多的内联样式来实现这一目标? 我应该以其他方式这样做,例如绝对定位而不是浮动?

如何实现这一目标的任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:2)

我的第一个想法是将height #title12设置为160px,但如果下面的元素相同width,则无效。< / p>

相反,您可以尝试以下方法:

假设网格的每个“行”都有一个固定的高度,请使用<div>...</div>或类似的块元素包裹height:160px;(或任何适当的大小,但要使其相同,每个div“行”)。

用第一行图像填充第一行。对于第二行(及后续行),确定每个“单元格”是否与之前的行重叠。如果是这样,请添加一个“填充”块,其中包含一个空块元素,heightwidth等于您想要的行和列大小。

这允许<li>...</li>项将div“行”溢出到下面的一行(因为默认情况下溢出设置为visible)。空块元素阻止下一行与前一行重叠溢出。

这种方法的缺点是:

  • 这会让你的HTML更加丑陋。
  • 这可能太像桌子了,值得使用而不是真正的桌子。
  • 在服务器端需要一些额外的工作。

编辑:此外,列表中不允许<div>,因此您需要在每行中启动/停止列表。或者,也许使用<ul> </ul>作为行而不是<div>

答案 1 :(得分:1)

好的,这只是一个想法。假设您最多有3列和固定的行高,您可以使用数组来存储每列的超出行数,然后添加一个负的margin-top或类来“拉出”特定数量的行。 e.g:

在添加2行项目后,每列的行数为[0][0][0],就像[2][0][0]添加另外两个高度为3行和2行的项目[2][3][2] [5][3][2] }} 将放置的下一个项目应该放在第一个最短列中,并且将被最大值减去最短值的差值拉高,在本例中为一列(3 - 2),如果添加的元素是2行高池将是{{1}},下一个项目将放在最右边的列中,并将被拉出3行(5 - 2)。

这就是全部!乍一看,它看起来会起作用,但我还没有测试过。

答案 2 :(得分:1)

你将使用浮动遇到这个问题。但是,您可以更改该页面上一个元素的位置,并且所有内容都会像您期望的那样落实到位。

Updated Fiddle

将以下内容添加到CSS中:

#homepage-grid li#tile10 {
    position: absolute;
    top: 342px;
}

这会将违规元素从文档流中删除,从而消除了对应用于其余列表项的“float”分配给它的垂直空间的保留。最后一项是浮动的,因此不会与绝对定位的瓷砖重叠。

修改

根据以下评论,here's a slightly more flexible way of doing this。该示例适用于已发布的代码。

用更新的小提琴做出的假设:

  1. sizex1,sizey1,sizex2等......是常量值
  2. 这些内容的右边内容将被正确浮动(这将对左浮动项目反向运行,但这些情况看起来似乎不会成为问题,因为右侧的项目将正确浮动,如果元素到左边是垂直的大)
  3. 用户可以覆盖样式,或在创建布局时应用样式这主要是为了控制position: absolute不必要地应用于某些元素
  4. 这是做什么的:

    此CSS根据具有某些类的兄弟姐妹的存在设置不同的规则。这就是sizex1 sizex2 sizey1sizey2值的恒定性很重要的原因。

    CSS:

    #homepage-grid li.col1:not(.row1):not(.row2) {
        position: absolute;
    }
    #homepage-grid li.col1.sizey1.row1 ~ li.col1.row2 { /* The first column of the first row has a sizey of 1 */
        top: 172px;
    }
    #homepage-grid li.col1.sizey2.row1 ~ li.col1.row2{ /* The first column of the first row has a sizey of 2 */
        top: 342px;
    }
    #homepage-grid li.col1.sizey1.row1 ~ li.col1.sizey1.row2 ~ li.col1.row3 { /* The first column of the first row has a sizey of 1 and the first column of the first row has a sizey of 1 */
        top: 344px;
    }
    #homepage-grid li.col1.sizey2.row1 ~ li.col1.sizey2.row2 ~ li.col1.row3{ /* The first column of the first row has a sizey of 2 and the first column of the second row has a sizey of 2 */
        top: 684px;
    }
    #homepage-grid li.col1.sizey2.row1 ~ li.col1.sizey1.row2 ~ li.col1.row3,
    #homepage-grid li.col1.sizey1.row1 ~ li.col1.sizey2.row2 ~ li.col1.row3 { /* The first column of the first row has a sizey of 2 and the first column of the second row has a sizey of 1, or vice versa */
        top: 514px;
    }
    

    理想情况下,您需要在页面投放时设置#homepage_grid li.col1值。这样,您可以选择哪些切片从文档流中分离出来以保持正确的间距。我通常使用:not()选择器来完成此操作,但如果您正在寻找较旧的浏览器兼容性,则可以轻松使用覆盖。

    示例:

    #homepage-grid li.col1:not(.row1):not(.row2) {
        position: absolute;
    }
    

    *上述内容只会破坏文档流程中的第3行及更多行。

    #homepage-grid li.col1 {
      position: absolute;
    }
    #homepage-grid li.col1.row1, #homepage-grid li.col1.row2 {
      position: static;
    }
    

    这完成了与上面相同的事情,但更详细。但是,它将在不太符合标准的浏览器中正确呈现。

    编辑2 为了清楚起见,这是一个使用jQuery在页面加载时将相应元素设置为静态的示例。

    Another fiddle example

答案 3 :(得分:0)

您需要一个允许嵌套的网格系统。

然后在网格布局中搜索整行。

然后在每一行搜索完整列等等。

答案 4 :(得分:-1)

我真的建议使用像Masonry这样的JavaScript插件。