skip to Main Content

I am building a ToDo list in React. I have a component that contains a ul with the li items being check boxes. The check boxes work as intended in Chrome, but do not check when clicked in Mozilla. How may I correct this, so the checkboxes are compatible with all browsers? Thank you for any assistance.

GitHub Link

App.jsx code

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" />
            Item 1
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
        <li>
          <label>
            <input type="checkbox" />
            Item 2
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
      </ul>
    </>
  );
}

styles.css code

* {
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}

body {
  background: #333;
  color: hsl(200, 100%, 90%);
  max-width: 400px;
  padding: 1rem;
  margin: 0 auto;
}

.new-item-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.btn {
  background: hsl(200, 100%, 50%, 0.1);
  border: 1px solid hsl(200, 100%, 50%);
  color: hsl(200, 100%, 50%);
  padding: 0.25em 0.5em;
  border-radius: 0.25em;
  cursor: pointer;
  outline: none;
}

.btn:hover,
.btn:focus-visible {
  background: hsl(200, 100%, 50%, 0.2);
}

.btn.btn-danger {
  background: hsl(0, 100%, 40%, 0.1);
  border: 1px solid hsl(0, 100%, 40%);
  color: hsl(0, 100%, 40%);
}

.btn.btn-danger:hover,
.btn.btn-danger:focus-visible {
  background: hsl(0, 100%, 40%, 0.2);
}

.new-item-form input {
  outline: none;
  border: 1px solid hsl(200, 100%, 40%);
  background: hsl(200, 100%, 30%);
  border-radius: 0.25em;
  padding: 0.25em 0.5em;
  color: hsl(200, 100%, 90%);
}

.new-item-form input:focus {
  border: 1px solid hsl(200, 100%, 70%);
}

.header {
  font-size: 1.5rem;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.list {
  margin: 0;
  padding: 0;
  margin-left: 1rem;
  list-style: none;
}

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

.list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.list li {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.list li label {
  display: flex;
  gap: 0.25rem;
  cursor: pointer;
  align-items: center;
}

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

.list li input {
  outline: none;
  width: 0;
  height: 0;
  appearance: none;
  pointer-events: none;
  position: absolute;
}

.list li label::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:hover::before {
  background: hsl(200, 100%, 80%);
}

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

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

I tried inspecting in the debugger, but no error messages occurred. I originally loaded the page via a local host in Mozilla and the checkboxes did not work. Then I loaded the page in Chrome as part of troubleshooting, and the boxes worked as intended.

2

Answers


  1. Firefox doesn’t support :has pseudo-class yet.

    https://caniuse.com/css-has

    I’m pretty sure you can rewrite your css using sibling selector (+ or ~).

    Login or Signup to reply.
  2. The problem was in your css code. There were unnecessary styles were applied and causing issues with the checkbox styling, you can remove those styles to ensure proper checkbox appearance. This is the updated version.

    * {
      font-family: Arial, Helvetica, sans-serif;
      box-sizing: border-box;
    }
    
    body {
      background: #333;
      color: hsl(200, 100%, 90%);
      max-width: 400px;
      padding: 1rem;
      margin: 0 auto;
    }
    
    .new-item-form {
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }
    
    .form-row {
      display: flex;
      flex-direction: column;
      gap: 0.1rem;
    }
    
    .btn {
      background: hsl(200, 100%, 50%, 0.1);
      border: 1px solid hsl(200, 100%, 50%);
      color: hsl(200, 100%, 50%);
      padding: 0.25em 0.5em;
      border-radius: 0.25em;
      cursor: pointer;
      outline: none;
    }
    
    .btn:hover,
    .btn:focus-visible {
      background: hsl(200, 100%, 50%, 0.2);
    }
    
    .btn.btn-danger {
      background: hsl(0, 100%, 40%, 0.1);
      border: 1px solid hsl(0, 100%, 40%);
      color: hsl(0, 100%, 40%);
    }
    
    .btn.btn-danger:hover,
    .btn.btn-danger:focus-visible {
      background: hsl(0, 100%, 40%, 0.2);
    }
    
    .new-item-form input {
      outline: none;
      border: 1px solid hsl(200, 100%, 40%);
      background: hsl(200, 100%, 30%);
      border-radius: 0.25em;
      padding: 0.25em 0.5em;
      color: hsl(200, 100%, 90%);
    }
    
    .new-item-form input:focus {
      border: 1px solid hsl(200, 100%, 70%);
    }
    
    .header {
      font-size: 1.5rem;
      margin-top: 1.5rem;
      margin-bottom: 0.5rem;
    }
    
    .list {
      margin: 0;
      padding: 0;
      margin-left: 1rem;
      list-style: none;
    }
    
    .list li:has(input:checked) label {
      color: hsl(200, 20%, 40%);
    }
    
    .list {
      display: flex;
      flex-direction: column;
      gap: 0.3rem;
    }
    
    
    .list li {
      display: flex;
      gap: 0.5rem;
      align-items: center;
    }
    
    .list li label {
      display: flex;
      gap: 0.25rem;
      cursor: pointer;
      align-items: center;
    }
    
    .list li:has(input:focus-visible) label {
      outline: 1px solid hsl(200, 100%, 50%);
    }
    
    .list li input[type="checkbox"] {
      position: absolute;
      opacity: 0;
      pointer-events: none;
    }
    
    .list li input[type="checkbox"] + label {
      position: relative;
      padding-left: 2.5em; /* Adjust as needed */
      cursor: pointer;
    }
    
    .list li input[type="checkbox"] + label::before {
      content: "";
      position: absolute;
      left: 0;
      top: 0;
      width: 0.95em; /* Adjust as needed */
      height: 0.95em; /* Adjust as needed */
      border: 2px solid hsl(200, 100%, 40%);
      border-radius: 0.25em;
      background-color: hsl(200, 100%, 30%);
      display: flex; /* Added */
      justify-content: center; /* Added */
      align-items: center; /* Added */
    }
    
    .list li input[type="checkbox"]:checked + label::after {
      content: "2713";
      position: absolute;
      left: 0.35em; /* Adjust as needed */
      top: 0.15em; /* Adjust as needed */
      color: hsl(200, 100%, 90%);
      font-size: 0.75rem;
      font-weight: bold;
    }
    

    In App.jsx file i noticed something. You have to add id attribute to input tag and htmlFor attribute to label so React can deal with UI changes efficiently. Happy coding.

    The updated version

    import "./styles.css";
    import { useState } from "react";
    
    
    const itemArray = [
      { id: 1, text: "Item 1", checked: false },
      { id: 2, text: "Item 2", checked: false },
      { id: 3, text: "Item 3", checked: false },
      { id: 4, text: "Item 4", checked: false },
      { id: 5, text: "Item 5", checked: false },
    ];
    
    const App = () => {
      const [items, setItems] = useState(itemArray);
    
      const handleCheckboxChange = (itemId) => {
        setItems((prevItems) =>
          prevItems.map((item) =>
            item.id === itemId ? { ...item, checked: !item.checked } : item
          )
        );
      };
    
      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">
          {items.map(({id, text,checked}) => (
            <li key={id}>
              <>
                <input
                  type="checkbox"
                  id={`checkbox-${id}`}
                  name={`checkbox-${id}`}
                  checked={checked}
                  onChange={() => handleCheckboxChange(id)}
                />
                <label htmlFor={`checkbox-${id}`}>{text}</label>
              </>
              <button className="btn btn-danger">Delete</button>
            </li>
          ))}
        </ul>
      </>
      );
    };
    
    export default App;
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search