【问题标题】:Table layout equivalent using DIVs使用 DIV 等效的表布局
【发布时间】:2010-10-11 17:24:15
【问题描述】:

我今天正在创建一个布局,如下所示:

+----+ +----+ +----+ +----+
|    | |    | |    | |    |
+----+ +----+ +----+ +----+

看起来很简单,但我还有一些额外的规格:

  1. 最大列数 (n) 需要是动态的(此 HTML 页面是在运行时生成的)。
  2. 整个集合必须是水平流动的(当窗口变窄时,它们会尽可能地压缩。
  3. 整个集合还必须在屏幕上居中,在任何 1 行中一次不超过 n 列。
  4. 理想情况下,最右边的“框”会放到下一行,并在必要时重新排列,即当窗口变窄且 n 个框不适合屏幕时。
  5. 当然,当要显示的元素超过 n 个时,它们只会创建这些元素的额外行。
  6. 各个框都带有圆角边框,可以通过任何操作进行点击。

通过一些研究(谷歌+对我发现的示例的改编),我能够像使用 div 和 css 那样做#6。但是,我很难做到 2-4。我几乎一路走到了那里,但我一生都无法让 2 和 3 工作。 2 没什么大不了的,但 3 至关重要。我正在使用浮动 div 进行定位,并找到了一个 example site 提到使用相对定位和左移等来使其居中,但它在我的情况下不起作用(尽管该示例工作正常)。在我的情况下,他们会从中心开始而不是居中,然后向右移动,让它看起来很滑稽,所以我不知道我错过了什么。

在为此苦苦挣扎了几个小时后,我在 5 分钟内使用以下代码完成了它:

<simplified code>
max_columns = 3; /* whatever */
html = "<table>";
for i = 1 to num_elements
  if i % max_columns eq 1 then
    html += "<tr>";
  endif
  html += "<td>";
  html += "<div>my element</div>"; /* This is a complex multi-leveled div */
                                   /* that makes boxes with rounded corners */
  html += "</td>";
  if i % max_columns eq 0 or i eq num_elements then
    html += "</tr>";
  endif
endfor
html += "</table>";
</simplified code>

这满足了我的所有要求,除了 #4 很好,但不是必需的。

问题:[你会如何]/[有什么办法]不使用表格吗?

编辑:我没有机会实施/测试以下任何潜在的解决方案,因为我需要完成其他方面(在接下来的 5 天内),然后再回到这个问题。我当前的 lame (?) 解决方案似乎工作正常,除了 req #4,所以这个问题现在不在我的关键路径上。但我对此进行测试并发布反馈。所以我会一直保持这个问题,直到那时。我很欣赏这些回应。谢谢。

编辑#2:所以我尝试了以下一些解决方案,这就是我想出的:

<html>
    <head>
    <style>
  .box {
          width: 19%;
          height: 150px;
          border: 1px solid black;
          display: inline-block;
          margin: 3 0 0 0;
  }
  #center {
          text-align: center;
          border: 1px solid green;
          width: 80%;
          height: 85%;
          padding: 0 0 0 0;
          vertical-align: middle;
          margin: 0;
  }
  .footr{
          text-align: center;
          border: 1px solid green;
          width: 80%;
          height: 38px;
          padding: 0 0 0 0;
          vertical-align: middle;
          margin: 0;
  }
  </style>
    </head>
    <body style="margin-left:0; margin-top:0; margin-right:3;" >
    <div style="background-image: url(x); height: 60; width:131; float:left;"></div>
    <div style="background-image: url(x); background-repeat:repeat-x; height:60;"></div>
    <div class="clearer"></div>
    <center>
    <div id="center">
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box" style="float:right;">Blah</span><br>
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box" style="float:right;">Blah</span><br>
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
    </div>
    <div class="footr">Footer</div>
    </center>
    </body
</html>

你可能会说,这解决了我几乎所有的问题,除了 2/3(我原来的 Q 中没有提到:

  1. 整个块的垂直对齐,使其垂直居中
  2. 在水平行上,我希望跨度粘附在外部 div 的外侧边缘,内部 div 之间的间距均匀。
  3. 在小于n 跨度的行上,我会让他们在前一行的第 3 个跨度下排队。

我做这个练习完全是为了我个人的“我只是想从头开始”,而且是在我自己的时间。为了工作,我已经做了大部分(很少)使用表格来正确排列东西。

PS:请原谅一些格式错误的 HTML 和内联样式等。一旦我得到 100% 有效的解决方案,我清理它。

【问题讨论】:

  • 根据您的要求——注意术语“列”和“行”——这似乎满足了作为“表”的语义要求,那么为什么不使用正确的语义标记呢?如果它像鸭子一样嘎嘎叫……
  • 是的。但是,我的术语纯粹是我的思维方式的反映,我试图不依赖这种方式。但这就是我为了权宜之计而最终做的事情。我想,如果 div 采用了 de-riguer (?) 的格式化方式,那么肯定有一种简单的方法可以做到这一点吗?

标签: html css layout


【解决方案1】:

最好将表格用于表格数据。请注意Divitis 问题。

更新:如果这些“框”是指向其他地方的链接,那么只需使用锚点实现它们并适当地设置它们的样式。一种称为image replacement 的技术可能会对您有所帮助。关于如何布置这些链接,请查看listamatic horizontal lists

【讨论】:

  • 这是一个很棒的链接。我不是特别喜欢 div,但我在其中一些例子中看到了自己。主要是由于 HTML 无知。等不及我的 CSS/XHTML 书籍到了,我就可以阅读这个 shi-ite。
  • 哦,顺便说一句,在我原来的问题中,它真的不是表格数据。它们实际上是一些需要在主页上排列的复杂按钮(可点击的 div,如果您愿意的话)。而且我的描述有点简单,以免被无关的细节所困扰。
【解决方案2】:

问题:[你会怎么做]/[有吗? 任何方式]不使用 表?

只需给它们一个固定的宽度并将它们浮动到左边。 (如果它们没有设定宽度,这将是不够的)。

【讨论】:

  • 您将如何满足 nr 3 的要求?
  • 我在热衷于简单地回答动态、流动、变化的数量要求时错过了这一点。 :-(
  • 我不确定这是否可能,至少在没有 Javascript 或专有 CSS 的情况下是不可能的......
【解决方案3】:

试试这是否适合你:

<html>
    <head>
        <title>box test</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div id="boxContainer">
            <span class="box">1</span>
            <span class="box">2</span>
            <span class="box">3</span>
            <span class="box">4</span>
            <span class="box">5</span>
            <span class="box">6</span>
            <span class="box">7</span>
            <span class="box">8</span>
            <span class="box">9</span>
            <span class="box">a longer block</span>
            <span class="box">a longer multi <br/> lined<br/> block</span>
            <span class="box">12</span>
            <span class="box">13</span>
            <span class="box">14</span>
            <span class="box">15</span>
            <span class="box">16</span>
            <span class="box">17</span>
            <span class="box">18</span>
            <span class="box">19</span>
            <span class="box">20</span>         
        </div>
    </body>
</html>

#boxContainer{
    text-align: center;

    background-color: #D0DC16;
    border: 1px solid black;
    height: 100%;
    padding: 1em 0 1em 0;
    width: 100%;
}
.box{
    /*width: 24%;*/
    display: inline-block;

    padding: 2em;
    margin: 0.5em 0 0.5em 0;
    background-color: #DC6216;
    border: 1px solid black;
}

您可以将 .box 宽度更改为 (100/n)-1。 我不完全知道为什么是-1,但这可能与边距和边框不计入宽度以及单个像素不能划分为子像素的事实有关。

--编辑--
在 cmets 之后审查了代码。 用于自拟合的注释/注释框宽度线/每行固定数量的框。
添加了两个不规则框。

【讨论】:

  • 这将始终给他每行 4 个框,无论浏览器窗口的宽度如何...
  • 嗯,也许我误解了 req. nr 1?
  • 如果省略宽度,css 将在一行中容纳其内容允许的尽可能多的块。
  • 框需要有某种宽度,无论是 % 或 px 还是 em ,否则它们将默认为 100% 宽度
  • 仅在 Opera 中测试了我的代码,但如果我不为框提供宽度,它们会为内容收缩包装..
【解决方案4】:

你可以试试display:inline-block;。这将满足所有条件,除了扩大收缩的条件。

教程在这里:display:inline-block; tutorial

示例用法在这里:display:inline-block; example

【讨论】:

【解决方案5】:

这就是我想出的。您可能必须使用宽度来调整浏览器舍入错误/空白校正,但总体上应该可以。 IE 也可能需要明智地使用溢出:隐藏|自动。

<!DOCTYPE html>
<html><head><style type="text/css">

.container { width: 100%;text-align: center;}
.ib { min-width: 150px; display: -moz-inline-stack; display: inline-block; zoom: 1; *display: inline;}
.ib .styleMe { display: block; background: green; margin: 5px; text-align:left; border: 2px solid black; padding: 0 8px; }
.n1 .ib { width: 100%; } /* you could also use max-width here (if you can ignore IE6) and want jagged lines of items */
.n2 .ib { width: 50%; }
.n3 .ib { width: 33%; }
.n4 .ib { width: 25%; }
.n5 .ib { width: 20%; }
.n6 .ib { width: 16%; }
/*.nX .ib { max-width: 100/X; } may need to account for white-space/browser rounding errors too! */

</style></head>
<body>

<div class="container n4">
    <div class="ib"><div class="styleMe">
        <p>One</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Two</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Three</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Four</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Five</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Six</p>
        <p>Line 2</p>
    </div></div>
</div>
</body></html>

【讨论】:

  • 如何确定哪个 .n?您在调整大小时使用的类?
  • 使用原始问题 .n 将来自 max_columns (在他的代码中它将是 html = "
    " CSS 将handle.max_columns 可以是任何你需要的值,只要它是在 css 中定义的
  • 注意...如果您使用固定宽度而不是百分比宽度,您实际上并不需要 .nX 类。显示器将根据需要调整以最适合它的 contianer 添加/删除列/行。这个例子使用了最小宽度(也可以使用最大宽度),虽然这会对 IE6 有所改变!
  • 谢谢,当我完成页面的其余部分时,我会试试这个。看起来很有希望。我不能忽略 IE6(尽管令人沮丧的是,我 可以 忽略 FF 等,因为我的网络应用只支持 IE),所以我可能不得不按照你的建议调整一下宽度。
  • 对于上述宽度,您可以将 50% 更改为 49.9% 和 25% 更改为 24.9%;它将全面适用于 IE。上面唯一不适用于 IE6 的是最小宽度。您可以通过在 IE
【解决方案6】:

把你的 div 变成内联元素并给它们一个固定的宽度:

<html>
<head><title>Column test</title></head>
<style>
.box {
        width: 60px;
        height: 20px;
        border: 1px solid black;
        display: inline;
        margin: 3px;
}
.center {
        text-align: center;
        border: 1px solid green;
}
</style>
<body>
<div class="center">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
</div>
</body>
</html>

这将使它们像普通文本一样在彼此后面流动。一旦没有更多元素适合当前行,它们就会开始一个新的。

您需要固定宽度,因为默认宽度是 100%。如果可以说“宽度以适应内容”会很好,但这不起作用,因为 div 的内容需要 div 的宽度来布局本身(母鸡问题)。

【讨论】:

  • 有趣.. 如果这行得通,我会踢自己。在我屈服于快速'n容易之前,我处于“浮动”和“清除”地狱中。
  • “内联”的东西也会使它们居中吗?不幸的是,我的 VPN 连接中断(在新西兰已经过了午夜),我现在无法测试这个?
  • 使元素居中的最简单方法是使用
    但我怀疑它因没有语义价值而受到反对。
  • 是的,
    已经到位,但我的 div 出于某种原因拒绝服从。我怀疑嵌套的 div 是那里的罪魁祸首。我本可以尝试将 text-align:center 放在每个“容器”类型的 div 上,但这感觉太讨厌了。
  • 带 display:inline 的 div 不是和 一样吗?此外,您可以将盒子包装在一个容器中,并给出 text-align: center;
猜你喜欢
相关资源
最近更新 更多
热门标签