<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3" -->

---
title: How to Build a Dark Mode Toggle Without JavaScript
description: A practical guide to implementing a dark mode toggle using only HTML and CSS, without any JavaScript. The technique leverages the CSS `:has()` pseudo-class...
canonical: https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How to Build a Dark Mode Toggle Without JavaScript | daily.dev
og:description: A practical guide to implementing a dark mode toggle using only HTML and CSS, without any JavaScript. The technique leverages the CSS `:has()` pseudo-class...
og:url: https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3
og:image: https://api.daily.dev/og/posts/nbeU3niL3.png
og:image:alt: How to Build a Dark Mode Toggle Without JavaScript
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Build a Dark Mode Toggle Without JavaScript

**[freeCodeCamp](https://daily.dev/sources/freecodecamp)** · 6 min read · 30 upvotes · 6 comments

## Summary

A practical guide to implementing a dark mode toggle using only HTML and CSS, without any JavaScript. The technique leverages the CSS `:has()` pseudo-class combined with hidden radio button inputs to detect user selection and apply theme styles. CSS variables are used to manage color tokens for light and dark themes, and the `prefers-color-scheme` media query ensures the toggle defaults to the user's system preference. The post also explains why building JavaScript-free websites benefits accessibility, SEO, and AI crawler visibility.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.freecodecamp.org/news/how-to-build-a-dark-mode-toggle-without-javascript>

## Community discussion

Top comments from developers on daily.dev.

**@allinonetools** · 1 upvotes

> **Nice write-up!** It's a great reminder that not every interactive feature needs JavaScript—less code, simpler maintenance, and a faster experience.

**@nubecolectiva** · 0 upvotes

> Thanks for the article, But I heard it's better to do it with pure CSS because of the file size?

**@devmount** · 0 upvotes

> I love the `:has()` pseudo class. It's really useful and was introduced waay to late (baseline end of 2023)!

**@jakubkordovsky** · 0 upvotes

> This is neat, but also kinda useless since you'd want to remember the user's chosen mode, so you still need JS either way to set localStorage or a cookie.

---

Tags: [#css](https://daily.dev/tags/css)

[View this post on daily.dev](https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"How to Build a Dark Mode Toggle Without JavaScript","url":"https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3"},"datePublished":"2026-07-06T17:05:46.994Z","dateModified":"2026-07-06T17:06:05.603Z","description":"A practical guide to implementing a dark mode toggle using only HTML and CSS, without any JavaScript. The technique leverages the CSS `:has()` pseudo-class...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ab4ee3deb8f177c3ab58808f5e402155?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ab4ee3deb8f177c3ab58808f5e402155?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"freeCodeCamp","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"freeCodeCamp","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1628412854/logos/freecodecamp","url":"https://daily.dev/sources/freecodecamp"},"commentCount":6,"discussionUrl":"https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":30},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":6}],"keywords":"css","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"freeCodeCamp","item":"https://daily.dev/sources/freecodecamp"},{"@type":"ListItem","position":3,"name":"How to Build a Dark Mode Toggle Without JavaScript"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/how-to-build-a-dark-mode-toggle-without-javascript-nbeu3nil3","comment":[{"@type":"Comment","text":"Nice write-up! It’s a great reminder that not every interactive feature needs JavaScript—less code, simpler maintenance, and a faster experience.","datePublished":"2026-07-08T03:15:10.340Z","url":"https://daily.dev/posts/nbeU3niL3#c-wXPJWwXek","author":{"@type":"Person","name":"AllInOneTools","url":"https://daily.dev/allinonetools","image":"https://media.daily.dev/image/upload/s--4ZT8QlF0--/f_auto/v1769790028/avatars/avatar_igzBsWloJeaegzm9bQltZ?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}},{"@type":"Comment","text":"Thanks for the article, But I heard it’s better to do it with pure CSS because of the file size?","datePublished":"2026-07-10T13:38:55.145Z","url":"https://daily.dev/posts/nbeU3niL3#c-zerfyVsZM","author":{"@type":"Person","name":"Nube Colectiva","url":"https://daily.dev/nubecolectiva","image":"https://media.daily.dev/image/upload/s--sKadI8aB--/f_auto/v1787001795/avatars/avatar_d2lQlbHPWLBIYkmIhoKKS?_a=BAMAMicg0"}},{"@type":"Comment","text":"I love the :has() pseudo class. It’s really useful and was introduced waay to late (baseline end of 2023)!","datePublished":"2026-07-09T05:19:36.291Z","url":"https://daily.dev/posts/nbeU3niL3#c-mSOHN1JBK","author":{"@type":"Person","name":"Andreas","url":"https://daily.dev/devmount","image":"https://media.daily.dev/image/upload/s--0yHQgkD3--/f_auto/v1730121566/avatars/avatar_wkPuMtV83z5WseTrVc5QU"}},{"@type":"Comment","text":"This is neat, but also kinda useless since you’d want to remember the user’s chosen mode, so you still need JS either way to set localStorage or a cookie.","datePublished":"2026-07-07T04:54:01.419Z","url":"https://daily.dev/posts/nbeU3niL3#c-ERm84VMJe","author":{"@type":"Person","name":"Jakub Kordovský","url":"https://daily.dev/jakubkordovsky","image":"https://avatars.githubusercontent.com/u/11707547?v=4"}}]}
```

