为啥 Bootstrap 网格布局优于 HTML 表格?
Posted
技术标签:
【中文标题】为啥 Bootstrap 网格布局优于 HTML 表格?【英文标题】:Why is the Bootstrap grid layout preferable to an HTML table?为什么 Bootstrap 网格布局优于 HTML 表格? 【发布时间】:2013-01-05 20:00:33 【问题描述】:[注意:对于那些可能将此问题与“为什么不使用表格进行 html 布局”混淆的人,我不是在问这个问题。我要问的问题是,为什么网格布局与表格布局根本不同。]
我正在为一个项目研究 CSS 库(尤其是 Bootstrap)。我是一名程序员而不是网页设计师,我觉得我可以从封装好的设计的库中受益。
我们都知道使用 HTML 表格来完成基本的网站布局是一种不好的做法,因为它将演示与内容混合在一起。像 Bootstrap 这样的 CSS 库提供的好处之一是它们提供了在不使用表格的情况下创建“网格”布局的能力。但是,我在理解它们的网格布局与等效表格布局有何不同之处时遇到了一些麻烦。
换句话说,这两个 HTML 示例之间的根本区别是什么?我认为网格布局只是一个具有另一个名称的表格,我错了吗?
<div class="row">
<div class="span16"></div>
</div>
<div class="row">
<div class="span4"></div>
<div class="span4"></div>
<div class="span4"></div>
<div class="span4"></div>
</div>
和
<table>
<tr>
<td colspan=4></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
【问题讨论】:
Why not use tables for layout in HTML? 的可能重复项 @Quentin and close-voters:这不是骗子。 这个问题不是关于为什么不使用表格,而是询问 HTML 表格和 CSS 表格之间的区别正如 Bootstrap &co 所做的那样,在实践中归结为标记和功能的差异很小。 @Quentin:这绝对是不是该问题的副本(我已阅读)。我不是在问为什么不应该使用表格。我在问 Bootstrap 和其他库中的网格布局是否以及为什么与表格布局有根本的不同——也就是说,为什么“行”和“跨度”类比行和单元格 elements 和 colspan 属性。 想一想,我们正走在启蒙之路上……还记得csszengarden.com 吗?除了原来 css 更像是组装地狱而不是 python 天堂 “为什么 Bootstrap 网格布局比 HTML 表格更可取?”——它不是,因为那只是糟糕的 DIV 汤。恕我直言,Bootstrap 主要迎合那些一开始就不知道如何编写语义 HTML 的人。 【参考方案1】:不同之处在于第一个示例是语义上标记的,假设被标记的数据实际上不是表格的。 <table>
应仅用于表格数据,而不应用于恰好以类似于表格的布局显示的任何数据。
虽然使用像 Bootstrap 这样的 CSS 包是正确的,它要求您将类分配给 非 语义但呈现的 HTML 元素,这减少了内容和呈现的分离,使得差异有点没有实际意义.您应该为元素分配语义上有意义的类,并使用lesscss mixins(或类似技术)将CSS框架中定义的表现行为分配给这些类,而不是直接将表现类分配给元素。
说:
<div class="products">
<div class="product"></div>
</div>
.products
.row;
.products > .product
.span16;
注意我说的是应该。在实践中,这不一定总是更可行的选择,但它应该是理论上的目标。
【讨论】:
我有点不同意。在现实世界中,绝对分离是不现实的。这只是一个很好的指南,可以尽可能地分离样式和内容。您当然不需要预处理器来实现这一点。 @Jezen 我完全同意,实际上这不是 100% 可以实现的目标。即使只是在理论上,这也不应该分散关于什么是好什么是坏的事实。至少知道你选择的邪恶以及为什么。 :) 为什么网格布局中使用的row
和span*
类的表现力不如表格示例中的<tr>
和<td>
元素?
@Larry 它们的表现力也不少,它们纯粹是表现性的并且不是语义性的。 <table>
具有语义。使用<table>
标记的数据可以解析为其他表格格式,比如(上帝保佑)Excel 工作表。 <div>
元素虽然没有特定的含义。 <div class="row">
仅代表<div class="flargleborg">
。意义和表现的分离。
嗯。我想我不同意。您可以定义row
的抽象概念,使其不暗示对象的物理表示。但这显然不是这种网格布局的作用。我读过的关于网格布局的教程总是从显示网格看起来像合同的具体图片开始,或多或少地展示了您的网格标记内容将如何出现。它不像flargleborg
,而更像flargleborg-red
。我错了吗?【参考方案2】:
基本上 DIV 是 DIV 而表格元素只是表格元素。表的问题通常只是跟踪所有列和行,因为它最终是一个严格的数据结构。 DIV 更加灵活和宽容。
例如,如果您想获取类等于“span4”的四个 DIV,并将它们更改为 2 列宽,您需要做的就是为外部类调整一点 CSS “行”,也许是“span4”类。事实上,在执行这样的 DIV 时,我会避免将单个 DIV 称为“span4”或其他数字。
我的方法是创建一个名为“rowspan”的父包装 DIV,内部 DIV 将具有一些通用 ID,例如“cell”。
<div class="rowspan">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
例如,每个“单元格”类的宽度可以是 100 像素,然后父“行跨度”可以是 400 像素。这相当于连续 4 列。想让它变成 2 列吗?没问题!只需将“rowspan”更改为 200 像素宽。此时,一切都在 CSS 中,因此无需在 DOM 中重新调整页面结构即可轻松完成。
但是桌子呢?不容易。您基本上必须使用 </tr><tr>
标签重新渲染表格才能创建新行。
【讨论】:
再一次,我无法理解您的示例在理论上与包含四个<td>
s 的 <tr>
元素有何不同。你甚至可以使用类名“cell”。在我看来,您已将演示文稿(连续四个单元格)编码到 HTML 中。
<tr>
是一个 DOM 级别的元素。 CSS 位于 DOM 之外。通过使用具有良好 CSS 分类的 <div>
元素,您可以获得更大的灵活性并且不必通过添加 <tr>
元素来更改 DOM。这意味着您可以创建(例如)一个 php 脚本,该脚本可以简单地使用特定的 CSS 类生成 <div>
元素,而不必进行疯狂的计算来创建 <table>
元素。
或者另一种理解它的方式,删除任何 CSS 逻辑和类,<tr>
只是一个<table>
行,永远不会——也永远不会——成为其他任何东西。但是<div>
更灵活,可以允许在视觉上与<table>
相同但有更多选项的布局,而无需拆开和重新设计<table>
的DOM 结构。
如果你看一下我引用的网格布局(我从一个赞美 Bootstrap 优点的教程中复制的),在我看来,当使用 960 网格时,布局的所有计算都是必需的由设计人员完成并硬编码到 HTML 中。网格的全部目的是保证您将在“这个”位置有单元格 X,在“那个”位置有单元格 Y,并且您将无法灵活地通过更改 CSS 来制作两种截然不同的演示文稿。跨度>
我理解您的论点,即<div>
提供了更大的灵活性来使用 CSS 更改演示文稿,以及为什么这很有价值。我的问题从来不是关于将表示与意义分开的好处。但是,网格布局系统似乎通过将行和列结构硬编码到 HTML 中来收回这种灵活性,我的问题是——我错了,这就是网格布局正在做的事情吗?【参考方案3】:
如果您只使用表格,我认为您将错过为移动设备/平板电脑重新调整文档大小的很多灵活性,而无需为每个设备制作单独的页面。一旦定义了表格结构,您真正可以做的就是放大和缩小。
【讨论】:
【参考方案4】:我使用 Bootstrap 网格进行页面布局,表格用于表格数据。
我认为 Bootstrap 中的网格,不是开发人员意义上的网格,如 gridview 控件,而是设计页面布局意义上的网格 - 包含页面内容的网格。尽管 Bootstrap 网格也可用于创建包含表格数据的常规网格,正如 deceze 指出的那样,这种网格更适合 HTML 表格 - 在这种情况下仍然可以使用。
【讨论】:
【参考方案5】:根本区别在于,您可以使用 Bootstrap 为不同的显示尺寸“重排”布局,只需使用媒体查询,而无需更改标记。例如,我可以决定在台式机上,我希望您的 4 个 div 位于同一行,因为用户具有高分辨率宽显示屏,但在手机上,我希望在一行上进行 2 次潜水,在下一行进行下一个 div。因此,通过这种方式,我可以使用媒体查询来调整每行中的列数。如果您使用硬编码的 HTML 表格,则很难做到这一点。
话虽如此,我不太喜欢 bootstrap 实现,原因如下:
-
它有以像素为单位硬编码的断点。这意味着,随着手机和桌子在显示分辨率方面的进步,您的网站可能会开始在这些设备上显示意想不到的布局。像素数不能很好地代表显示 size。
它将最大使用的显示区域限制为 1170 像素,这对于拥有漂亮宽显示器的用户来说又是一个遗憾,他们实际上可以使用它们来查看应用程序中的更多内容。
Bootstrap 的布局与源无关,也就是说,您无法更改 HTML 中设置的列顺序。然而,这更像是一个迂腐的观点。
默认布局适用于非常小的分辨率,只有当媒体查询触发时才会触发更高分辨率的布局,考虑到手机将继续具有更好的分辨率,并且迟早您的网站将默认布局设置为过时,IMO 是一个糟糕的选择移动设备。
引导布局并不是真正的“无忧无虑”,因为您必须阅读它们的细则才能看到他们认为不值得支持但您可能关心的所有错误和浏览器关于。例如,如果您针对的是韩国或中国的用户,您会感到惊讶。
因此,在引导程序中,并非所有东西都是黄金,而且他们的方法不一定总是最好的(顺便说一句,我在引导程序中鄙视的另一件事是他们对所谓的“jumbotrones”的痴迷——那些浪费不便的房地产—— your-face headers - 我希望社区不要开始将其视为“新标准”)。就我个人而言,这些天我使用 CSS 表格布局 (display:table
),它具有与引导程序类似的好处,而无需在我的标记中硬编码 <table>
。例如,我仍然可以使用媒体查询根据纵向或横向重新排列行。然而,最重要的好处是我的布局是真正的像素甚至百分比独立。例如,在 3 列布局中,我让内容决定第一列和最后一列应该占用多少空间。没有像素甚至百分比宽度。中心栏占据了所有剩余空间(这对我的应用程序来说是件好事,但对其他人来说可能不是)。此外,我在媒体查询断点中使用了 ems,而 bootstrap 出人意料地没有。
【讨论】:
“回流”点很好,在任何其他答案中都没有提到。回流概念的新词是“响应式”。【参考方案6】:我认为CBroe comment是最好的选择,所以我选择澄清它。
避免使用div
。 div
应该是您最后的选择,而不是您的首选。相反,请尝试在实际元素上使用 Bootstrap 类。例如:
<form class="container">
<fieldset class="row">
<label class="span4" for"search">Type your search</label>
<input class="span6" type="text" id="search" />
</fieldset>
</form>
使用 fieldset 包含单个字段是一种耻辱,但它在语义上比使用 div
来做同样的事情更好。 HTML5标准定义了很多新的容器元素,如article
、section
、header
、footer
and many more。在某些情况下,您将不得不使用div
,但如果您尽量减少它的使用,那么您的代码将更加语义化。
【讨论】:
这个答案是我第一次理解这种模式。当人们只是用 div 替换每个 html 元素然后在 css 和 javascript 中进行所有布局时,这似乎是对整个 HTML 规范的巨大浪费。但是使用这些模式来增强现有的 html 并减少额外标签的数量确实很有意义。 在<form>
标签上使用.container
是否正确?我认为.container
是最外层的包含元素(主要是<div>
),如果你想要一个水平表单,你只能应用.form-horizontal
,否则不要在表单上附加任何类(BS3 已经稍微控制它了)。然后有.row
-> .col-XX-yy
-> .form-group
-> .label-control
用于<label >
和.form-control
用于非复选框元素。请参阅文档:getbootstrap.com/docs/3.3/css/#forms【参考方案7】:
虽然两组标记之间的语义差异不一定很大(因为 Bootstrap 的网格系统使用的类确实是纯粹的表现形式),但一个非常重要的区别是网格系统更多灵活。
例如,让基于表格的布局响应不同的屏幕尺寸是非常困难的。没有办法告诉浏览器在同一行中显示一个td
元素下面另一个td
。而对于div
示例,这很容易做到,并且当类在定义相对比例和位置的意义上是“呈现”时,可以以不同的方式呈现相同的标记甚至页面上的元素。
【讨论】:
【参考方案8】:如果可以的话,我想总结一下我从其他 cmet 中收集到的内容以及我在此页面中经历的链接爆炸:
使用表格的问题不在于网格布局,而是试图用 HTML 而不是 CSS 来表达它。
Bootstrap 允许通过(大部分)纯 CSS 进行网格布局,这就是它可以使用的原因。 '大部分'的部分是因为你的 HTML 仍然会被你的布局数据污染,但更微妙的是:
<nav class="span4"> ... </nav>
<article class="span8"> ... </article>
这肯定比旧的表格设计更具语义性和可维护性,但“span4”和“span8”仍然是嵌入到我们 HTML 中的显示数据。但是,由于设计永远无法真正与我们的数据(例如嵌套 div)分离,因此这是一个合理的代价。
话虽如此,如果您使用由预处理语言(例如LESS)提供的一些更现代的 CSS 功能,即使这种耦合也可能被打破。同样的例子:
<nav id="secondary-nav"> ... </nav>
<article id="main-content"> ... </article>
加上下面的LESS:
#secondary-nav
.span4;
// More styling (padding, etc) if needed
#main-content
.span8;
这将创建完全解耦的 HTML 和样式表,这是理想的,因为 HTML 更干净且更具可读性,并且可以通过更少的 HTML 修改来进行重新设计。但是,这仅在您使用 LESS 或其他一些 CSS 预处理器时才有效,因为 CSS 目前不支持 mixins (AFAIK)。
我们已经在我的工作场所使用 LESS,所以我知道我会努力使用这种类型的解决方案。我非常相信语义 HTML 和数据设计解耦。 :)
【讨论】:
【参考方案9】:带有 table、tr、td 的版本取决于浏览器算法 - 换行、动态宽度、边距、居中等。 带有 div 的版本可以更容易地通过 css 和脚本进行调整。
【讨论】:
以上是关于为啥 Bootstrap 网格布局优于 HTML 表格?的主要内容,如果未能解决你的问题,请参考以下文章
从 Bootstrap 3 迁移的 Bootstrap 4 网格布局问题