Home > Back-end >  Changing content of the label with checkbox and CSS, w/o JavaScript
Changing content of the label with checkbox and CSS, w/o JavaScript

Time:11-30

I would like to achieve changing the content for label when the checkbox is checked and vice-versa.

For that I prepare the following implementation:

I paste the invisible checkbox directly after <body>:

<input type="checkbox" id="theme-switch" />

with the SASS:

input#theme-switch[type=checkbox]
    display: none
    &:not(:checked)
        & ~ label[for=theme-switch]
            & > .sun
                &::before
                    content: var(--theme-moon)
    &:checked
        & ~ label[for=theme-switch]
            & > .sun
                &::before
                    content: var(--theme-sun)

And the result element can be placed anywhere in the body with the following content:

<label for="theme-switch">
    <div ></div>
</label>

Obviously, I want to replace the content of the .sun with text valid for that state.

I am not putting the checkbox nearby the label, because I am controlling the theme with it.

The following Sass code is designed for it:

# Some cycle
@if $theme == dark
        \:root[data-theme=#{$theme}], html:has(> body > input#theme-switch[type=checkbox]:checked), body:has(> input#theme-switch[type=checkbox]:checked), input#theme-switch[type=checkbox]:checked ~ header, input#theme-switch[type=checkbox]:checked ~ main, input#theme-switch[type=checkbox]:checked ~ article, input#theme-switch[type=checkbox]:checked ~ footer
            @include theme($theme)

Is there any way to change the content of label only with CSS (SASS) and w/o JavaScript? Or is there any other trick to achieve it?

CodePudding user response:

~ is the general sibling combinator. So input:checked ~ label would only select the label, if it was an actual sibling of the input field. You will need to target an actual sibling of the input, then you can target the label within that.

Let's imagine putting it in: header > nav > .navbar-menu > div > div > label input and header are on the same level in HTML.

Then it would be input:checked ~ header > nav > .navbar-menu > div > div > label.

The important thing is to target the actual sibling first, otherwise ~ won't work. After that, you can select anything you want inside header.

  • Related