Dark mode toggle animation using CSS !
Tags: webdev, css, javascript, tutorial
Published: 2021-06-18 06:36:03

This tutorial will mainly focus on how to use transitions in CSS and make a toggle button for light as well as dark mode using little JavaScript. Let's dive into the world of transitions!

##HTML

HTML Markup is pretty simple to understand. All you have to do is to make a container for the icons that we are going to use from [fontawesome](https://fontawesome.com/v5.15/icons/sun?style=solid) and nest the respective `div`s containing the icons inside the container.

```html
<div class="container">
   <div class="sun sun-logo">
      <i class="fas fa-sun"></i>
   </div>
   <div class="moon moon-logo">
      <i class="fas fa-moon"></i>
   </div>
</div>
```

##CSS

```css
.container{
    position: relative;
}

.sun, .moon{
    font-size: 10rem;
    width: fit-content;
    height: fit-content;
}

.moon{
    position: absolute;
    inset: 0;
}
```

Set the container position to be `relative` and the moon container position to be `absolute` because we will position the moon icon in the same position as that of the sun icon.

Here's the interesting part. Instead of using `top: 0;` `bottom: 0;` `left: 0;` and `right: 0;` you can use `inset: 0;` to get the same result. It works!

Also, set the `height` and `width` of the sun and the moon container to `fit-content`. What this will do is, it will set the height and width of the container to match the height and width of the content inside it.

And, in order to change the size of the fontawesome icon, just change the `font-size` of the icon.


```css
.moon-logo{
    opacity: 0;
    transform: translateY(20%) rotateZ(50deg);
}
```

Next, we will set up the initial position of the moon icon and its initial opacity when the webpage is rendered for the first time. Here, as the opacity of the moon icon is zero, only the sun icon will be visible to us.

The `translateY(20%)` declaration will offset the moon icon down along the Y-axis by 20% of the height of it's parent element.

Similarly, the `rotateZ(50deg)` declaration will rotate the moon icon along the Z-axis by 50 degrees.

```css
.sun-logo{
    opacity: 1;
    transform: translateY(0) rotateZ(0deg);
}
```
In the same way, we will set the initial properties for the sun icon.

```css
.animate-sun{
    opacity: 0;
    transform: translateY(20%) rotateZ(100deg);
    color: aliceblue;
}
```
Now, we will set the final properties of the sun icon to which it will transition into.

```css
.animate-moon{
    opacity: 1;
    transform: translateY(0%) rotateZ(0deg);
    color: aliceblue;
}
```
Also, we will set the final properties of the moon icon to which it will transition into. One thing to note here is the default color of the icons is `black`, so if you want to change the color of the icon, then define its `color` property.

But wait, we haven't used the `transition` property yet, so how will it transition from one state to another? Yeah, that's the only thing left to do in CSS part.

```css
.moon-logo{
    opacity: 0;
    transform: translateY(20%) rotateZ(50deg);
    transition: all 1s ease-out;
}
.sun-logo{
    opacity: 1;
    transform: translateY(0) rotateZ(0deg);
    transition: all 1s ease-out;
}
```

```css
body{
    transition: background-color 1s;
}

.dark{
    background-color: black;
}
```
We will use the above class to change the `background-color` of the `body` when the transition of the icons will happen.

That's it. Your CSS part is ready.

Now, let's move on to the JavaScript part. We will use JavaScript to `toggle` the classes on `click` event.

##JavaScript

```javascript
document.querySelector(".container").addEventListener("click", () => {
    document.querySelector(".sun-logo").classList.toggle("animate-sun");
    document.querySelector(".moon-logo").classList.toggle("animate-moon");
    document.querySelector("body").classList.toggle("dark");
})
```
Here, we have added an `eventListener` to the container element so that when we click on the container, it will toggle the CSS classes for respective elements.
Which means that, if the CSS class is not present in the `classList` of an element, `toggle` function will add the CSS class to the `classList` of the respective element.

And, if the CSS class is already present in the `classList` of the element, it will remove it.

The `classList` is actually a `DOMTokenList` but we will not go into the specifics of it.

This is it. Here's the final output.

![Final Output GIF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67x2v5x0txm0kznor5at.gif)

{% codepen https://codepen.io/seekertruth/pen/LYWaoyQ %}