如何在通过按住鼠标左键来聚焦某个元素时,仅应用该元素的CSS样式;并在释放鼠标且光标移出该元素之外时让它失去焦点?

前端开发 2026-07-09

我正在研究一个无障碍设计概念:用户点击并按住一个元素(如按钮),随后在其外释放鼠标。当发生这种情况时,元素的视觉样式应相应地进行调整。


以下是这个无障碍设计概念的描述:

  • 如果按钮被点击,然后光标移出它,或在其外部再次点击,样式应保持不变,即 background-color: blue
  • 另一方面,如果按钮只是被点击并按住,随后在该元素之外释放点击(即按钮),则应应用 background-color: red 样式。

请参阅以下演示以作参考:

Accessibility design concept demo

注:上面的GIF演示旨在展示行为,而非样式(例如边框和下划线文本)。其实,我已经实现了那个特定的行为;不过,我现在正尝试将设计概念扩展到包括背景色等其他属性类型。


document.addEventListener("DOMContentLoaded", function() {
  const el = document.getElementById("submit");
  el.addEventListener("blur", function(e) {
    e.preventDefault();
    el.classList.add("out-of-focus");
  });
});
#submit.out-of-focus {
  background-color: red;
}

#submit:hover {
  background-color: green;
}

#submit {
  background-color: blue;
}
    <button class="submit" id="submit">Some button</button>

注:此代码片段的输出并不完全符合预期的无障碍设计行为。我提供它的目的是演示我打算如何实现目标。


最后,为了避免让这套设计概念的代码实现过于复杂,我希望仅使用纯CSS来实现,不依赖JavaScript,同时确保不与其他现有样式规则冲突。请注意,我在实际环境中也在使用Bootstrap v5.2.3。


仅用纯CSS就能实现这个设计概念吗?如果不能,能否解释原因并给出替代方案?

解决方案

要实现这一无障碍设计概念,你只需要指定 :focus 伪类,并对其他伪类进行特定排除,在这种情况下排除 :hover:active 伪类。以下是完整的CSS:

#submit:focus:not(:hover :active) {
  background-color: red;
}

更新:上述解决方案不完整。要实现预期输出,需要优先级CSS (CSS Cascade 以及JavaScript覆盖是必需的。*

以下是完整的 MRE 代码:

(function () {
  const btn = document.getElementById("submit");

  btn.addEventListener("click", (e) => {
    // or pointerup event type
    btn.classList.add("active");
  });

  btn.addEventListener("mousedown", () => {
    btn.classList.remove("active");
  });
})();
#submit {
  background-color: blue;
}

#submit:hover {
  background-color: green !important;
}

#submit:focus:not(:hover :active) {
  background-color: red;
}

.submit.active {
  background-color: blue !important;
}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS Playground</title>
    <link rel="icon" type="image/x-icon" href="img/www_icon.ico" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet"/>
    <link rel="stylesheet" href="css/style.css" />
  </head>

  <body>
    <div class="d-flex justify-content-center align-items-center vh-100">
      <button class="submit text-white fw-bold" id="submit">Click me</button>
    </div>
    <script src="./script.js"></script>
  </body>
</html>

以下是上述代码片段能起作用的关键原因!

  • #submit.active 选择器中移除 !important 规则会破坏预期行为,因为 #submit:focus:not(:hover, :active) 具有优先权。
  • 事件 mousedown 会在 clickpointerup 事件之前触发。这对于在按钮接收不同指针交互时重置样式属性至关重要。

最后,我通过在 :hover 规则中添加一个 !important 标志来调整,以确保在级联中悬停状态占优。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章