Night and Day switch using css variables
UI Development

Night and Day switch using CSS variables

 

Introduction

Nowadays, most of the websites and apps are switching to dark mode as giving the users a way to customize the interface according to their preference is a huge win for the user experience. The user might want a reduced brightness during the night or otherwise during the day and having an option to do that is always a great thing. In this blog, we are going to provide the user with a switch to toggle between the night mode and day mode and we will also try to change the modes according to the hour of the day.

Before we get started, let’s first go through what css variables are.

CSS Variables

CSS variables (also known as CSS custom properties or cascading variables) are entities that contain specific values that can be reused throughout a document. They are set using custom property notation (i.e., prefixed with ‘’ for eg, –property-name) and contains a value(–property-name: value) .

The var() function is used to define the variables which can take two arguments as can be seen from the below syntax:

var( <custom-property-name> , <declaration-value>)

The custom-property-name is any user defined name (and is case sensitive) for the variable which must start with ‘–’ (double dash) and contains the value.

The declaration-value is optional argument and is the fallback value in case the custom property name doesn’t work or is invalid. If the declaration-value is not given then css variables inherit their value from their parent.  For more information on CSS variables, you can also read on MDN.

As we have gone through the basics of css variables, let’s move on to the code.

Adding the CSS variables

We will start by adding the default mode (the Day mode is the default mode here) in the css variables. We will add them directly to our html element as we want to avail our variables globally. The selector that we use defines the scope for that variable. A common best practice is to define the css variables on the :root pseudo-class, as it matches with the root element in the document tree, which is generally the <html> tag so that it can be applied globally across the whole document.

html {
--bg: #fff;
--bg-panel: #ebebeb;
--bg-img: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("/images/day.jpg");
--btn-color: #fff;
--btn-hover-color: #a5a5a5;
--color-text: #333333;
--color-text-secondary: #ddd;
--transition-body: all 1000ms !important;
--transition-body-delay: 0 !important;
}

Next, we will add our night mode variables using data attribute as, if you want to store some extra information on the same element which doesn’t necessarily have any visual representation then we can make use of the data attribute for that (you can use any attribute name and prefix it with ‘data-’ and it becomes a data attribute). We can just change this attribute through the javascript and it changes the value of the properties used in it, everywhere in the document (we will see that in a while).

html[data-theme="night"] {
--bg: #333333;
--bg-panel: #434343;
--bg-img: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("/images/image1.jpg");
--btn-color: #000;
--btn-hover-color: #555;
--color-text: #B5B5B5;
--color-text-secondary: #333333;
--transition-body: all 1000ms !important;
--transition-body-delay: 0 !important;
}

Now, the css variables declared can be referenced throughout our css file, as shown.

body {
background-color: var(--bg);
color: var(--color-text);
margin: 0;
transition: var(--transition-body);
transition-delay: var(--transition-body-delay);
}

/* just a simple container */
.container {
border-radius: 15px;
background-color: var(--bg-panel);
display: grid;
margin: 3em;
padding: 5em;
padding-left: 15px;
padding-right: 15px;
}

/* the header part that contains the logo and the switch */
.header {
background-color: var(--bg-panel);
overflow: hidden;
transition: var(--transition-body);
transition-delay: var(--transition-body-delay);
}

/* for the heading on the top of the hero image banner */
.heading {
color: var(--color-text-secondary);
font-size: 40px;
transition: var(--transition-body);
transition-delay: var(--transition-body-delay);
}

/* for the paragraph used */
.para {
    color: var(--color-text-secondary);
    transition: var(--transition-body);
    transition-delay: var(--transition-body-delay);
}

Adding the day-night toggle switch

Next, we will add the toggle day-night switch which is basically just a checkbox and when checked/unchecked (toggled) it will change the classes accordingly. We have also added few styles to our toggle switch.

HTML part:

<input type="checkbox" id="toggle_checkbox">
<label for="toggle_checkbox" class="active">
<div id="star">
<div class="star" id="star-1">?</div>
<div class="star" id="star-2">?</div>
</div>
<div id="moon"></div>
</label>

CSS part:

#toggle_checkbox {
display: none;
}

/* overall toggle switch */
label {
background-color: #03a9f4;
border-radius: 56px;
cursor: pointer;
display: block;
height: 33px;
left: 75%;
margin: 0 auto;
overflow: hidden;
position: absolute;
right: 0;
top: 5%;
transform: translateY(-50%);
transition: 0.3s ease background-color;
width: 88px;
}

/* below is a normal circle */
#star {
background-color: #fff;
border-radius: 50%;
height: 6px;
left: 14px;
position: absolute;
transform: scale(1);
transition: 0.3s ease top, 0.3s ease left, 0.3s ease transform, 0.3s ease background-color;
top: 10px;
width: 6px;
z-index: 1;
}

/* below is first unicode star */
#star-1 {
position: relative;
}

/* below is second unicode star rotated a little */
#star-2 {
position: absolute;
transform: rotateZ(36deg);
}

/*below is to determine the size for the unicode stars */
.star {
color: #fff;
font-size: 28px;
left: -8px;
line-height: 13px;
top: 0;
transition: 0.3s ease color;
}

/* changes the moon*/
#moon {
background-color: #fff;
border-radius: 50%;
bottom: -20px;
height: 16px;
position: absolute;
right: 8px;
transition: 0.3s ease bottom;
width: 18px;
}

Adding the Javascript

Finally, we will add the javascript to tie the day and night theme together. I have used jQuery framework in my javascript.

Here we will add the click event for the checkbox, when the click event is fired we verify the toggle. If checked, we will add the ‘night’ value to the data-theme attribute from css, and if its unchecked the ‘day’ value gets added to the data-theme  attribute (which is the default mode ).

$(document).ready(function () {
    $('#toggle_checkbox').click(function () {

        if (this.checked) {
            $('html').attr('data-theme', 'night');
            $(this).prop("checked", true);
        } else {
            $('html').attr('data-theme', 'day');
            $(this).prop("checked", false);
        }
    })
})

 

That’s it and we are good to go with our own Day-night switch for a simple page.

The next part is optional and can be added to improve the user experience. Here, we will use the getDate() method which gets the time and change the theme based on the time.

var date = new Date();
    var hours = date.getHours();

    if (hours > 18 || hours < 6) {
        $('html').attr('data-theme', 'night');
        $('#toggle_checkbox').prop("checked", true);

    } else {
        $('html').attr('data-theme', 'day');
        $('#toggle_checkbox').prop("checked", false);
    }

By using the getHours() method, we are getting the hour of the day and according to the hours we are changing the theme (same way as mentioned above). If the value of the hour is greater than 18 (6 PM) or less 6 (6 AM) then we are making the “night” as the default mode otherwise the “day” mode is the default mode. We have also changed the default value of the checkbox based on the hour of the day by using the prop method.

Note: The time doesn’t get changed dynamically but if the page is refreshed.

That’s all and we are done with our own day-night theme switch with the use of css variables.

I have also deployed the page on firebase. You can view the page that I have created by using the following link:

https://day-night-switch.web.app/

Conclusion

We can choose our own theme as we desire for the page or also can create our own palette to be used as the theme . Just pick out two contrast colors and use the darker shade as the background color and the lighter shade as font color when in dark mode and vice versa.

To conclude with, I will also mention few of the advantages of using css variables: 

  1. Many websites use a large amount of CSS in their codes, and very often, a lot of values are repeated. For an instance, the same color might be used many times and at many places. If we want to change that colour at all the places then it will become a huge complicated task. While with CSS variables we can store a value in one place, and then it can be referenced in multiple other places wherever we desire. And changing all the values will only require to change the value of the css variable used.
  2. CSS variables provide Re-usability.
  3. For semantic purposes also css variables are a lot handy. As any part of the code is much better understood if it is mentioned as ‘–background-color’ rather than ‘#333333’ or ‘#00ff00’.

About The Author