使用无表格的CSS相对布局(CSS RelativeLayout)实现类似表格的对齐方式?

23
无论我在互联网上走到哪里,都不断有人敲打我不应该使用表格。可悲的是,我是为数不多还在使用表格的程序员之一——老实说,我认为CSS的对齐和布局功能不足强大,无法让我戒掉使用表格的习惯。抛开个人偏好,我想尝试解决我对CSS系统的一个主要不满:
假设我想要这样的布局:
+---+---+
| A | B |
+---+---+
| C | D |
+---+---+
在上面的示例中,我希望A和C的宽度相同,BD的宽度保持不变。
我还希望AB的高度保持一致,C和D的高度也相同。
换句话说,如果列中的任何元素变宽了,我希望该列中的所有元素都变宽。如果行中的任何元素变高了,我也希望该行中的所有元素变宽。
我刚才描述的正是我们的老朋友表格的确切功能。我认为,表格非常适合这种布局!如果我尝试使用CSS布局做类似的事情,可能会得到如下结果:
+-------+---+
|   A   | B |
+---*---*---+
| C |   D   |
+---+-------+

这绝对不是我要找的布局类型(AC构成了崎岖的列,而不是我想要的完美平滑的列)。

简单来说,我真的需要一种使用CSS布局(而不是预定义的宽度或高度),将一个CSS框的边缘位置与另一个CSS框的边缘位置对齐的方法。如果CSS支持这个简单的功能,我可以立刻放弃表格,并创建超越表格能力的布局!这种功能的一个好但无用的例子是,在表格的两侧有两个不相连的框,动态地共享着完全相同的高度和垂直位置。

但不幸的是,在我的互联网搜索中,到目前为止我发现的最高级别的对齐方式是居中、左对齐和右对齐。所有这些对齐类型都不相对于其他元素,使它们没有任何用处。

我只是想找到一种不必使用表格就能将HTML元素对齐到其他HTML元素的方法!

编辑

在选择此问题的标签时,我遇到了一个几乎概括了所有内容的描述:

RelativeLayout:一种布局,其中子项的位置可以相对于彼此或父项进行描述。

有CSS RelativeLayout吗?还是每当我想要这样做时就必须使用表格?

我将接受最接近我所需功能的答案,而不使用预定宽度或高度(如果没有其他人提供更好的答案,则包括答案“不存在这样的东西”)。


3
人们常常误解:这正是需要使用表格的情况,应该使用表格来实现。用纯 CSS 模仿表格的行为没有意义。为了页面布局目的,应该避免在许多情况下使用表格,但并非总是如此。 - arkascha
如果你真的想要一个表格,那么表格就是答案。然而,问题是为什么你绝对需要这种行为?这意味着有些情况下人们认为他们需要一个表格,但实际上,一个响应式的CSS解决方案可能会更好甚至更好。 - mb14
相关问题:表单是否可以不使用表格来完成? - Ciro Santilli OurBigBook.com
2个回答

9
使用CSS可以将非语义表格元素展示为表格。通过使用display属性,可以在标记中使用div时模拟表格。具体请参考这篇文章
根据您的需求,还有其他替代方案。如果您只希望每个列中的两行固定在列的宽度上,请尝试将行放置在列标记内而不是相反。这可以在没有预定义维度的情况下工作。
此外,如果每一行中的单元格高度相同,则可以将它们简单地向左浮动,并将容器宽度设置为行宽之和。这仅适用于预定义维度。
CSS
div.c
{
    width: 100%;
}

div.c>div:nth-child(2n-1)
{
    width: 25%;
    float: left;
    background: blue;
}

div.c>div:nth-child(2n)
{
    width: 75%;
    float: left;
    background: yellow;
}

这里有一个演示: http://jsfiddle.net/kdani3/DbRuV/ 更复杂的例子: http://jsfiddle.net/kdani3/DbRuV/1/ 我认为这很简单,甚至比使用表格布局还要简单。
此外,我强烈推荐您查看CSS网格框架,如Twitter Bootstrap。那绝对值得一看。

表格的一个好处是不必指定宽度,因为OP说如果需要(而无需指定宽度),列会增加其大小(在每一行上)。您的示例没有提供这个基本的表格功能。 - mb14
你好!你的回答很聪明,在某些情况下,我确实可以将列作为父级,而不是行。然而,在某些情况下,我需要两者对齐。可惜,这样的解决方案行不通 :( 使用预定宽度也不是一个选项。使用Twitter Bootstrap很有趣,尽管我想知道是否有比被限制在12个预定列更强大的东西。虽然如此,我还是给你点赞,因为它很有启发性。 - Georges Oates Larsen
display 属性怎么样?请查看我在答案中提到的文章。我认为使用 display 属性是解决您问题的好方法。 - kdani
非常棒 - 我会接受你的答案!如果你加粗一个注释,说明这个答案是为了display:table, bit而被接受的,那对于其他也在想同样问题的人来说会非常有帮助。 - Georges Oates Larsen
这是一个好的解决方案,但遗憾的是:"inline-table"、"table"等值在IE7及更早版本中不被支持。IE8需要!DOCTYPE声明。IE9支持这些值。 - silversky
显示剩余3条评论

4

我认为如果要使用纯CSS,不使用Widthtable,你可以使用Flex布局

这是代码

HTML

<section class="flexrow">
    <div class='item'>1asdf</div>
    <div class='item'>2</div>
</section>
<section class="flexrow">
    <div class='item'>1</div>
    <div class='item'>2</div>
</section>

CSS

.flexrow {
    display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flex;
    display: -o-flex;
    -webkit-justify-content: space-between;
    -moz-justify-content: space-between;
    -ms-justify-content: space-between;
    -o-justify-content: space-between;
    margin-bottom: 10px;
    -webkit-align-items: center;
    -moz-align-items: center;
    -ms-align-items: center;
    -o-align-items: center;
    -webkit-flex: none;
    -moz-flex: none;
    -ms-flex: none;
    -o-flex: none;
}
.item {
    -webkit-flex: 1;
    -moz-flex: 1;
    -ms-flex: 1;
    -o-flex: 1;
    margin: auto 10px;
    border-radius: 5px;
    border:1px solid black;
}

这里是 JsFiddle


你的回答听起来很有希望!我尝试在Firefox的夜间版本中查看了您的示例,但它没有起作用(flex行似乎只是直接堆叠在一起的列)。即使将您示例中的div-flexrow更改为section-flexrow,它仍然无法正常工作。您能告诉我您使用的浏览器吗?这样我就可以亲自查看示例了。谢谢! - Georges Oates Larsen
我正在使用 Google Chrome,我已经在 jsfiddle 上发布了我的示例,链接在上面。 - Sieryuu
啊!在Chrome中运行您的示例现在已经可以了。不幸的是,我对其进行了修改(添加了更多的f,并在最后五个f之前添加了一个<br/>标签)。它不能保持与同一列/行中的兄弟元素相同的列大小(或行大小)。虽然这是一种有趣的布局策略,但如果它不能动态地保持对齐,我不确定它是否能像表格一样起到同样的作用。我的问题在这里得到了证明:http://i.imgur.com/Jf5T6j3.png - Georges Oates Larsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接