You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/JSX复选框在Firefox无法勾选,Chrome正常,如何修复?

React Todo列表Firefox复选框失效问题解决

你的复选框在Firefox中无法勾选的核心原因是CSS的:has()选择器在旧版Firefox中未被支持,同时你通过CSS将原生复选框隐藏并禁用了指针事件,导致视觉状态无法通过:has()更新,看起来像是未勾选(实际input的状态可能已切换,但无视觉反馈)。


解决方法1:升级并启用Firefox的:has()支持

  • 将Firefox升级到121版本及以上(该版本开始默认支持:has()选择器)
  • 若暂时无法升级,在Firefox地址栏输入about:config,找到layout.css.has-selector.enabled并设置为true

解决方法2:修改CSS脱离:has()依赖(推荐,全浏览器兼容)

通过调整HTML结构,结合相邻兄弟选择器实现视觉效果,同时保留label的点击触发逻辑:

修改后的App.jsx

import "./styles.css";

export default function App() {
  return (
    <>
      <form className="new-item-form">
        <div className="form-row">
          <label htmlFor="item">New Item</label>
          <input type="text" id="item" />
        </div>
        <button className="button">Add</button>
      </form>
      <h1 className="header">Todo List</h1>
      <ul className="list">
        <li>
          <label>
            <input type="checkbox" />
            <span>Item 1</span>
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
        <li>
          <label>
            <input type="checkbox" />
            <span>Item 2</span>
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
      </ul>
    </>
  );
}

修改后的styles.css关键部分

/* 移除所有:has()相关选择器,替换为相邻兄弟选择器 */
.list li label input:checked + span {
  color: hsl(200, 20%, 40%);
}

.list li label input:focus-visible + span {
  outline: 1px solid hsl(200, 100%, 50%);
}

.list li label span::before {
  content: "";
  display: block;
  width: 0.9rem;
  height: 0.9rem;
  background: hsl(200, 100%, 90%);
  border-radius: 0.25em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.list li label span:hover::before {
  background: hsl(200, 100%, 80%);
}

.list li label input:checked + span::before {
  content: "✔";
  background: hsl(200, 100%, 40%);
  color: hsl(200, 100%, 90%);
  font-size: 0.75rem;
  font-weight: bold;
}

.list li label input:checked + span:hover::before {
  background: hsl(200, 100%, 30%);
}

/* 调整input样式,保留点击触发逻辑 */
.list li label input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

解决方法3:结合React状态管理(符合React开发模式)

利用React的useState管理todo的勾选状态,通过类名控制样式,彻底脱离对:has()的依赖:

修改后的App.jsx

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [todos, setTodos] = useState([
    { id: 1, text: "Item 1", checked: false },
    { id: 2, text: "Item 2", checked: false }
  ]);

  const toggleTodo = (id) => {
    setTodos(todos.map(todo => 
      todo.id === id ? {...todo, checked: !todo.checked} : todo
    ));
  };

  return (
    <>
      <form className="new-item-form">
        <div className="form-row">
          <label htmlFor="item">New Item</label>
          <input type="text" id="item" />
        </div>
        <button className="button">Add</button>
      </form>
      <h1 className="header">Todo List</h1>
      <ul className="list">
        {todos.map(todo => (
          <li key={todo.id} className={todo.checked ? "checked" : ""}>
            <label>
              <input 
                type="checkbox" 
                checked={todo.checked}
                onChange={() => toggleTodo(todo.id)}
              />
              <span>{todo.text}</span>
            </label>
            <button className="btn btn-danger">Delete</button>
          </li>
        ))}
      </ul>
    </>
  );
}

对应styles.css修改

.list li.checked label span {
  color: hsl(200, 20%, 40%);
}

.list li label span::before {
  content: "";
  display: block;
  width: 0.9rem;
  height: 0.9rem;
  background: hsl(200, 100%, 90%);
  border-radius: 0.25em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.list li label span:hover::before {
  background: hsl(200, 100%, 80%);
}

.list li.checked label span::before {
  content: "✔";
  background: hsl(200, 100%, 40%);
  color: hsl(200, 100%, 90%);
  font-size: 0.75rem;
  font-weight: bold;
}

.list li.checked label span:hover::before {
  background: hsl(200, 100%, 30%);
}

.list li label input:focus-visible + span {
  outline: 1px solid hsl(200, 100%, 50%);
}

.list li label input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

内容的提问来源于stack exchange,提问作者thelinuxlobster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:57:26