Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change checked html table row with CSS

I am trying to change the style of input elements in a single when check box in said row is checked. I have tried many combinations of "~", "+", with and without class identifiers, to no avail. I know how to use Javascript to create a workaround, and I know CSS does not allow for ancestor selection for many good reasons, but I was wondering if you can use CSS in any manner to accomplish this task.

tr td input {
  font-size: 20px;
  font-family: helvetica;
  padding: 5px;
}

tr td input[type=checkbox]:checked+tr td input.input-item {
  color: red;
  font-style: italic;
  text-decoration: line-through;
}
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8;charset=utf-8">
  <title>Title</title>
</head>

<body>
  <table>
    <thead>
      <tr>
        <th><input type="checkbox" name="checklist-list" class="checkbox-box"></th>
        <th>Item1</th>
        <th>Item2</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="checkbox-td"><input type="checkbox" name="checklist-list" class="checkbox-box"></td>
        <td class="item-td"><input class="input-item" type="text" value="Artificial"></td>
        <td class="item-td"><input class="input-item" type="text" value="Amateurs"></td>
      </tr>
      <tr>
        <td class="checkbox-td"><input type="checkbox" name="checklist-list" class="checkbox-box"></td>
        <td class="item-td"><input class="input-item" type="text" value="Broken"></td>
        <td class="item-td"><input class="input-item" type="text" value="Barriers"></td>
      </tr>
      <tr>
        <td class="checkbox-td"><input type="checkbox" name="checklist-list" class="checkbox-box"></td>
        <td class="item-td"><input class="input-item" type="text" value="Casual"></td>
        <td class="item-td"><input class="input-item" type="text" value="Create"></td>
      </tr>
    </tbody>
    <tfoot>
    </tfoot>
  </table>
</body>
like image 955
idionym Avatar asked Oct 25 '25 00:10

idionym


2 Answers

Unfortunately, existing CSS combinators allow only selecting elements within one common parent element and later in the source order. There is currently no way to select an ancestor or a previous sibling of the element. So it's not possible to style the container (e.g. tr) based on the state of the content (e.g. input). It's possible to change the next inputs based on the state of the previous one (as shown in Ivan's answer), but only if they are in the same container, which makes it impossible to format them as different table cells (it can be done so with CSS Grid layout, though, but it would require even flatter markup structure since all grid items have to be children of one grid container).

There is one terribly hacky workaround for this based on the fact that <label> element can transfer the click to the linked <input> regardless its position in the source code. We can make actual checkboxes invisible, place them before the table, and then style any part of the table we need using following siblings and descendants combinators, and make labels look as if they were checkboxes. A quick demo/proof of concept:

tr td input {
  font-size: 20px;
  font-family: helvetica;
  padding: 5px;
}

[type="checkbox"] {
  position: absolute;
  clip: rect(0 0 0 0);
  width: 0;
  height: 0;
  overflow: hidden;
}

.fake-checkbox {
  display: inline-flex;
  width: .8em;
  height: .8em;
  border: 2px inset #ccc;
  justify-content: center;
  align-content: center;
  vertical-align: middle;
}

#checkbox0:checked ~ table [for="checkbox0"]::before,
#checkbox1:checked ~ table [for="checkbox1"]::before,
#checkbox2:checked ~ table [for="checkbox2"]::before {
  content: '✔';
  line-height: 1;
}

#checkbox0:checked ~ table #checkbox0-tr td input.input-item,
#checkbox1:checked ~ table #checkbox1-tr td input.input-item,
#checkbox2:checked ~ table #checkbox2-tr td input.input-item {
  color: red;
  font-style: italic;
  text-decoration: line-through;
}
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8;charset=utf-8">
  <title>Title</title>
</head>

<body>

  <input type="checkbox" name="checklist-list" class="checkbox-box" id="checkbox0">
  <input type="checkbox" name="checklist-list" class="checkbox-box" id="checkbox1">
  <input type="checkbox" name="checklist-list" class="checkbox-box" id="checkbox2">

  <table>
    <thead>
      <tr>
        <th><input type="checkbox" name="checklist-list" class="checkbox-box"></th>
        <th>Item1</th>
        <th>Item2</th>
      </tr>
    </thead>
    <tbody>
      <tr id="checkbox0-tr">
        <td class="checkbox-td"><label for="checkbox0" class="fake-checkbox"></label></td>
        <td class="item-td"><input class="input-item" type="text" value="Artificial"></td>
        <td class="item-td"><input class="input-item" type="text" value="Amateurs"></td>
      </tr>
      <tr id="checkbox1-tr">
        <td class="checkbox-td"><label for="checkbox1" class="fake-checkbox"></label></td>
        <td class="item-td"><input class="input-item" type="text" value="Broken"></td>
        <td class="item-td"><input class="input-item" type="text" value="Barriers"></td>
      </tr>
      <tr id="checkbox2-tr">
        <td class="checkbox-td"><label for="checkbox2" class="fake-checkbox"></label></td>
        <td class="item-td"><input class="input-item" type="text" value="Casual"></td>
        <td class="item-td"><input class="input-item" type="text" value="Create"></td>
      </tr>
    </tbody>
    <tfoot>
    </tfoot>
  </table>
</body>

But honestly, I wouldn't recommend using this approach in production.

like image 186
Ilya Streltsyn Avatar answered Oct 26 '25 12:10

Ilya Streltsyn


It's all in the selectors: use the pseudo selector :checked and the sign + to select the right element on the right state.

.check-with-label:checked + .input-for-check {
  color: red;
  font-style: italic;
  text-decoration: line-through;
}
<div>
  <input type="checkbox" class="check-with-label" id="idinput" />
  <input class="input-for-check" type="text" name="input-field">
</div>
like image 37
Ivan Avatar answered Oct 26 '25 13:10

Ivan