一致的HTML表格维度

时间:2014-05-24 16:43:44

标签: css html5 html-table

我经常发现自己想要一个带有两个(或更多)连续表格的HTML文档,我希望它们的格式相同:每列的列宽相同。 E.g。

<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>

逻辑上它是一个表,但是我希望在几个部分中进行渲染,因为它会过长。这表明编码表的逻辑方式是使用两个单独的<tbody> 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技巧将第二个<tbody>(及其标题的副本)移到段落之后吗?

2 个答案:

答案 0 :(得分: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-something类的每一行,并将其移动到具有something的id的表中。如果目标表没有<thead>元素,那么源表中包含类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的情况下也不会很好地降级。但它是我提出的最好的。

答案 1 :(得分:0)

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

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

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

请参阅此小提琴以获取示例:http://jsfiddle.net/5q8Zc/

我也不一定同意&#39;逻辑上它是一张桌子&#39; - 如果两者都需要一个标题,并且两者之间有明显的内容,那对我来说听起来就像2,但如果没有看到整页,很难判断。