Switching Themes Based on the Current Month


Recently, I’ve been experimenting with Javascript Date objects. I wanted to see if I could dynamically change the theme of a webpage, based on the current date.

For example, if it was October, the spookiest month of the year, I could have an orange, purple and black theme to remind them of Halloween.

Let’s try implementing this.

Create a New Date Object

The MDN web docs describes a Javascript Date object as:

“…[an] instance that represents a single moment in time in a platform-independent format. Date objects contain a Number that represents milliseconds since 1 January 1970 UTC.”

A new date object can be created with new Date(). The value of a date object will look something like this.

Sat Oct 17 2020 22:56:11 GMT-0400 (Eastern Daylight Time)

That’s a lot of information we can play around with.

Methods for Date Objects

While it looks like a string, keep in mind that the date is an object, not a string. Running console.log(typeof new Date()); would return false.

Luckily, the date prototype comes with built-in methods. These methods allow us to focus on specific parts of the date object.

For this example, I want to focus on the current month. Instead of converting the value of the date object to a string, comparing it to calendar months (October, November, etc), we can use the getMonth() method.
getMonth() returns an integer, that corresponds to the months of the year. The months of the year are zero index, so January would be 0, February 1 and so on.

Let’s see what it returns given the new Date() referenced above.

let now = new Date() // Sat Oct 17 2020 22:56:11 GMT-0400 (Eastern Daylight Time)
now.getMonth() // 9

It is currently October 17th. October is the 10th month of the year and since January would return 0 this is returning what we need.

Theme Names

Now that I know the current month, I can use it to influence changes in the CSS. I’ll use a switch case to change the value of a themeToAdd variable that I’ll later apply to the body tag.

My switch case looks something like this.

let now = new Date() // Sat Oct 17 2020 22:56:11 GMT-0400 (Eastern Daylight Time)
now.getMonth() // 9

// Placeholder for theme name that we'll add later
let themeToAdd = ""

// Evaluates the current, zero-indexed month based off of the now date object

switch(now.getMonth()) { 
    case 9:
       themeToAdd = "dark-and-spooky" 
    break; 
    default: 
       themeToAdd = "dark"
}

The logic goes something like this.

  • If the current month is October, apply the dark-and-spooky theme.
  • If the current month is not October, apply the dark theme

A bonus to having a default case is that if a date object cannot be created, we have a fallback style.

Speaking of styles, let’s set up the CSS variables for our default, dark and dark-and-spooky themes.

:root { 
--background-color: #efefef;
--font-color: #444444; 
...
}

body[data-theme="dark"] { 
--background-color: #032b43; 
--font-color: #efefef;
...}

body[data-theme="dark-and-spooky"] {
--background-color: #010101;
--font-color: #BA4A00;
...
}

...

body {
background-color: var(--background-color); 
color: var(--font-color);
...}

Changing the Theme

Now that we know which month is it, and have a theme name, and the styles set, it’s time to implement it.

Borrowing from the data attribute demo from a few months ago, we’ll implement the theme as a checkbox.

Given an HTML file that looks like this:

<html>
    <head>
    ...
    </head>
    <body>
        <label>
            Dark Mode?
            <input type="checkbox">
        </label>
    ...
    </body>
</html>

With Javascript we can target the checkbox and wait for it to be checked. If it’s checked during the month of October, implement the dark-and-spooky data attribute. Otherwise, add dark. And, if either theme is already a set attribute on the `body` tag (it was already checked), remove the data-theme attribute entirely and show the default theme.

...
let checkbox = document.querySelector("input")
    let body = document.querySelector("body")
    
    checkbox.addEventListener('change', (event) => {
        event.target.checked ? body.setAttribute('data-theme', themeToAdd) : body.removeAttribute("data-theme")
    });

Putting everything together, we have something that looks like this.

See the Pen Switching Theme Based on the Current Month by Shannon Crabill (@scrabill) on CodePen.

Note that you’ll see specific styles of the current month is October, February, or December.

Time Travel is Fun

If you enable the checkbox during the month of October, and see a dark background with orange text, it’s working!

But, you may be wondering how you can test to see if your themes are working without waiting for the right month or resetting your computer’s clock.

What’s powerful about the date constructor is that is can take in optional parameters.

If a valid date value is passed into new Date() it “…returns a Date object whose component values (year, month, day, hour, minute, second, and millisecond) all come from the [given] parameters”.

So, if we wanted to test if a lovey-dovey theme would work in the month of February, we can create a new date object for testing, like this.

let now = new Date('February 2020') // Sat Feb 01 2020 00:00:00 GMT-0500 (Eastern Standard Time)

now.getMonth() // 1

Resources


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.