Skip to main content Accessibility Feedback

Automatic night mode with vanilla JS

Today, I live-coded an automatic night mode feature using vanilla JS (video and text write-up below).

For this project, I want to detect the time where the user is located, and display a time-aware greeting and color palette. Let’s dig in.

The template

My starting HTML looks like this.

<p id="greeting"></p>

Inside the empty #greeting element, I want to display a customized greeting, like, “Good morning” or “Good afternoon”, based on the time of day where the visitor is.

I also want to update the UI at night, and in the morning/evening.

.night body {
	background-color: #001f3f;
	color: white;
}

.transitional body {
	background-color: #f7f7f7;
}

I have a .night class that uses a midnight blue color for the background instead of default white. For the morning and evening, I have a .transitional class that makes the background gray to be a bit more gentle on the eyes.

You can download the source code on GitHub.

Watch me code this project

If you want, you can follow along while I figure this one out in real time. If you’re rather read about it, keep scrolling.

How it works

For this project, the first thing I did was use the new Date() constructor to get a Date object for the current user and their location. Then, I used the getHours() method to get the hour of the day.

The getHours() method returns the hour portion of the time as an integer, in 24-hour format.

This means that for 10am, it would return 10, and for 10pm it would return 22. This is really handy for what we’re trying to do.

// Get the time right now
var now = new Date().getHours();

I also used the querySelector() method to get the #greeting element.

// Get the #greeting element
var greeting = document.querySelector('#greeting');

Displaying a greeting

Now, let’s display a greeting based on the time of day.

I creating a getGreeting() function that will return the greeting as a string. I’ll set the textContent of my greeting element to whatever it returns.

/**
 * Get the greeting based on time
 * @return {String} The greeting
 */
var getGreeting = function () {
	// Code goes here...
};

// Set the greeting
greeting.textContent = getGreeting();

Inside the getGreeting() function, I check to see what now is. If it’s bigger than 20 (8pm), I return Good night!. If it’s bigger than 17 (5pm), I return Good evening!. And so on.

Because I use return, once we find a match, nothing else in the function runs. If no match is found, Good morning! is returned.

/**
 * Get the greeting based on time
 * @return {String} The greeting
 */
var getGreeting = function () {
	if (now > 20) return 'Good night!';     // If it's after 8pm
	if (now > 17) return 'Good evening!';   // If it's after 5pm
	if (now > 11) return 'Good afternoon!'; // If it's after noon
	return 'Good morning!';                 // Default message
};

Updating the color palette

Next, I want to update the color palette based on the time. I created an adjustColorMode() helper function, and run it when the page loads.

/**
 * Adjust the color theme based on time
 */
var adjustColorMode = function () {
	// Code goes here...
};

// Update color palette
adjustColorMode();

If now is greater than 20 (8pm), I want to add the .night class. I used the classList.add() method for that. Then I ran return so the rest of the function would not run.

If now is greater than 17 or less than 11 (if it’s after 5pm or earlier than 11am), I added the .transitional class instead.

/**
 * Adjust the color theme based on time
 */
var adjustColorMode = function () {

	// If it's nighttime, go dark mode
	if (now > 20) {
		document.documentElement.classList.add('night');
		return;
	}

	// If it's morning or evening, go transitional
	if (now > 17 || now < 11) {
		document.documentElement.classList.add('transitional');
	}

};

Updating throughout the day

If someone visits the site and stays there for a while, I want to periodically check the time and adjust the greeting and them as needed.

To do that, I first moved injecting the greeting and adjusting the color palette into a function, updateUI(), which I run when the page loads.

/**
 * Add a greeting and adjust the color palette
 */
var updateUI = function () {

	// Set the greeting
	greeting.textContent = getGreeting();

	// Update color palette
	adjustColorMode();

};

Then, I setup a setInterval() method to run every 15 minutes. In it, I update the now variable to the current time, then I run the updateUI() function again.

// Update the UI on page load
updateUI();

// Check again every 15 minutes
setInterval(function () {
	now = new Date().getHours();
	updateUI();
}, 1000 * 60 * 15);

Finally, I need to remove any existing .transitional or .night classes before trying to update the color palette.

/**
 * Adjust the color theme based on time
 */
var adjustColorMode = function () {

	// Remove any existing classes
	document.documentElement.classList.remove('transitional');
	document.documentElement.classList.remove('night');


	// If it's nighttime, go dark mode
	if (now > 20) {
		document.documentElement.classList.add('night');
		return;
	}

	// If it's morning or evening, go transitional
	if (now > 17 || now < 11) {
		document.documentElement.classList.add('transitional');
	}

};

And now, I have a time aware, automatically updating UI.