4

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>

2
  • 2
    Possible duplicate of Is there a CSS parent selector? Commented Jul 26, 2017 at 12:47
  • I have provided an answer Commented Jul 26, 2017 at 12:49

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Ilya. This validated my feeling that there wasn't a direct solution and I greatly appreciate the creativity you employed by providing a hack that works with the constraints of the problem. I don't suspect I will use this over JavaScript; however, I learned a lot from your snippet.
2

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>

1 Comment

Thank you for providing a potential solution to my problem, however, the table element was removed and this solution does not demonstrate a CSS method to modify style on an entire row.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.