
Documentation
Webflow
Code
Setup: External Scripts
External Scripts in Webflow
Make sure to always put the External Scripts before the Javascript step of the resource.
In this video you learn where to put these in your Webflow project? Or how to include a paid GSAP Club plugin in your project?
HTML
<script src="https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js"></script>
Step 1: Copy structure to Webflow
Copy structure to Webflow
In the video below we described how you can copy + paste the structure of this resource to your Webflow project.
Copy to Webflow
Webflow structure is not required for this resource.
Step 1: Add HTML
HTML
<button data-theme-toggle="" class="btn-darklight">
<div class="btn-darklight__icon">
<div class="btn-darklight__icon-box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewbox="0 0 24 24" fill="none"><path d="M15.5355 8.46447C17.4882 10.4171 17.4882 13.5829 15.5355 15.5355C13.5829 17.4882 10.4171 17.4882 8.46447 15.5355C6.51184 13.5829 6.51184 10.4171 8.46447 8.46447C10.4171 6.51184 13.5829 6.51184 15.5355 8.46447Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 4V2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22V20" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M18.3599 5.63999L19.0699 4.92999" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M4.93018 19.07L5.64018 18.36" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M20 12H22" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2 12H4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M18.3599 18.36L19.0699 19.07" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M4.93018 4.92999L5.64018 5.63999" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
</div>
<div class="btn-darklight__icon-box is--absolute">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewbox="0 0 24 24" fill="none"><path d="M18.395 13.027C18.725 12.872 19.077 13.197 18.985 13.55C18.671 14.752 18.054 15.896 17.104 16.846C14.283 19.667 9.77001 19.726 7.02201 16.978C4.27401 14.23 4.33401 9.71601 7.15501 6.89501C8.10501 5.94501 9.24801 5.32801 10.451 5.01401C10.804 4.92201 11.128 5.27401 10.974 5.60401C9.97201 7.74301 10.301 10.305 11.998 12.002C13.694 13.7 16.256 14.029 18.395 13.027Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
</div>
</div>
<div class="btn-darklight__word">
<p class="btn-darklight__word-p">Light</p>
<p class="btn-darklight__word-p is--absolute">Dark</p>
</div>
<p class="btn-darklight__word-p">mode</p>
</button>
HTML structure is not required for this resource.
Step 2: Add CSS
CSS
.btn-darklight {
color: #131313;
cursor: pointer;
background-color: #efeeec;
border: 0 solid transparent;
border-radius: .25em;
outline: 0 transparent;
justify-content: center;
align-items: center;
padding: 0 1.125em 0 .75em;
display: flex;
position: relative;
overflow: hidden;
}
.btn-darklight__icon {
width: 1.25em;
height: 100%;
margin-right: .25em;
position: relative;
}
.btn-darklight__word {
padding-right: .25em;
position: relative;
}
.btn-darklight__word-p {
margin-top: .05em;
margin-bottom: 0;
line-height: 1.2;
position: relative;
}
.btn-darklight__word-p.is--absolute {
opacity: 0;
letter-spacing: .025em;
position: absolute;
top: 0;
}
.btn-darklight__icon-box {
height: 100%;
padding-top: .66em;
padding-bottom: .66em;
display: flex;
position: relative;
}
.btn-darklight__icon-box.is--absolute {
position: absolute;
}
/* Background */
[data-theme-status] {
transition: background-color 0.4s cubic-bezier(0.35, 1, 0.6, 1);
}
[data-theme-status="dark"] {
background-color: #070915 !important;
}
/* Button Word */
[data-theme-status="dark"] .btn-darklight .btn-darklight__word .btn-darklight__word-p,
[data-theme-status="light"] .btn-darklight .btn-darklight__word .btn-darklight__word-p.is--absolute{
opacity: 0;
}
[data-theme-status="light"] .btn-darklight .btn-darklight__word .btn-darklight__word-p,
[data-theme-status="dark"] .btn-darklight .btn-darklight__word .btn-darklight__word-p.is--absolute {
opacity: 1;
}
/* Button Icon */
.btn-darklight .btn-darklight__icon-box{
transition: transform 0.8s cubic-bezier(0.35, 1.5, 0.6, 1);
transform: translateY(0%) rotate(-90deg);
}
[data-theme-status="dark"] .btn-darklight .btn-darklight__icon-box{
transform: translateY(-100%) rotate(0.001deg);
}
Step 2: Add custom Javascript
Custom Javascript in Webflow
In this video, Ilja gives you some guidance about using JavaScript in Webflow:
Step 2: Add Javascript
Step 3: Add Javascript
Javascript
function initCookieDarkLight() {
// Function to toggle theme
function initThemeCheck() {
// Get the element that has [data-dash-theme] attribute
const dashThemeElement = document.querySelector('[data-theme-status]');
if (!dashThemeElement) return;
// Toggle between light/dark
const currentTheme = dashThemeElement.getAttribute('data-theme-status');
const newTheme = (currentTheme === 'light') ? 'dark' : 'light';
dashThemeElement.setAttribute('data-theme-status', newTheme);
Cookies.set('theme', newTheme, { expires: 365 });
}
// Keydown to toggle theme when Shift + T is pressed
document.addEventListener('keydown', function(e) {
const tagName = e.target.tagName.toLowerCase();
if (tagName === 'input' || tagName === 'textarea' || e.target.isContentEditable) {
return; // Do nothing if typing into a field
}
if (e.shiftKey && e.keyCode === 84) { // Shift+T
e.preventDefault();
initThemeCheck();
}
});
// For all elements with [data-theme-toggle], add click handler
document.querySelectorAll('[data-theme-toggle]').forEach(function(button) {
button.addEventListener('click', initThemeCheck);
});
// If theme cookie is 'dark', set theme to dark
if (Cookies.get('theme') === 'dark') {
const themeElement = document.querySelector('[data-theme-status]');
if (themeElement) {
themeElement.setAttribute('data-theme-status', 'dark');
}
}
}
// Initialize Cookie Dark/Light Theme
document.addEventListener('DOMContentLoaded', function() {
initCookieDarkLight();
});
Step 3: Add custom CSS
Step 2: Add custom CSS
Custom CSS in Webflow
Curious about where to put custom CSS in Webflow? Ilja explains it in the below video:
CSS
/* Background */
[data-theme-status] {
transition: background-color 0.4s cubic-bezier(0.35, 1, 0.6, 1);
}
[data-theme-status="dark"] {
background-color: #070915 !important;
}
/* Button Word */
[data-theme-status="dark"] .btn-darklight .btn-darklight__word .btn-darklight__word-p,
[data-theme-status="light"] .btn-darklight .btn-darklight__word .btn-darklight__word-p.is--absolute{
opacity: 0;
}
[data-theme-status="light"] .btn-darklight .btn-darklight__word .btn-darklight__word-p,
[data-theme-status="dark"] .btn-darklight .btn-darklight__word .btn-darklight__word-p.is--absolute {
opacity: 1;
}
/* Button Icon */
.btn-darklight .btn-darklight__icon-box{
transition: transform 0.8s cubic-bezier(0.35, 1.5, 0.6, 1);
transform: translateY(0%) rotate(-90deg);
}
[data-theme-status="dark"] .btn-darklight .btn-darklight__icon-box{
transform: translateY(-100%) rotate(0.001deg);
}
Implementation
Attributes
- Add
[data-theme-status="light"]
to the<body>
, used to style the elements on the page. - Use
[data-theme-toggle]
to toggle between theme (light & dark).
Example Structure
For both Webflow and Code
<body data-theme-status="light">
<button data-theme-toggle>Change theme</button>
</body>
Animating
[data-theme-status="dark"] {
background-color: var(--color-dark);
color: var(--color-light);
}
Cookie
We store the user’s theme preference in a cookie, ensuring the chosen theme remains consistent across page loads and future visits. In fact, you can store any type of preference this way—such as filter settings, grid or list views, font sizes, and more.
More information
Read more about the Cookie library: JS-Cookie Documentation
Variant: Using localStorage
An alternative way to save a user's preference that does not require a 3rd party library like JS-Cookie, is using the localStorage API. This will also persist and save even if the website or window is closed. To utilise this, you of course don't need the CDN link, and then you need to replace 2 things in the JS.
In your theme toggle function:
// Replace:
Cookies.set('theme', newTheme, { expires: 365 });
// With:
localStorage.setItem('theme', newTheme);
In your theme initialization, replace:
// Replace:
if (Cookies.get('theme') === 'dark') {
// With:
if (localStorage.getItem('theme') === 'dark') {
Resource Details
Last updated
February 17, 2025
Type
The Vault
Category
Utilities & Scripts
Need help?
Join Slack