V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
geelaw
V2EX  ›  分享创造

[文章分享] CSS 实现 Word 表格“镶边行”的效果

  •  
  •   geelaw ·
    GeeLaw · 2017-05-24 11:50:09 +08:00 · 2324 次点击
    这是一个创建于 2774 天前的主题,其中的信息可能已经有所发展或是发生改变。

    2016 年的事情了,现在写一篇 blog 记录之。之前建立自己的 blog 的时候给自己提出过一个需求:希望实现“镶边行”效果(奇、偶行的背景色不同)。(需求背景请看全文,链接在最末)

    当然这很简单,只要

    table > tbody > tr:nth-child(odd)
    {
        background: rgba(0, 0, 0, 0.02);
    }
    

    即可。但是后来又因为一些原因(欲知详情请查看全文,链接在最末),我希望 当且仅当表格有至少 4 行时 显示为“镶边行”。

    因为无法检测一个 tbody 是否有至少 4 个 tr,我们可以直接检测 tr。我们需要排除的有 :only-child:first-child:nth-last-child(2)( 2 行表格中的第 1 行)、:first-child:nth-last-child(3):last-child:nth-child(3)( 3 行表格中的第 1、3 行)。理想状态下我可以这样:

    table > tbody > tr:nth-child(odd):not(:only-child):not(:first-child:nth-last-child(2)):not(:last-child:nth-last-child(3)):not(:last-child:nth-child(3))
    {
        background: rgba(0, 0, 0, 0.02);
    }
    

    但是 CSS 4 的 :not 才支持选择器列表,CSS 3 的 :not 只支持 简单选择器

    于是可以利用数理逻辑的知识,假设 ABCD 是 4 个选择器,则 :not(AB):not(CD) 等价于

    :not(A):not(C), :not(A):not(D),
    :not(B):not(C), :not(B):not(D)
    

    于是可以把我们理想中的选择器展开为长度为 8 的复杂选择器列表,这件事情可以用一个工具自动化完成。

    这个问题得到了部分的解决:不完美的原因是把一个“理想的”选择器转换为 CSS 3 选择器可能会使得代码长度 指数速度 增长。

    在我写这篇博文的时候,似乎未有见到很多讨论 :not(AB):not(CD) 型选择器 CSS 3 化的问题,比较多的是 :not(.simple1, .simple2) 型选择器 CSS 3 化的问题(等于 :not(.simple1):not(.simple2))。不知道是这件事情太无聊以致于没人写(这肯定是 trivial 啦),还是什么别的原因。


    在我的 blog 上查看完整的故事:Make a table banded if and only if it has at least 4 rows

    直接转到 blog 上的答案位置

    第 1 条附言  ·  2017-05-26 05:56:40 +08:00

    展开版本的代码(现在我的 blog 使用的代码也差不多是这样):

    table > tbody > tr:nth-child(odd):not(:only-child):not(:first-child):not(:first-child):not(:last-child),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:nth-last-child(2)):not(:first-child):not(:last-child),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:first-child):not(:nth-last-child(3)):not(:last-child),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:nth-last-child(2)):not(:nth-last-child(3)):not(:last-child),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:first-child):not(:first-child):not(:nth-child(3)),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:nth-last-child(2)):not(:first-child):not(:nth-child(3)),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:first-child):not(:nth-last-child(3)):not(:nth-child(3)),
    table > tbody > tr:nth-child(odd):not(:only-child):not(:nth-last-child(2)):not(:nth-last-child(3)):not(:nth-child(3))
    { background: rgba(0, 0, 0, 0.02); }
    

    这是一个学院派的、纯粹的做法。

    2 条回复    2017-05-26 07:01:34 +08:00
    geelaw
        1
    geelaw  
    OP
       2017-05-24 12:04:32 +08:00
    这个代码染色器有毒,什么迷之配色……
    geelaw
        2
    geelaw  
    OP
       2017-05-26 07:01:34 +08:00
    wlgq,我刚刚更新了文章,因为我想到了一种更简单的实现。

    要选中的行分成如下几类:

    · 第五行、第七行……
    · 第一行,但不是倒数一、二、三行
    · 第三行,但不是倒数第一行

    于是只要

    ```
    table > tbody > tr:nth-child(2n+5),
    table > tbody > tr:first-child:not(:nth-child(-n+3)),
    table > tbody > tr:nth-child(3):not(:last-child)
    {
    background: color(0,0,0,0.02);
    }
    ```

    即可!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5730 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 06:07 · PVG 14:07 · LAX 22:07 · JFK 01:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.