0

What would be the solution for applying the attached stylesheets on the checkbox ::before{} pseudoelement when it's checked? As soon as I have supplied the checked={checked} property, the attached stylesheets shop working

export const ThemeSwithcer: FC = () => {
    const [checked, setChecked] = useState(false);

    useEffect(() => {                
        if (localStorage.getItem('theme') === 'theme-dark') {
            setTheme('theme-dark');
            setChecked(false);
        } else {
            setTheme('theme-light');
            setChecked(true);
        }
    }, [checked]);

    const setTheme = (themeName: string) => {
        localStorage.setItem('theme', themeName);
        document.documentElement.className = themeName;
    }

    const themeChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (localStorage.getItem('theme') === 'theme-dark') {
            setTheme('theme-light');
        } else {
            setTheme('theme-dark');
        }
    }

    return (
        <label className="Theme-Switcher">
            <input className="Theme-Switcher-Util" type="checkbox" onChange={themeChangeHandler} checked={checked} />
            <span className="Theme-Switcher-Slider round"></span>
        </label>
    );
}
&:checked + .Theme-Switcher-Slider:before {
  -webkit-transform: translateX(24px);
  -ms-transform: translateX(24px);
  transform: translateX(24px);
  background: white url('https://i.ibb.co/7JfqXxB/sunny.png');
  background-repeat: no-repeat;
  background-position: center;
}
0

1 Answer 1

1

TL;DR

Also, you have to delete the:

useEffect(() => {                
  if (localStorage.getItem('theme') === 'theme-dark') {
    setTheme('theme-dark');
    setChecked(false);
  } else {
    setTheme('theme-light');
    setChecked(true);
  }
}, [checked]);

And can see how it works in this image: https://im5.ezgif.com/tmp/ezgif-5-f94608df776f.gif

Explanation

  • With this useEffect you're setting back the value of check.

Not clear if you want to apply the styles to the checked element or to the span next to it.

So, I created one codesandbox for both examples, you can check it: https://codesandbox.io/s/summer-brook-ktw08?file=/src/styles.css

But the code would be:

In the next code you will see one example for:

  1. CSS Selector for normal Checkbox
  2. CSS Selector for Checked Checkbox
  3. CSS Selector for Checked Checkbox Before
  4. CSS Selector for Neighbor Before for Checkbox
  5. CSS Selector for Neighbor Before for Checked Checkbox

The rules in the previous 3 are just examples. The rules in the last 2 are to show the moon and sun based on your code and specific needs.

Important I'd say your missing part is the content: ' '; display: inline-block in the modifications for before elements. Basically, without those 2 attributes, you won't be able to see the before because its default size is 0x0.

/* 1. Checkbox */
.Theme-Switcher-Util {
  margin-right: 36px;
}

/* 2. Checked Element */
.Theme-Switcher-Util:checked {
  margin-right: 36px;
}

/* 3. Before of the Checked Element */
.Theme-Switcher-Util:checked::before {
  content: ' ';
  display: inline-block;
  background: rgba(255, 0, 0, .5);
  width: 50px;
  height: 10px;
}

/* 4. Before of the Slider after the NOT Checked Element */
.Theme-Switcher-Util + .Theme-Switcher-Slider::before {
  content: ' ';
  display: inline-block;
  height: 24px;
  width: 24px;
  background: white url('https://i.pinimg.com/564x/cc/d4/46/ccd4469667ba2915b82d48e28700843a.jpg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
/* 5. Before of the Slider after the Checked Element */
.Theme-Switcher-Util:checked + .Theme-Switcher-Slider::before {
  content: ' ';
  display: inline-block;
  height: 24px;
  width: 24px;
  background: white url('https://i.ibb.co/7JfqXxB/sunny.png');
  background-repeat: no-repeat;
  background-position: center;
}
Sign up to request clarification or add additional context in comments.

10 Comments

What i want is that when the checkbox state is set to checked with JavaScript, the supplied stylesheets would apply to the before pseudoelement. Is this generally possible?
In that case, your needed selector is 3 .Theme-Switcher-Util:checked::before for checked before or 5 .Theme-Switcher-Util:checked + .Theme-Switcher-Slider::before for the span next to it. Also, include ` content: ' '; display: inline-block;` or it won't work
In the codesandbox you can see the moon/sun with the checkbox :)
You can check this specific sandbox: codesandbox.io/s/adoring-cartwright-mvwei?file=/src/styles.css with your specific case and without other examples
could you please guide me through? =c here is the full scss code snippet jsfiddle.net/j1hv8Ly7
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.