Skip to main content

Creating day-night CSS only toggle switch

 

In this article, I'll recreate this in CSS and help you understand the elements and code you will need to do the same.

The result will look like this:

HTML Structure

<input type="checkbox" id="toggle" class="toggle--checkbox" />
<label for="toggle" class="toggle--label">
  <span class="toggle--label-background"></span>
</label>
<div class="background"></div>

Yes, that's all the HTML we need, weird right?
We will use a lot of pseudo-elements to add the little styling gimmicks.

The basic idea is that we use the label to control the checkbox, the checkbox in turn will be hidden.
But it's checked state will cause the switch effect.

We did use this effect before in this CSS Custom checkbox article.

CSS only day/night toggle switch

To create our switch we need to use quite a lot of pseudo-elements.

But let’s start with the basics.
We need to hide our checkbox, the checkbox is only used to toggle our styling.

The label will be the one visible and toggling the checkbox

We use ‘display: none’ to hide our checkbox

.toggle--checkbox {
  display: none;
}

Once that is out of the way let’s use CSS grid to center everything in our body.

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  position: relative;
}

I'm using CSS variables for this tutorial, just for the colours, here is the variable declaration:

:root {
  /** sunny side **/
  --blue-background: #c2e9f6;
  --blue-border: #72cce3;
  --blue-color: #96dcee;
  --yellow-background: #fffaa8;
  --yellow-border: #f5eb71;
  /** dark side **/
  --indigo-background: #808fc7;
  --indigo-border: #5d6baa;
  --indigo-color: #6b7abb;
  --gray-border: #e8e8ea;
  --gray-dots: #e8e8ea;
  /** general **/
  --white: #fff;
}

Then, we should move to the label styling as you see in the end result this is about twice the size of our sun and moon element.

We also add a transition so it will animate with ease. In this case, the animation will be the background and border color.

.toggle--label {
  width: 200px;
  height: 100px;
  background: var(--blue-color);
  border-radius: 100px;
  border: 5px solid var(--blue-border);
  display: flex;
  position: relative;
  transition: all 350ms ease-in;
}

This code will result in the following.

Let’s add our first pseudo-element the sun icon.
It is an absolute position element and has a fixed width and height.

.toggle--label:before {
  animation-name: reverse;
  animation-duration: 350ms;
  animation-fill-mode: forwards;
  transition: all 350ms ease-in;
  content: '';
  width: 82px;
  height: 82px;
  border: 5px solid var(--yellow-border);
  top: 4px;
  left: 4px;
  position: absolute;
  border-radius: 82px;
  background: var(--yellow-background);
}

Note: don’t use border-radius: 50% since we want to expand the width of this element.

Now we should see the following result.

We also add a custom animation called reverse, this animation takes 350ms to complete and the fill-mode is set to ‘forwards’ which means it will stop at the last frame.

This animation is as follows:

@keyframes reverse {
  0% {
    left: 104px;
    width: 82px;
  }
  60% {
    left: 72px;
    width: 112px;
  }
  100% {
    left: 4px;
  }
}

What happens, is that we start on our initial value, and then 60% of the time (350ms) we modify the left position and width.
Then from 60-100%, we change the position to 4px.
This gives us a neat grow and move effect.

We also see the main background div it’s used for the full color and is absolutely positioned in our body.

The only thing that will change there is the background color.

.background {
  position: absolute;
  left: 0;
  top: 0;
  background: var(--blue-background);
  z-index: -1;
  width: 100%;
  height: 100%;
  transition: all 250ms ease-in;
}

Adding the cloud detail

You might have also noted the white cloud in the sun switch, we will animate this to transform into the stars so it’s based on three elements.

The main element is the span background inside the label. This in turn has a before and after pseudo-element.

The main span is relatively positioned on the right-hand side, it has a transition that takes 150ms so it’s faster than our main toggle.

.toggle--label-background {
  width: 10px;
  height: 5px;
  border-radius: 5px;
  position: relative;
  background: var(--white);
  left: 135px;
  top: 45px;
  transition: all 150ms ease-in;
}

This alone results in the following:

The before and after are absolute positioned elements that resemble the top and bottom part of the cloud.

.toggle--label-background:before {
  content: '';
  position: absolute;
  top: -5px;
  width: 40px;
  height: 5px;
  border-radius: 5px;
  background: var(--white);
  left: -20px;
  transition: all 150ms ease-in;
}
.toggle--label-background:after {
  content: '';
  position: absolute;
  top: 5px;
  width: 40px;
  height: 5px;
  border-radius: 5px;
  background: var(--white);
  left: -10px;
  transition: all 150ms ease-in;
}

With those, we get the simplistic looking cloud.

CSS changing styling based on checked class

Now that we have our default sunny side of the toggle let’s go ahead and see how to make it switch to the nighttime mode.

There is a really cool feature where you can detect a checkbox checked state and then target the next element.

The code works as follows

.toggle--checkbox:checked + element {
  // Element can be after our checkbox
}

Knowing that we will start with the background.

.toggle--checkbox:checked ~ .background {
  background: var(--indigo-background);
}

Now if we click our label the background will change.

So knowing this works we can go ahead and use this principle for our label.

I’ve said we only need to change the background and border so the CSS is as follows

.toggle--checkbox:checked + .toggle--label {
  background: var(--indigo-color);
  border-color: var(--indigo-border);
}

And this result in the following

Let’s continue and change our sun into a moon, this has the same idea a change of background and border is enough, but we want to reverse the animation so we add another custom animation to this one.

.toggle--checkbox:checked + .toggle--label:before {
  background: var(--white);
  border-color: var(--gray-border);
  animation-name: switch;
  animation-duration: 350ms;
  animation-fill-mode: forwards;
}

The animation is the same as the "reverse" one, but from left to right.

@keyframes switch {
  0% {
    left: 4px;
  }
  60% {
    left: 4px;
    width: 112px;
  }
  100% {
    left: 104px;
    width: 82px;
  }
}

Then for the moon, we need to add another after to show some dimples.

.toggle--label:after {
  transition-delay: 0ms;
  transition: all 250ms ease-in;
  position: absolute;
  content: '';
  box-shadow: var(--gray-dots) -13px 0 0 2px, var(--gray-dots) -24px 14px 0 -2px;
  left: 143px;
  top: 23px;
  width: 10px;
  height: 10px;
  background: transparent;
  border-radius: 50%;
  opacity: 0;
}

This has an opacity of 0 and once it’s checked we will show it.
You also see we use a box-shadow to actually create this effect.
What this does is create two circles positioned left from the actual element.

Then once we clicked the CSS will need to change the opacity

.toggle--checkbox:checked + .toggle--label:after {
  transition-delay: 350ms;
  opacity: 1;
}

I think these little dimples make a big difference, wouldn't you agree?

The last part is that we want to move our cloud and turn it into the three stars.

We move the positions around and make them a bit smaller.

.toggle--checkbox:checked + .toggle--label .toggle--label-background {
  left: 60px;
  width: 5px;
}
.toggle--checkbox:checked + .toggle--label .toggle--label-background:before {
  width: 5px;
  height: 5px;
  top: -25px;
}
.toggle--checkbox:checked + .toggle--label .toggle--label-background:after {
  width: 5px;
  height: 5px;
  left: -30px;
  top: 20px;
}

That gives us the following end result, have a play on this Codepen.

Thank you for reading

Comments

Popular posts from this blog

Coronavirus phishing lures continue to dominate threat landscape

Overall cybercrime activity isn't necessarily going up amid COVID-19, experts say. However, coronavirus-themed emails are becoming the dominant form of phishing attacks.  The good news is, overall cybercrime isn't necessarily going up significantly amid the COVID-19 pandemic, experts say. The bad news is, coronavirus phishing attacks have become a dominant -- and effective -- threat. "PhishLabs is not seeing a significant change in attack volumes. What PhishLabs has seen is that COVID-19 has become part of the lure, part of the social engineering mechanism of phishing attacks," PhishLabs founder and CTO John LaCour said. "We're seeing malware attacks, we're seeing credential phishing attacks, we're seeing advance fee fraud/ 419 scams , we're seeing ransomware, we're seeing all of those things that we see from time to time where attackers are leveraging coronavirus as part of the lure, part of the scam." LaCour said the type of sca

A quarter of users will fall for basic phishing attacks

Slightly more than a quarter of people will fall for a phishing scam that claims to be an urgent message prompting them to change a password, according to statistics gathered by cyber security testing and training firm KnowBe4 , which specialises in phishing simulations. While the statistics might be read as a positive indicator that end-users are awake to the importance of password protection and basic cyber security hygiene , KnowBe4 founder and CEO Sty Sjouwerman said it actually showed the need for users to be even more cautious. “It is easy to see how they fall for phishing scam related to changing or checking their passwords,” said Sjouwerman. “As identifying phishing attacks from legitimate emails becomes trickier, it is more important than ever for end-users to look for the red flags and think before they click.” KnowBe4 studied tens of thousands of email subject lines both from simulated phishing tests and those found in the wild, and found many of the most-clicke

10 best Content Management Systems of the year

The significant benefits of using a CMS are that such software is often user-friendly. These programs enable users to translate their ideas to practicality quickly. The maintenance and updates are regular and easy to handle. It is highly cost-efficient with out-of-box solutions, freeware or open-source. There is a broad scope for functionality using a large number of extensions and plugins. There is a great developer and community support as well. A Content Management System refers to a software application that can be used for creating and modification of digital content. CMS is generally used for web content management and enterprise content management. ECM (Enterprise Content Management) supports multiple users in a collaborative environment by integrating digital asset management, document management and record retention. Whereas, WCM (Web Content Management) is a collaborative authoring of websites and can include graphics, photos, audio, videos, programmes and maps that