Author: JowayYoung warehouse: Github, CodePen blog: official website, nuggets, si Fu, Zhihu public number: IQ front special statement: the original is not easy, shall not be reproduced without authorization or plagiarism, if you need to be reproduced can contact the author authorized

preface

Dark Mode is a concept that dates back to Mojave for MacOS. It provides users with a choice of both light theme and dark theme skins. Dark theme is often referred to as dark mode. For eye health, I chose dark mode on my phone, tablet and computer.

With Apple increasingly demanding that every system platform adapt to The Dark mode, I have explored a dark mode adaptation solution that should be the lowest cost on the market.

Those of you who know me know that I am a heavy CSS enthusiast, and of course I use pure CSS to implement this solution. Yes, without a single section of JS, the side once again proves the power of CSS.

Train of thought

The idea is simple: use a button to switch theme styles back and forth. If the button is not selected, it switches to a light theme, and if it is selected, it switches to a dark theme. Available: Checked and + clicked to complete this task.

  • : Checked: indicates the selected form element
  • + : the adjacent sibling of the element

Use to simulate the button. When the button is selected, : Checked is triggered, and + is used to drive the adjacent website body

into dark mode. When the selected state is cancelled, the dark mode will be quit.
<body>
    <input class="ios-switch" type="checkbox">
    <div class="main">Website main body</div>
</body>
Copy the code

For more information about selectors and their classification, please refer back to my article, “Probably the most complete and memorable CSS selector classification Method.”

Switch button

I wanted to design a beautiful button, but I didn’t have any special ideas, so I opened the iPhone and implemented the toggle button in the Settings using pure CSS.

The size and color are consistent with the iPhone toggle button. The idea is to use to simulate the iPhone toggle button, declare appearance: None to erase its default appearance, use ::before to simulate the background area, use ::after to simulate the click area, and add some small animations after triggering :checked to modify it almost perfectly.

<input class="ios-switch" type="checkbox">
Copy the code
.btn {
    border-radius: 31px;
    width: 102px;
    height: 62px;
    background-color: #e9e9eb;
}
.ios-switch {
    position: relative;
    appearance: none;
    cursor: pointer;
    transition: all 100ms;
    @extend .btn;
    &::before {
        position: absolute;
        content: "";
        transition: all 300ms cubic-bezier(.45.1.4.1);
        @extend .btn;
    }
    &::after {
        position: absolute;
        left: 4px;
        top: 4px;
        border-radius: 27px;
        width: 54px;
        height: 54px;
        background-color: #fff;
        box-shadow: 1px 1px 5px rgba(# 000.3);
        content: "";
        transition: all 300ms cubic-bezier(.4.4.25.1.35);
    }
    &:checked {
        background-color: #5eb662;
        &::before {
            transform: scale(0);
        }
        &::after {
            transform: translateX(40px); }}}Copy the code

Please click here for the online demo and source code.

Diablo mode

Remember April 4 when the entire Internet went into mourning mode? I published an article called “One Line of Code goes into Mourning mode,” which makes clever use of the powerful CSS attribute Filter.

html {
    filter:grayscale(1);
}
Copy the code

Really is a line of code, this is no exception, a line of code into the dark mode.

html {
    filter: invert(1) hue-rotate(180deg);
}
Copy the code

Filter compatibility is not poor, students can rest assured to use, there are some details need to pay attention to, this article will not repeat the explanation, details can be referred to “a line of code into mourning mode”.

Filter is an amazing property that can apply some basic Photoshop filter effects to a website. I like to use filter in my CodePen. Many pure CSS effects use filter in my CodePen. I like to use hue-rotate() to dynamically generate transition colors with CSS variables. Make your CSS more exciting.

This dark mode uses two filter functions: invert() and hue-rotate().

  • invert(): reverse phase, reverse output image coloring, value is0%Then, there is no change and the value is0 ~ 100%Is the linear multiplier effect, and the value is zero100%It reverses completely
  • hue-rotate(): Hue rotation, attenuate image coloring, process non-black and white colors, value is0degThen, there is no change and the value is0~360degIs gradually weakened, and the value exceeds360degIt’s like going around N times and calculating the rest

Invert () invert() invert() invert() invert() Hue -rotate() simply means to dilute colors. To ensure that the theme tone does not change, it is reasonable to declare the hue rotation at 180deg.

According to the above analysis, when the button is selected, use + along with its siblings. Transition :all 300ms if the sibling element does not have a background color, you need to declare background-color:# FFF.

.ios-switch{... &:checked{... & +.main {
            filter: invert(1) hue-rotate(180deg); }}}.main {
    background-color: #fff;
    transition: all 300ms;
}
Copy the code

To better illustrate the effect on CodePen, use

To optimize the

Careful students may find that how the pictures have become the feeling of taking B ultrasound.

As a design principle, skin only applies to components. Elements of some media types, such as backgrounds, images, videos, etc., cannot be handled directly and should be left as they are. Since the dark mode is implemented using the filter’s inversion and hue rotation, the media elements can be restored by using the filter’s inversion and hue rotation again. Those of you who have used Photoshop filters should know better.

img.video {
    filter: invert(1) hue-rotate(180deg);
}
Copy the code

One more question, what about the background? As we all know, backgrounds are declared using the background family of attributes and therefore cannot be annotated with a specific selector. However, another way of thinking about it is to add a specific class name to the element that has the background, including it in the above rule.

Use Chrome DevTools to look at the source code of the Gold Digger community website and find that these avatars, thumbnails, and presentation images have some specific class names. Add their specific class names to the rule.

img.video..avatar..image..thumb {
    filter: invert(1) hue-rotate(180deg);
}
Copy the code

In a generic web site, the class name is customizable, and the most feasible way to do this is to define a specific class name. Exclude. Exclude all elements that do not use the filter effect.

.exclude {
    filter: invert(1) hue-rotate(180deg);
}
Copy the code

transform

In order to demonstrate the code, we used

In Chrome, press F12 or Cmd+Alt+I to open Chrome DevTools and analyze the HTML structure of the site.

<body>
    <div id="__nuxt">.</div>
</body>
Copy the code

Insert the toggle button in .

<body>
    <input class="ios-switch" type="checkbox">
    <div id="__nuxt">.</div>
</body>
Copy the code

Insert the following SCSS code into the new

.btn {
    border-radius: 31px;
    width: 102px;
    height: 62px;
    background-color: #e9e9eb;
}
.ios-switch {
    position: relative;
    appearance: none;
    cursor: pointer;
    transition: all 100ms;
    @extend .btn;
    &::before {
        position: absolute;
        content: "";
        transition: all 300ms cubic-bezier(.45.1.4.1);
        @extend .btn;
    }
    &::after {
        position: absolute;
        left: 4px;
        top: 4px;
        border-radius: 27px;
        width: 54px;
        height: 54px;
        background-color: #fff;
        box-shadow: 1px 1px 5px rgba(# 000.3);
        content: "";
        transition: all 300ms cubic-bezier(.4.4.25.1.35);
    }
    &:checked {
        background-color: #5eb662;
        &::before {
            transform: scale(0);
        }
        &::after {
            transform: translateX(40px);
        }
        & + #__nuxt {
            filter: invert(1) hue-rotate(180deg);
            img.video..avatar..image..thumb {
                filter: invert(1) hue-rotate(180deg); }}}}#__nuxt {
    background-color: #fff;
    transition: all 300ms;
}
Copy the code

When the switch button does not appear, you can use position: Absolute to position it to the desired position.

.ios-switch {
    position: absolute;
    right: 0;
    top: 0;
    z-index: 99999;
    outline: none;
}
Copy the code

Or create a

, bind each other by declaring
and

If you feel that the explanation is a bit messy, you can sort it out and complete the above operations in three steps.

Go to the Nuggets community website

Press F12 or Cmd+Alt+I to open Chrome DevTools

To make it easier to copy and paste, I compress the CSS code from the above analysis.

<style>.btn..ios-switch::before..ios-switch{border-radius:31px;width:102px;height:62px;background-color:#e9e9eb; }.ios-switch{position:relative; appearance:none;cursor:pointer;transition:all 100ms; }.ios-switch::before{position:absolute;content:"";transition:all 300ms cubic-bezier(0.45.1.0.4.1); }.ios-switch::after{position:absolute;left:4px;top:4px;border-radius:27px;width:54px;height:54px;background-color:#fff;box-shadow:1px 1px 5px rgba(0.0.0.0.3);content:"";transition:all 300ms cubic-bezier(0.4.0.4.0.25.1.35); }.ios-switch:checked{background-color:#5eb662; }.ios-switch:checked::before{transform:scale(0); }.ios-switch:checked::after{transform:translateX(40px); }.ios-switch:checked + #__nuxt{filter:invert(1) hue-rotate(180deg); }.ios-switch:checked + #__nuxt img..ios-switch:checked + #__nuxt video..ios-switch:checked + #__nuxt .avatar..ios-switch:checked + #__nuxt .image..ios-switch:checked + #__nuxt .thumb{filter:invert(1) hue-rotate(180deg); }#__nuxt{background-color:#fff;transition:all 300ms; }.ios-switch{position:absolute;right:0;top:0;z-index:99999;outline:none; }</style>
Copy the code

Insert into

<body>
    <input class="ios-switch" type="checkbox">
    <div id="__nuxt">.</div>
</body>
Copy the code

In this way, a pure CSS implementation can make the site instantly have dark mode switching function, there is no CSS impressive.

conclusion

The whole pure CSS implementation scheme revolves around three points: Checked, + and filter, which are indispensable. Seemingly simple, if not commonly used CSS to do special effects it is difficult to imagine just three dots can also complete such a powerful function.

<body>
    <input class="ios-switch" type="checkbox">
    <div class="main">Website main body</div>
</body>
Copy the code
.ios-switch{... &:checked{... & +.main {
            filter: invert(1) hue-rotate(180deg);
            img.video..exclude {
                filter: invert(1) hue-rotate(180deg); }}}}.main {
    background-color: #fff;
    transition: all 300ms;
}
Copy the code

Compared to the CSS+JS implementation, there is no need to maintain a complete set of dark mode style code, no DOM manipulation, no usual complex operations. Unless you need a CSS+JS implementation to do a full set of highly customized dark patterns, use it.

The program has the following characteristics.

  • Pure CSS implementation, simple and efficient, forcing higher grid
  • Almost no maintenance costs, fast iteration
  • Make full use of filter effect, good compatibility

Try just as well, finished feel the effect is good to look for your boss to raise salary to 😜, ha ha!

For me, CSS is an unconstrained language, easy or difficult. If you love CSS and want to know more about pure CSS effects, you can go back to my previous articles, or browse my personal website for pure CSS effects to ensure that your eyes are satisfied.

  • Use CSS development techniques flexibly:4000 +Thumb up.110k+reading
  • Use CSS variables to make your CSS more exciting:500 +Thumb up.13k+reading

Finally, I wonder if our favorite nuggets community will adopt this csS-only skin change solution. What do you think?

conclusion

❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create more high-quality articles

Follow public accountIQ front-end, a focus on CSS/JS development skills of the front-end public number, more front-end small dry goods waiting for you oh

  • Reply after attentiondataFree access to study materials
  • Reply after attentionInto the group ofGet you into the tech community
  • Welcome to attentionIQ front-endAnd moreCSS/JS development skillsOnly in the public account push