带有多个 <tbody> 元素的条纹表的纯 CSS3 解决方案?

Posted

技术标签:

【中文标题】带有多个 <tbody> 元素的条纹表的纯 CSS3 解决方案?【英文标题】:Pure CSS3 solution to stripe table with multiple <tbody> elements? 【发布时间】:2011-02-25 19:28:46 【问题描述】:

我有一张包含多个 &lt;tbody&gt; 元素的表格。在给定时间,仅显示一个&lt;tbody&gt;,或显示所有&lt;tbody&gt;

我目前使用此 CSS3 代码对表格进行条带化:

table tr:nth-child(even) 
  background: #efefef;

当显示单个 &lt;tbody&gt; 元素时,一切(显然)都很好,但是当显示多个 &lt;tbody&gt; 元素时,CSS 规则分别适用于每个元素,并且每个 &lt;tbody&gt; 都有自己的“条纹系统” .条纹可能看起来一致,也可能不一致,具体取决于行数。

<tbody>
  <tr> [ODD]
  <tr> [EVEN]
  <tr> [ODD]
</tbody>
<tbody>
  <tr> [ODD]
  <tr> [EVEN]
</tbody>
…

我一定要使用 javascript (... jQuery) 来解决这个问题吗?还是有纯 CSS 的解决方案?

【问题讨论】:

我不知道如何避免使用 jQuery,除非你能够让你的表只有一个 tbody。 给每一行一个“奇数”或“偶数”类。然后使用 CSS 为类着色,而不是表格单元格。 相关:Select nth-child across multiple parents 【参考方案1】:

是的,我认为您需要脚本,因为没有nth-grandchild 选择器可以相对于&lt;table&gt; 起作用。无论如何,您都需要脚本才能使其在较旧的浏览器中运行,所以可能没什么大不了的。

var table= document.getElementById('sometable');
for (var i= table.rows.length; i-->0;)
    table.rows[i].className= i%2===0? 'stripe-even' : 'stripe-odd';

【讨论】:

我忘了说,我不在乎兼容性。我只会支持支持 CSS3 的浏览器。编写脚本,尤其是使用 jQuery,并不是什么大问题。但我真的很想避免它,因为表格是动态的,我必须重新申请很多。【参考方案2】:

如果您使用的是 jQuery,则使用 :even 选择器,(编辑:处理可见性)like this:

$("table tr:visible:even").addClass("even");​

还有这样的课程:

.even  background: #efefef; 

同样,如果您不使用纯 javascript 解决方案(包括 just 的任何库,这是矫枉过正),那 if 您已经在使用 jQuery,例如bobince 已发布。无论哪种方式,我在这里都看不到纯 CSS 解决方案...这绝对是一个有效的案例,但不是经常出现的足以使其符合规范的东西。

【讨论】:

这并不能解决他试图回答的问题。这只是他的问题的 jQuery 版本。 @Scott - 它确实解决了问题,你看过演示吗?当可见性发生变化时,您必须删除并重新应用该类,就像 javascript 解决方案一样...如果您有一个更简单的非 javascript 解决方案,我很乐意看到它,但我不明白这是怎么可能的。 啊,这是正确的,我完全误解了。我正在尝试更改我的投票,但除非进行编辑,否则不允许我投票。 @Scott - 更新 - 根据问题添加了额外的处理或可见性。 啊,太好了,我不会考虑可见性。【参考方案3】:

如果你的行高度都一样,你可以用渐变作弊,例如:

#table 
    background-image: repeating-linear-gradient(pink 0, pink 1.6em, yellow 1.6em, yellow 3.2em);
    background-repeat: no-repeat;

    /* To account for headers; adjust size to account for footers.
     * You can also use a second (or third) gradient for both.
     */
    background-position: 0 1.4em;

如果你能保证所有&lt;tbody&gt; 元素的行数都是偶数,你也可以使用它(即使最后一个被隐藏了),否则,你就不走运了。不过,选择器级别 4 可能有话要说,类似于

#table > !tbody > tr:last-child:nth-child(even)

补课。

Demo!

【讨论】:

该选择器将tbody 与偶数个孩子匹配-我不确定仅选择器就足够了。我正在考虑类似tr:nth-match(even of #table &gt; tbody &gt; tr) 之类的东西,它可能等同于$('#table &gt; tbody &gt; tr:odd'),但选择器4 可能不允许!:nth-match() 中的组合符在CSS 中使用,这意味着你仍然有无论哪种方式都回退到 JS。 (我正在想办法滥用换行和罗马数字样式的 CSS 计数器来为此提供 CSS2 兼容的东西,但到目前为止还没有运气.) @minitech 问题是把计数器变成可以使用模运算符的数字codepen.io/Zeaklous/pen/djtBz @BoltClock nth-match 不起作用,我检查过。看我的回答。 聪明和赞成,但给予“不可能”的答案赏金。【参考方案4】:

经过深入研究,我可以声明

没有纯 CSS3(甚至不是 CSS4)解决方案来匹配多个父项的偶数/奇数行。

你能想到的所有解决方案都是不可能的:

    使用:nth-child pseudo-class。

    结论:这仅适用于单亲。

    以某种方式涉及具有奇数行的tbody 标签(颜色切换器),方法是计算它们的子元素并以类似nth-child(odd) 的工作方式区分具有奇数行的标签。

    结论:在 CSS 中无法计算子级,请参阅 this question。当心令人困惑的公认答案 - 这实际上是计算兄弟姐妹,而不是孩子

    尝试根据一些儿童 CSS 规则只匹配一些tbodys,从而能够识别具有奇数个儿童的tbodys。

    结论:在 CSS 中不可能根据子元素匹配元素:

    Apply CSS styles to an element depending on its child elements Complex CSS selector for parent of active child Is there a CSS parent selector? Select element based on child class

    CSS4 引入了一个新的选择器:nth-match,这听起来很有希望,因为它不包含“child”这个词。所以你会想知道这是否可行:

:nth-match(even of tr)  background-color: #ccc; 
:nth-match(odd of tr)  background-color: #fff; 

结论:它不起作用。如果您查看描述,您会发现它会做与您观察到的完全相同的事情:

:nth-match(An+B of &lt;selector&gt;)pseudo-class 表示法表示一个 具有与给定选择器列表匹配的 An+B-1 siblings 的元素 在文档树之前。

有问题的是 siblings 这个词,这意味着它只会计算 within 每个 tbody 标记,就像 :nth-child 选择器所做的那样。

结论

没有纯 CSS(既不是 CSS3 也不是 CSS4)解决方案。您必须避免:

javascript,例如Nick Craver 提到的很棒的 jQuery 解决方案; minitech 的后台技巧,但它的使用仅限于等高行; html 生成代码的变化。

【讨论】:

【参考方案5】:

如果使用 JQuery,则使用此代码:

//style for even CSS Class
<style>.even  background: #efefef;  </style>

将类添加到每隔一行的表格以进行样式设置

 <script>
   $('tbody').parents('.table-container').find('tr:even').addClass( 'even' );
 </script>

HTML 代码

<div class="table-container">
    <table>
        <tbody>
          <tr> [ODD]
          <tr> [EVEN]
          <tr> [ODD]
        </tbody>
        <tbody>
          <tr> [ODD]
          <tr> [EVEN]
        </tbody>
    </table>
</div>

【讨论】:

【参考方案6】:

目前在任何浏览器中都无法使用的解决方案(据我所知)是使用计数器(在 tr 上),然后使用 w3c 计数器样式级别 3 中的计数器:

w3c doc

3.1.1。循环符号:“循环”系统

“循环”计数器系统通过其提供的重复循环 符号,当它到达末尾时循环回到开头 列表。它可以用于简单的子弹(只需提供一个计数器 符号),或用于循环通过多个符号。第一个柜台 符号用作值1的表示,第二个 计数器符号(如果存在)用作 值 2 等。

如果系统是“循环”的,“符号”描述符必须包含 至少一个计数器符号,否则“@counter-style”规则是 无效的。该系统是针对所有计数器值定义的。

“三角形子弹”计数器样式可以定义为:

@counter-style 三角形 系统:循环;符号:‣;后缀: '';

然后它将生成如下所示的列表:

‣ 一 ‣ 二 ‣ 三 如果有 N 个计数器符号和一个 正在为整数值构造表示, 表示是索引 ((value-1) mod N) 处的计数器符号 计数器符号列表(从 0 开始)。

如果我用 2 个符号设置此规则,一个是实心方块,另一个是空方块,我会得到一个在颜色和透明度之间交替的伪元素。

然后我可以强制这个伪元素扩展到所有的tr。

【讨论】:

“那我可以强制这个伪元素扩展到所有的tr。”如何? 我想transform: scale(something big);overflow: hidden; 可能会成功…… 提供一个简单的示例代码这将如何适用于表格将使这个答案更加有用:)

以上是关于带有多个 <tbody> 元素的条纹表的纯 CSS3 解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

如果使用了多个 tbody 标签,html 表是不是有效? [复制]

Bootstrap 表条纹:如何更改条纹背景颜色?

无法将嵌套的表输入元素放入jQuery数组中

覆盖引导表条带化 CSS

vue中将多个元素包装成一个非情感元素标签

js添加表格