How to Make Dark Mode for Websites Using Only CSS

How to Make Dark Mode for Websites Using Only CSS

Ever since it became trendy, the demand for websites, web apps, desktop software, and tools to have dark theme support is ever increasing.

Nowadays, every other website needs a dark theme, and while there are tonnes of methods to implement a new theme, one of the most interesting and less time-consuming ways for developers is to just use the power of CSS to deliver a website with dark theme support.

In this CSS-only dark mode tutorial, you will get a short introduction to variables in CSS and then you will create a super simple yet CSS-only dark theme implementation of a website section.


A short intro to CSS variables

Before we start with the dark theme implementation, we need to dive into the world of CSS variables and advanced selectors.

What are CSS variables?

CSS custom properties, or commonly known as CSS variables, are some rulesets that contain specific values to be reused throughout a document.

Just like you create variables in any other programming language, like JavaScript, so that we can use variable’s value throughout the program, in styling with CSS with large websites, we get large amounts of repeated values which we can condense into a specific set of CSS variables to inject them on the properties throughout the styling of the app wherever needed.

Let’s look at an example. If your webpage has an accent color that you know will be used in primary buttons, links, and borders of images, then instead of doing this:

.primary-btn {
  color: #88d95f;
}

img {
  border: 2px dashed #88d95f;
}

.links {
  color: #88d95f;
}
.
.
.

We can create a variable called --accent-color and give it a value of the hex code “#88d95f”. Now, we can add this new custom variable to the :root pseudo-class so that it can be accessed globally:

:root {
  --accent-color: #88d95f;
}

Now, the above code changes to this:

.primary-btn {
  color: var(--accent-color);
}

img {
  border: 2px dashed var(--accent-color);
}

.links {
  color: var(--accent-color);
}
.
.
.

One of the greatest use cases of this is that whenever we need to change the color value, we can simply change it at one place at the :root selector declaration and the result will be affected on all the elements where it was used!

Let’s create dark theme with just CSS

We will be using the recently gained knowledge of CSS variables to build a dead-simple but very effective section of a webpage. Here’s what it looks like in default or light mode:

How to Make Dark Mode for Websites Using Only CSS

And here’s what it looks like in dark theme:

How to Make Dark Mode for Websites Using Only CSS

As you can see we have the following four elements here:

1. The checkbox to enable dark theme.

2. The heading.

3. The paragraph.

4. The button (or effectively, a link).

Everything will be made with the help of CSS only and no JavaScript will be involved in this. When we click on the “Enable dark theme” checkbox, the entire webpage section should turn to the dark theme. Let’s see how to do this step by step.


Creating the HTML structure:

  • Here we start with the <input /> tag which will be of type checkbox and we give it two classes: dark-mode-checkbox and hidden.
  • After this, we need to have a container around the label for our checkbox which we give a class of checkbox-container that will contain the dark-mode-label. Don’t forget to add the id of dark-mode to the <input /> tag so that <label> also gets the same for attribute.
  • As for the actual content like the text and the button link, we make a new div for it with the wrapper class. Under this, make sure you have the heading, paragraph, and anchor tags.

If you follow all the above steps, we get the following HTML code:

<input id="dark-mode" class="dark-mode-checkbox hidden" type="checkbox">

<div class="checkbox-container">
  <label class="dark-mode-label" for="dark-mode">
    Enable dark mode
  </label>


  <div class="wrapper">
    <h1>🎥 Live video transcription</h1>
    <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fugit necessitatibus, quod perspiciatis voluptatem vero natus dolores eaque, consequatur perferendis sint ex, corrupti rerum.</p>
    <a href="#">Get started →</a>
  </div>
</div>

And on your browser it will result in this:

How to Make Dark Mode for Websites Using Only CSS

We have a lot to do here from now: the basic styling and then actually making the checkbox toggle work for dark theme.


Adding basic CSS styles:

Let’s switch to the CSS file and import the custom Montserrat font from Google Fonts:

@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap');

Now, let’s add the new font to our body tag and make it a flexbox so that our container fits perfectly on any viewport. We can also reset the margin, font-size, and line-height as required:

body {
  font-family: 'Montserrat', sans-serif;
  display: flex; 
  flex-direction: column; 
  margin: 0;
  font-size: 1.25em;
  line-height: 1.5;
}

We also make the usual adjustments to h1, .wrapper, p, and a tags without touching on the background and color properties as shown:

h1 {
  margin-top: 2rem;
}

.wrapper {
  max-width: 600px; 
  text-align: left;
} 

p {
  margin-bottom: 2.5rem;
}

a {
  text-decoration: none;
  padding: 1rem;
  border-radius: 3px;
  font-weight: bold;
}

For the checkbox itself, we can use the .hidden class to hide the default checkbox rendered by the browser. Now, we need to replace the original checkbox with the ::before pseudo-class to use the \2610 and \2611 hexadecimal Unicodes for the tick and untick. Along with this, we give some padding to the .checkbox-container:

.hidden {
  display: none;
} 

.dark-mode-label::before {
  content: "\2610";
}

.dark-mode-checkbox:checked ~ .checkbox-container .dark-mode-label::before {
  content: "\2611";
}

.checkbox-container {
  padding: 1.5rem;
 }


Implement dark theme:

For this, we first need to define all the custom variables used for the foreground and background colors needed in our elements.

  • We first define the hex color variables for light theme and then the dark theme at the :root as:
  :root {
    /* Light mode variables */
    --container-background: #FDF8F7;
    --para-light-text: #333333;
    --anchor-light-text: #FAEEEB;
    --anchor-light-bg: #A04229;
    /* Dark theme variables */
    --container-dark-text: #FDF8F7;
    --container-dark-background: #1C0C07;
    --para-dark-text: #CCCCCC;
    --anchor-dark-text: #512115;
    --anchor-dark-bg: #F5DDD6
  }
  • Next, we select the .checkbox-container element that are siblings of .dark-mode-checkbox:checked class which will match the selected checkbox state of the element. This is done by the ~ sibling selector as:
  .dark-mode-checkbox:checked ~ .checkbox-container

All the rules we set in this CSS block will act as a toggle logic of the theme from light to dark theme and vice-versa. When the checkbox is in the selected mode it will toggle the theme and when unchecked it goes back to its base styles.

  .dark-mode-checkbox:checked ~ .checkbox-container {
    --container-text: var(--container-dark-text);
    --container-background: var(--container-dark-background);
    --para-light-text: var(--para-dark-text);
    --anchor-light-bg: var(--anchor-dark-bg);
    --anchor-light-text: var(--anchor-dark-text);
  }

Basically, all we are doing here is setting the default light color theme value to the new dark theme colors for both the text and the background.

  --container-text: var(--container-dark-text);

The line above translates to: “Change the --container-text color value to the new --container-dark-textwhen the checkbox is selected (or deselected).”

  • With this, we can now fill up the colors and background values whenever needed:
  .checkbox-container {
   // Previous styles
    color: var(--container-text);
    background-color: var(--container-background);
  } 
  p {
    // Previous styles
    color: var(--para-light-text);
  }
  a {
   // Previous styles
    color: var(--anchor-light-text);
    background: var(--anchor-light-bg);
  }

With this, you get the following CSS code:

  @import url(https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap);
  :root {
    /* Light mode variables */
    --container-background: #FDF8F7;
    --para-light-text: #333333;
    --anchor-light-text: #FAEEEB;
    --anchor-light-bg: #A04229;
    /* Dark theme variables */
    --container-dark-text: #FDF8F7;
    --container-dark-background: #1C0C07;
    --para-dark-text: #CCCCCC;
    --anchor-dark-text: #512115;
    --anchor-dark-bg: #F5DDD6;
  }
  .dark-mode-checkbox:checked ~ .checkbox-container {
    /* Toggle the theme */
    --container-text: var(--container-dark-text);
    --container-background: var(--container-dark-background);
    --para-light-text: var(--para-dark-text);
    --anchor-light-bg: var(--anchor-dark-bg);
    --anchor-light-text: var(--anchor-dark-text);
  }
  body {
    font-family: 'Montserrat',sans-serif;
    display: flex;
    flex-direction: column;
    margin: 0;
    font-size: 1.25em;
    line-height: 1.5;
  }
  .checkbox-container {
    padding: 1.5rem;
    color: var(--container-text);
    background-color: var(--container-background);
  }
  /*
  * Replace original checkbox
  */
  .dark-mode-label::before {
    content: "\2610";
  }
  .dark-mode-checkbox:checked ~ .checkbox-container .dark-mode-label::before {
    content: "\2611";
  }
  /* To hide the default checkbox */
  .hidden {
    display: none;
  }
  h1 {
    margin-top: 2rem;
  }
  .wrapper {
   max-width: 600px;
   text-align: left;
  }
  p {
    margin-bottom: 2.5rem;
    color: var(--para-light-text);
  }
  a {
    text-decoration: none;
    color: var(--anchor-light-text);
    background: var(--anchor-light-bg);
    padding: 1rem;
    border-radius: 3px;
    font-weight: bold;
  }

 

And now you get the fully working dark theme with just CSS!

How to Make Dark Mode for Websites Using Only CSS


Conclusion

In this CSS dark mode tutorial, we got to know how to make a dark theme for your webpage using only CSS. Particularly, we talked about CSS variables which come really handy in such a process. We then implemented it in a short demo where we used some pseudo-classes and advanced CSS selectors to make a toggle for the light to the dark theme.

From here, you can refer to the following resources to better understand this topic:

--

If you want to stay up to date with all the new content we publish on our blog, share your email and hit the subscribe button.

Also, feel free to browse through the other sections of the blog where you can find many other amazing articles on: ProgrammingITOutsourcing, and even Management.

 

Interested in hiring talented Latin American developers to add capacity to your team? Contact Jobsity: the nearshore staff augmentation choice for U.S. companies.

Nov 23, 2021
Mauricio Lopez
Mauricio Lopez

Mauricio has been at the forefront of technology for 12 years. He is constantly integrating new technologies including frameworks, CMS, and standard industry models. He is a pragmatic problem-solver and customizes solutions based on the best schema/language/application for each project. As head of technology at Jobsity, he ensures that his team is always up to date with the latest advances in software development by researching the software ecosystem, implementing several professional development initiatives, and coordinating with new and existing clients about their needs.
He holds a BA in Business and Marketing from UTEG Ecuador

Subscribe for the updates

 

Better hires, more work, less stress. Join the Jobsity Community. Contact Us