Day/Night CSS with JavaScript
Created 24th of February, 2026. Updated 26th of February, 2026.
My friend coffeebug (midifreak.online) made a post on her neocities profile talking about how having "times of day" on her website would be cool, but lamenting never being able to implement it.
If you reading this visited my site around February 2025, you might know that I had a theme selector. I still have the files from that iteration, so I was able to adapt it to make this cool idea a reality. Some things to know about this:
- This implementation requires some knowledge of element manipulation via JavaScript.
- There is a test of this code at the top of the page. It seems to work fine, but your mileage may vary.
- This is probably not the most optimal way of doing this...
The JavaScript Code
If you think you're pro enough, here is the full JavaScript.
let date = new Date();
const tz = "America/Chicago"; // CST
// Pick one Hour variable and delete the other two!
let localHour = date.getHours();
let UTCHour = date.getUTCHours();
let tzHour = new Intl.DateTimeFormat("en-US", {hour: "numeric", hour12: false, timeZone: tz}).format(date);
const themeLink = document.GetElementById("theme");
// Do not touch this.
let themeUrl = "";
// Replace x with whatever Hour variable you're using above.
switch (true) {
case (x <= 05 || x >= 19):
themeUrl = "/night.css";
break;
case (x == 06 || x == 18):
themeUrl = "/twilight.css";
break;
case (x >= 07 && x <= 17): // You can also replace this with just default:
themeUrl = "/day.css";
}
themeLink.href = themeUrl;
Now if you don't know what the hell any of that meant, let me break it down for you (starts beatboxing).
Let's look at grabbing the time first:
let date = new Date();
const tz = "America/Chicago"; // CST
let localHour = date.getHours();
let UTCHour = date.getUTCHours();
let tzHour = new Intl.DateTimeFormat("en-US", {hour: "numeric", hour12: false, timeZone: tz}).format(date);
So first, we create an instance of the Date() object. We only want the hour from this, so we can use either .getHours(), .getUTCHours(), or Intl.DateTimeFormat().
.getHours() just takes the hours reported from Date(). This will be the time reported by the visitor's browser, which is usually the computer's set time.
.getUTCHours() ignores the visitor's timezone and just reports the universal time.
Intl.DateTimeFormat() is the most complex, since it is technically its own object. Let's break down what parameters we've set above:
"en-US" sets the locale. I'm not sure if other locales have any effects on the outputted hour.
{hour: "numeric", hour12: false, makes it so that we only get the hour from this object, in 24-hour format.
timeZone: tz} uses the tz constant above, which must be set to a timezone formatted like "America/Chicago".
We only need one of these, not all three, so pick whatever suits your needs.
You should know, however, that the range output by each method is from 00 to 23, where 00 to 11 is 12 AM to 11 AM, and 12 to 23 is 12 PM to 11 PM.
Now we need to make sure it knows where to change the stylesheet. We have two lines for this:
const themeLink = document.getElementById("theme");
let themeUrl = "";
The line document.getElementById("theme") finds an element with the theme id, which should be a <link rel="stylesheet" href=""/> element in <head>.
let themeUrl = "" is set to an empty string here so that, should something break, there won't be any CSS loaded. You can either leave the href empty or add a default file.
Now we need to determine what CSS file to load based on what time it is. You could do this with a block of if... else statements, but the switch expression looks much neater to me:
switch (true) {
case (x <= 05 || x >= 19):
themeUrl = "/night.css";
break;
case (x == 06 || x == 18):
themeUrl = "/twilight.css";
break;
case (x >= 07 && x <= 17):
themeUrl = "/day.css";
}
First, switch (true) will check for when a case returns true. We have three cases, and they're simply comparing the current hour (represented with x here) with a range of hours.
(x <= 05 || x >= 19) returns true if it is either 5 AM and earlier, or 7 PM and later.
case (x == 06 || x == 18) returns true if it is either exactly 6 AM, or 6 PM.
And finally, (x >= 07 && x <= 17) returns true if it is 7 AM or later, and 5 PM or earlier.
(You could get away with having that last case just be default, since the other cases will always return false. This is just for the sake of explanation.)
Each case (besides the last) has two statements.
themeUrl = "/theme.css"; sets the themeUrl variable we made earlier to the corresponding file.
break; ends the switch expression, much like using return in a function, and we do this to prevent running other cases. You only need this for each case besides the last.
Now we have to actually set the theme, which we do with this last line:
themeLink.href = themeUrl;
This just sets the href attribute of our <link> element to be whatever file we declared in the cases above.
A Live Example
At the top of this page, there is an example of HTML being affected by CSS that is selected by the JS code here. Each sample here has comments added to it. Here is the HTML code:
<head>
...
<link rel="stylesheet" id="timed_theme" href=""/> <!-- If the JS fails to load, the element below won't be styled at all. -->
<script src="./test.js" defer></script> <!-- Defer means that the script won't run until the HTML is parsed. -->
</head>
<body>
...
<!-- The CSS will style the HTML parent element, and the JS will add what time of day it is to the content of this element. -->
<!-- You could also add text content with the CSS itself, but using the JS to do it can be useful if the CSS breaks. -->
<p id="js_test">
Where you are, it is currently: <!-- There is a space at the end of this sentence. -->
</p>
</body>
Here is the daytime CSS:
html {
border-image: fill 0 linear-gradient(to bottom,
/* These first two RGB values are equivalent to var(--nx-yellow) in this site's root.css. */
rgba(255, 198, 56, 0.25) 0%,
rgba(255, 198, 56, 0.0125) 10%,
rgba(0, 0, 0, 0) 11%,
rgba(0, 0, 0, 0) 100%);
}
And just for demonstration, here is the JS:
let date = new Date();
let hour = date.getHours();
const themeLink = document.getElementById("timed_theme");
const testString = document.getElementById("js_test");
let themeUrl = "";
let dayString = "";
// If you right click the site, there should be a button
// to Inspect Element, and you can access the console there.
// This and every other console.log call will show up there. Try it now!
console.log("Hour is: " + hour);
switch (true) {
case (hour <= 05 || hour >= 19):
themeUrl = "./night.css";
dayString = "night time.";
console.log("Night time.");
break;
case (hour == 06 || hour == 18):
themeUrl = "./twilight.css";
dayString = "twilight.";
console.log("Twilight time."); // Not to be confused with the song.
break;
case (hour >= 07 && hour <= 17):
themeUrl = "./day.css";
dayString = "day time.";
console.log("Day time.");
}
themeLink.href = themeUrl;
testString.append(dayString);
If you went through the previous section, then you probably will already know what the HTML and CSS, and by now the JS code, does here.
The HTML has the <link> element that is targeted by the JS file linked in the <script> element to load the stylesheet.
Each CSS file that gets loaded targets the <html> element for styling.
The JS also targets the <p> element with id js_test and adds text to it.
Like in my example above, the stylesheet ideally should affect very little!
The CSS in this example forms a yellow gradient overlay at the top of the website, kind of like a sunrise on the horizon, but you could always do much more!
For example, you could have different background images, logos. With more advanced CSS and JS, you could make the website itself look like its getting sleepy!
And you can always add different ranges of time. Above, it's broken into three parts, but you could break it into five:
switch (true) {
case (hour <= 04 || hour >= 20):
themeUrl = "./night.css";
dayString = "night time.";
console.log("Night time.");
break;
case (hour >= 05 && hour <= 07):
themeUrl = "./sunrise.css";
dayString = "morning.";
console.log("Morning.");
break;
case (hour >= 08 && hour <= 12):
themeUrl = "./day.css";
dayString = "day time.";
console.log("Day time.");
break;
case (hour >= 13 && hour <= 16):
themeUrl = "./afternoon.css";
dayString = "afternoon.";
console.log("Afternoon.");
break;
case (hour >= 17 && hour <= 19):
themeUrl = "./sunset.css";
dayString = "evening.";
console.log("Evening.");
}