Lately I've noticed that a lot of apps now have a dark mode that kicks in automatically when the system switches over. Then I found out websites can do the same thing, so I spent an afternoon setting up a dark mode for this site.
CSS offers a clean way to make colors change along with the system settings. The @media rule handles media queries, letting us apply different styles based on a device's characteristics and parameters. Under @media, prefers-color-scheme can detect the user's system theme preference. It accepts three values: no-preference, light, and dark.
According to the MDN docs, no-preference means the browser's host system doesn't support theme color settings, or it does but nothing is set by default and the user hasn't specified a preference.
First, let's create a test page:

Light mode example
Here's the CSS part:
.card{
top: 40%;
margin: auto;
box-shadow: 0px 8px 60px -10px rgba(13,28,39,0.6);
padding: 8px 10px 6px;
background: rgba(255,255,255,.596078431372549);
border-radius: 25px;
position: relative;
text-align: center;
}
p{
color: #000;
font-size: 2em;
}
.bg{
background-image: url(https://cdn.vinking.top/bg.jpg);
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100vh;
background-size: cover;
opacity: .4;
filter: blur(8px);
}
In dark mode, we want the text to turn white, the card background to become transparent black, and the background image to switch to a darker one with its opacity bumped up a bit. To pull off these style changes, we can use the @media (prefers-color-scheme: dark) media query together with the :root pseudo-class selector, rewriting the CSS like this:
/*Light mode*/
:root {
--p_color:#000;
--bg_img:url(https://cdn.vinking.top/bg.jpg);
--card_bg:rgba(255,255,255,.596078431372549);
--bg_op:.4;
}
/*Dark mode*/
@media (prefers-color-scheme: dark){
:root {
--p_color:#fff;
--bg_img:url(https://cdn.vinking.top/iVQRxPEjsx1xw7d.jpg);
--card_bg:rgba(0,0,0,.4);
--bg_op:.9;
}
}
.card{
top: 40%;
margin: auto;
box-shadow: 0px 8px 60px -10px rgba(13,28,39,0.6);
padding: 8px 10px 6px;
background: var(--card_bg);
border-radius: 25px;
position: relative;
text-align: center;
}
p{
color: var(--p_color);
font-size: 2em;
}
.bg{
background-image: var(--bg_img);
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100vh;
background-size: cover;
opacity: var(--bg_op);
filter: blur(8px);
}
When the user switches their system to dark mode, the page updates automatically too.

Dark mode example
One last thing to keep in mind: some browsers don't support prefers-color-scheme. You can check which ones do here