【问题标题】:Hide table columns with CSS using adjacent selector from checkbox使用复选框中的相邻选择器隐藏带有 CSS 的表格列
【发布时间】:2018-09-26 18:41:06
【问题描述】:

我想根据复选框隐藏表格中的列。

此处第 2 列应隐藏,因为复选框 "col 2" 未选中。

[v] col 1   [ ] col 2   [v] col3

+-------------------------------+
|       | col 1 | col 2 | col 3 |
| row 1 |  aaa  | bbb   | ccc   |
| row 2 |  ddd  | eee   | fff   |
+-------------------------------+

目前我有一个带有复选框的 div 容器,然后与这个 div 相邻,即表格。

为了让事情更复杂,复选框是“按钮复选框”,类似于:https://stackoverflow.com/a/7642302

<div class="filter_group">
    <div class="check_button">
        <label>
            <input type="checkbox" data-filter-col="d1"><span>col 1</span>
        </label>
    </div>
    <div class="check_button">
        <label>
            <input type="checkbox" data-filter-col="d2"><span>col 2</span>
        </label>
    </div>
    <div class="check_button">
        <label>
            <input type="checkbox" data-filter-col="d3"><span>col 3</span>
        </label>
    </div>
</div>
<table>
    <tr>
        <td> </td>
        <th data-col="d1">col 1</th>
        <th data-col="d2">col 2</th>
        <th data-col="d3">col 3</th>
    </tr>
    <tr>
        <th>row 1</th>
        <td data-col="d1">aaa</td>
        <td data-col="d2">bbb</td>
        <td data-col="d3">ccc</td>
    </tr>
</table>

(此处示例代码中只有一个数据行,实际表有多个。)


根据我在本网站和其他地方的发现,如果我正确理解各种选择器,这是一个渺茫的希望 - 但是否可以使用 descendantchild 组合器generaladjacent combinator 结合使用?方向:

 .filter_group .check_button label input[data-filter-col="d1"]:checked ~
 table td[data-col="d1"] {
     display: none;
 }

如果没有,有没有办法用 CSS 做到这一点而不会使结构过于复杂?

我可以并且正在使用 JavaScript 来解决这个问题,但我试图用 CSS 来解决它。

【问题讨论】:

    标签: html css


    【解决方案1】:

    由于 CSS 选择器(包括 CSS 级别 3 和 4)仅在树中向下(包括后代、孩子和弟弟妹妹),要使此解决方案正常工作,您需要复选框触发器处于同一级别或DOM 的级别高于table

    如果您这样做,您可以将标签设置为按钮的样式,并在关联的复选框处于活动状态时使它们处于激活状态。然后,您可以在复选框中添加display: none;

    但是,要回答您的特定问题,保持复选框不变,您可以将标签附加到顶级复选框,并在标签内添加两个复选框(一个有效,一个无效)。您可以在顶部复选框上附加带有id 的标签,并在label 上使用具有相同值的for 属性。

    <input class="trigger" id="col1" type="checkbox">
    <input class="trigger" id="col2" type="checkbox">
    <input class="trigger" id="col3" type="checkbox">
    
    <div class="filter_group">
        <div class="check_button">
            <label for="col1">
                <input type="checkbox" data-filter-col="d1"><input type="checkbox" data-filter-col="d1" checked><span>col 1</span>
            </label>
        </div>
        <div class="check_button">
            <label for="col2">
                <input type="checkbox" data-filter-col="d2"><input type="checkbox" data-filter-col="d2" checked><span>col 2</span>
            </label>
        </div>
        <div class="check_button">
            <label for="col3">
                <input type="checkbox" data-filter-col="d3"><input type="checkbox" data-filter-col="d3" checked><span>col 3</span>
            </label>
        </div>
    </div>
    <table>
        <tr>
            <td> </td>
            <th data-col="d1">col 1</th>
            <th data-col="d2">col 2</th>
            <th data-col="d3">col 3</th>
        </tr>
        <tr>
            <th>row 1</th>
            <td data-col="d1">aaa</td>
            <td data-col="d2">bbb</td>
            <td data-col="d3">ccc</td>
        </tr>
    </table>
    

    然后,这是启用一切的 CSS:

    .trigger {
      /* display: none; // You would probably use this. */
      opacity: .2; /* This is to show how the wiring works. */
    }
    
    /* Default the inputs to not displaying */
    .filter_group input {
      display: none;
    }
    
    /* Show and hide inline checkboxes */
    #col1:not(:checked) ~ .filter_group label[for=col1] input:not(:checked),
    #col2:not(:checked) ~ .filter_group label[for=col2] input:not(:checked),
    #col3:not(:checked) ~ .filter_group label[for=col3] input:not(:checked){
     display: inline-block; 
    }
    
    #col1:checked ~ .filter_group label[for=col1] input:checked,
    #col2:checked ~ .filter_group label[for=col2] input:checked,
    #col3:checked ~ .filter_group label[for=col3] input:checked{
     display: inline-block; 
    }
    
    /* Do filters */
    #col1:not(:checked) ~ * *[data-col="d1"],
    #col2:not(:checked) ~ * *[data-col="d2"],
    #col3:not(:checked) ~ * *[data-col="d3"] {
      display: none;
    }
    
    /* Avoid clicks on the inactive checkboxes */
    label input {
      pointer-events: none;
    }
    

    下面是实际代码:https://codepen.io/anon/pen/xWveoz

    你提到“有没有办法用 CSS 做到这一点而不会使结构过于复杂?”

    我认为这有点矫枉过正。我认为更简洁的策略是直接设置 label 元素的样式,这会删除两个非语义复选框。但是,如果复杂性适合你,那么这个解决方案应该足够了,只需要 CSS。

    【讨论】:

    • 谢谢伙计。我将复选框移到与表格相同的级别,在标签上使用 for 并删除其他复选框。这很好用。不确定我现在会使用它。但是对于我想到的其他一些表来说,这种可能性肯定是好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    相关资源
    最近更新 更多