Select 仅当输入为空且未聚焦时才添加标签?

Select label only if input is empty and not focused?

只有当 input 没有 focus 并且 value''(空字符串)

.email label:not(input[value='']:not(input:focus) ~ label) {
  color: green;
}
<div class='email'>
  <label for='email'>Email</label>
  <input type='email' id='email' value={email} onChange={handleEmail} />
</div>

只有 :has() pseudo class which at time of writing is only supported by Safari

才能选择 CSS 中的前一个兄弟姐妹

您当前的选择器:

.email label:not(input[value='']:not(input:focus) ~ label)

有句法上不正确的括号,但如果我们修复它:

.email label:not(input[value='']):not(input:focus) ~ label

它选择标签之后的所有标签,该标签不是 value='' 的输入,也不是重点输入,它们都是 class [=18 的元素的后代=].

下面是如何使用 has() 实现您想要的选择器:

label:has(+ #email:not(input[value='']:not(input:focus)) {
  color: green;
}
<div className='email'>
  <label htmlFor='email'>Email</label>
  <input type='email' id='email' value={email} onChange={handleEmail} />
</div>

Here is a JavaScript polyfill 您可能想同时使用。

除此之外,您可以使用的一种可能对屏幕阅读器等可能会或可能不会很糟糕的 hack 是反转标记并使用 CSS:

将其排序

#email:not(input[value='']):not(input:focus)+label {
  color: green;
}

.email {
  width: fit-content;
  display: flex;
  flex-flow: row-reverse wrap;
}
<div class='email'>
  <input type='email' id='email' value={email} onChange={handleEmail} />
  <label htmlFor='email'>Email</label>
</div>

您可以让生活更轻松一些(因为 :has 目前支持不是很好)。首先,将 input 放在 之前 label 然后,为了保留您的原始格式,将您的父级 email div 声明为 flex 容器并反转其弹性行方向。

CSS

.email {
  display: inline-flex;
  flex-direction: row-reverse;
  column-gap: 0.35rem;
}

input[value=""]:not(:focus) + label {
  color: red;
}

JSX

<div className="email">
  <input type="email" id="email" onChange={handleEmail} />
  <label htmlFor="email"> Email </label>
</div>

CodeSandbox example