【问题标题】:Consistent HTML table dimensions一致的 HTML 表格尺寸
【发布时间】:2014-07-13 21:18:11
【问题描述】:

我经常发现自己想要一个包含两个(或多个)连续表格的 HTML 文档,我希望它们的格式相同:每列具有相同的列宽。例如

<table>
  <thead><tr><th>Name</th><th>Identifier</th></tr></thead>
  <tbody><tr><td>John Smith</td><td>A-64</td></tr></tbody>
</table>
<p>Some text &hellip;</p>
<table>
  <thead><tr><th>Name</th><th>Id.</th></tr></thead>
  <tbody><tr><td>Xavier Ephraim Bloggs III</td><td>A-434-bcf</td></tr></tbody>
</table>

事实上,浏览器将呈现第二个表格的列比第一个更宽,这仅仅是因为每个单元格的内容更宽。

可以通过对每列的宽度进行硬编码来解决这个问题,或者使用 HTML width 属性,或者(更好)使用 CSS。但我不想这样做,因为我不知道每列的宽度。正确的宽度取决于用户代理选择的字体、用户屏幕的宽度以及每个单元格的内容(它本身是由用户输入生成的)。无论如何,UA在决定布局方面比我好得多。

我真正想要的是某种方式来布置第二张桌子,就好像它是第一张桌子的延续一样。我可以做到这一点,实际上让它们成为一个表格,中间的段落只是另一行(有足够的 CSS 让它看起来不那么),但这看起来很糟糕,邪恶和错误。

<table>
  <tr><th>Name</th><th>Id.</th></tr>
  <tr><td>John Smith</td><td>A-64</td></tr>
  <tr colspan="2"><p>Some text &hellip;</p></tr>
  <tr><th>Name</th><th>Id.</th></tr>
  <tr><td>Xavier Ephraim Bloggs III</td><td>A-434-bcf</td></tr>
</table>

从逻辑上讲,它是一张表格,但我想分几个部分进行渲染,否则它会过长。这表明对表格进行编码的逻辑方法是使用两个单独的&lt;tbody&gt;s:

<table>
  <thead><tr><th>Name</th><th>Identifier</th></tr></thead>
  <tbody><tr><td>John Smith</td><td>A-64</td></tr></tbody>
  <tbody><tr><td>Xavier Ephraim Bloggs III</td><td>A-434-bcf</td></tr></tbody>
</table>
<p>Some text &hellip;</p>

我可以使用某种 CSS / HTML5 技巧将第二个 &lt;tbody&gt;(及其标题的副本)移动到段落之后吗?

【问题讨论】:

  • 如果没有 JavaScript,这似乎不太可能实现。
  • 你可能是对的,@DavidThomas。但即使是 JavaScript 解决方案也不错。我的尝试在没有 JavaScript 的浏览器中性能下降得非常厉害。
  • 您能否发布一个实时的JS Fiddle 或类似的演示,以便我们了解您正在使用什么,以及它是如何失败的(对失败的清晰描述,以及失败的标准)成功的修正也会非常、非常有帮助)。
  • +1 表示厌恶“看起来很糟糕、邪恶和错误的事情”。我带着同样的问题和同样的厌恶来到这里。

标签: css html html-table


【解决方案1】:

最后我得出结论,CSS/HTML 解决方案是不可能的,但使用 JQuery 可以相对简单地完成。

$( "table.splittable" ).each( function() {
    $(this).find("tr").first().children().each( function() {
        this.setAttribute('width', this.offsetWidth);
    } );

    var hdrs = $(this).find("tr.move-header");
    $(this).find("tr").each( function() {
        var tr = this;
        $( this.className.split(/\s+/) ).each( function() {
            var match = this.match(/^move-to-(.*)$/);
            if (match) { 
                var dest = $('#'+match[1]).get(0);
                if (dest.childNodes.length == 0) {
                    var thead = document.createElement("thead");
                    dest.appendChild(thead);
                    hdrs.each( function() { 
                        thead.appendChild(this.cloneNode(true)); 
                    } );
                    dest.appendChild(document.createElement("tfoot"));
                    dest = dest.appendChild(document.createElement("tbody"));
                }
                else dest = $(dest).find("tbody").get(0);
                dest.appendChild(tr);
            }
        } );
    } );
});

此脚本查看每个带有splittable 类的表,等待浏览器呈现它们,然后添加一个width 属性,将列宽固定为浏览器认为的最佳值。然后,它查找类为move-to-<em>something</em> 的每一行,并将其移动到ID 为<em>something</em> 的表中。如果目标表没有 &lt;thead&gt; 元素,则会将源表中具有 move-header 类的所有行复制到那里。

结果是我需要将内容放在一个表格中,并在我希望后面的行移动的地方放置一个空的占位符表格:

<table class="splittable" id="table1">
  <thead><tr class="move-header"><th>Name</th><th>Identifier</th></tr></thead>
  <tbody>
    <tr class="move-to-table1"><td>John Smith</td><td>A-64</td></tr>
    <tr class="move-to-table2"><td>Xavier Ephraim Bloggs III</td><td>A-434-bcf</td></tr>
  </tbody>
</table>

<p>Some text &hellip;</p>

<table class="table2"></table>

一旦 JavaScript 运行,第二个表就会得到一个表头的副本,最后一行被移到那里。两个表的列宽相同。

这是一个有点丑陋的解决方案,并且在没有 JavaScript 的情况下不会很好地降级。但这是我想出的最好的。

【讨论】:

    【解决方案2】:

    如何将所有内容包装在父容器中,并使用它来指定整体宽度(其本身可以由其父容器或某种设备/屏幕尺寸规则确定)。

    然后您可以将列宽设置为相对百分比(2 列为 50%,4 列为 25% 等)

    table { width: 100%; }
    td { width: 50%; }
    

    请看这个小提琴的例子:http://jsfiddle.net/5q8Zc/

    我也不一定同意“逻辑上它是一个表” - 如果两者都需要一个标题并且中间有不同的内容,这对我来说听起来像是 2,但如果不看完整页就很难判断。

    【讨论】:

    • 这正是我想要避免的。您已经手动指定了每列的宽度,并且在小提琴示例中(至少在我的浏览器中),结果比留给浏览器的结果更差。第一列太窄,而第二​​列太宽。
    • 那么你正试图施加太多的约束,以使这可能只用 HTML/CSS 来完成。您正在尝试使某些列缩放以适应其文本内容,而其他列应缩放以匹配不同表中列的大小。如果用户决定增加或减少他们的文本大小会发生什么?您的桌子宽度将无处不在。在我给出的示例中,我没有按照您的建议手动指定每列的宽度。我设置了一个相对值,该值将由其父级的大小决定。
    • 在纯 HTML/CSS 中不可能实现这一点您可能是对的,但在其他 cmets 中您错了。我不希望某些列做一件事而其他列做另一件事:我希望所有列的布局就像它们是单个表的一部分一样。这是一个相当简单的概念,HTML 渲染引擎可以清楚地做到这一点,因为它们可以渲染单个长表。而且,是的,您通过说 50% 来明确指定列宽。当然它是相对于包含框的,而不是绝对的。但它仍然被指定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多