CSS 同级组合器在 <details> 元素

问题描述 投票:0回答:1

我检查倒计时后计时器标签没有显示,这是 HTML 结构和 CSS:

details {
  display: flex;
  /* Use flexbox layout */
  flex-direction: column;
  /* Stack children vertically */
  width: 100%;
  /* Full width of the container */
  font-size: 0.8em;
  /* Smaller font size */
  column-gap: 5px;
  /* Space between flex items */
}

summary {
  margin-bottom: 10px;
}

label {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 10px;
}


/* More options section */

#timer {
  width: 4ch;
  text-align: center;
  outline: none;
}

label[for='timer'] {
  display: none;
}

input[name='countdown']:checked~label[for='timer'] {
  display: flex;
}


/* end of options section */
<details>
  <summary>More options...</summary>
  <label for="blip">
    <input type="checkbox" name="blipping" id="blip"> Blipping
  </label>
  <label for="countdown">
<input type="checkbox" name="countdown" id="countdown"> Countdown
</label>
  <label for="timer">
Countdown: <input type="number" name="timer" id="timer" min="5" max="999"> Second
</label>
</details>

我尝试用div覆盖标签,但同级组合器仍然没有检测到它, 仍然给出相同的结果。

问题的关键是,当用户仅使用 CSS 选中/取消选中“倒计时”复选框时,我想切换“计时器”标签。

html css selector styling
1个回答
0
投票

您遇到的问题是,鉴于以下 HTML(您发布的 HTML 的轻度格式化/整理副本),同级组合器无法按照您编写代码的方式工作:

<label for="countdown">
  <input type="checkbox" name="countdown" id="countdown"> Countdown
</label>
<label for="timer">
  Countdown: <input type="number" name="timer" id="timer" min="5" max="999"> Second
</label>

您正在使用的选择器:

input[name='countdown']:checked~label[for='timer'] {
  display: flex;
}

要求选中的“倒计时”

<input>
<label>
元素的前一个兄弟元素,但事实并非如此;
<label>
是“倒计时”<input> 元素的
parent
的相邻同级。

因此,根据您的用户群的浏览器兼容性,您可以使用

:has()
选择器,并使用:

/*
  here we initially select the <label> element with the "for"
  attribute equal to "countdown", which contains a checked <input>
  element and then select its following sibling <label> element
  (using the same general sibling combinator) that has a "for"
  attribute equal to "timer":
*/
label[for=countdown]:has(input:checked) ~ label[for=timer] {
  /* I'm using display: initial to update the display, that way
     the browser can decide for itself to display it as block,
     flex-item, grid-item, list-item... according to the CSS
     cascade: */
  display: initial;
}

details {
  display: flex;
  /* Use flexbox layout */
  flex-direction: column;
  /* Stack children vertically */
  width: 100%;
  /* Full width of the container */
  font-size: 0.8em;
  /* Smaller font size */
  column-gap: 5px;
  /* Space between flex items */
}

summary {
  margin-bottom: 10px;
}

label {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 10px;
}


/* More options section */

#timer {
  width: 4ch;
  text-align: center;
  outline: none;
}

label[for='timer'] {
  display: none;
}

label[for=countdown]:has(input:checked)~label[for=timer] {
  display: initial;
}


/* end of options section */
<details>
  <summary>More options...</summary>
  <label for="blip">
    <input type="checkbox" name="blipping" id="blip"> Blipping
  </label>
  <label for="countdown">
    <input type="checkbox" name="countdown" id="countdown"> Countdown
  </label>
  <label for="timer">
    Countdown: <input type="number" name="timer" id="timer" min="5" max="999"> Second
  </label>
</details>

参考资料:

© www.soinside.com 2019 - 2024. All rights reserved.