Dark mode is not just a trend — it is a genuine accessibility and comfort feature. Over 80% of smartphone users enable dark mode on their devices, and they notice (and appreciate) when websites respect that preference. Plus, dark mode reduces eye strain at night and can save battery on OLED screens.
Squarespace does not have a dark mode toggle built in, but we can build one using CSS custom properties, a small JavaScript toggle, and system preference detection. Here is the complete walkthrough.
Step 1: Define Your Color Variables
The foundation of dark mode is CSS custom properties (variables). Instead of hardcoding colors everywhere, you define them once and swap them based on theme. Add this to Design → Custom CSS:
/* Light theme (default) */
:root {
--bg-primary: #ffffff;
--bg-secondary: #f7f6f2;
--text-primary: #1a1a1a;
--text-secondary: #555555;
--border-color: #e5e5e5;
--header-bg: rgba(255, 255, 255, 0.95);
}
/* Dark theme */
[data-theme="dark"] {
--bg-primary: #121212;
--bg-secondary: #1e1e1e;
--text-primary: #e4e4e7;
--text-secondary: #a1a1aa;
--border-color: #333333;
--header-bg: rgba(18, 18, 18, 0.95);
}Step 2: Apply the Variables
Now use these variables throughout your site. Squarespace has its own styles, so you will need !important on many of these:
/* Apply dark mode variables to site elements */
body {
background-color: var(--bg-primary) !important;
color: var(--text-primary) !important;
transition: background-color 0.3s ease, color 0.3s ease;
}
/* Header */
header#header,
.header-announcement-bar-wrapper {
background-color: var(--header-bg) !important;
}
/* Text elements */
h1, h2, h3, h4, h5, h6 {
color: var(--text-primary) !important;
}
p, li, span, a {
color: var(--text-secondary) !important;
}
/* Sections */
.page-section,
.content-wrapper {
background-color: var(--bg-primary) !important;
}
/* Alternate sections */
.page-section:nth-child(even) {
background-color: var(--bg-secondary) !important;
}
/* Cards, blocks */
.sqs-block {
background-color: var(--bg-primary) !important;
}
/* Footer */
footer {
background-color: var(--bg-secondary) !important;
}
/* Borders */
hr, .section-border {
border-color: var(--border-color) !important;
}Step 3: Add the Toggle Button and JavaScript
Paste this into Settings → Advanced → Code Injection → Footer. It creates a floating toggle button, detects the user's system preference, and remembers their choice:
<!-- Dark Mode Toggle -->
<button id="dark-mode-toggle" aria-label="Toggle dark mode" title="Toggle dark mode">
<svg class="icon-sun" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="5"/>
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
</svg>
<svg class="icon-moon" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</button>
<style>
#dark-mode-toggle {
position: fixed;
bottom: 32px;
left: 32px;
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid var(--border-color);
background: var(--bg-primary);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 998;
transition: all 0.3s ease;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
#dark-mode-toggle:hover {
transform: scale(1.1);
}
/* Show sun in dark mode, moon in light mode */
.icon-sun { display: none; }
.icon-moon { display: block; }
[data-theme="dark"] .icon-sun { display: block; }
[data-theme="dark"] .icon-moon { display: none; }
</style>
<script>
(function() {
var toggle = document.getElementById('dark-mode-toggle');
var html = document.documentElement;
// Check saved preference, then system preference
var savedTheme = localStorage.getItem('theme');
if (savedTheme) {
html.setAttribute('data-theme', savedTheme);
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
html.setAttribute('data-theme', 'dark');
}
// Toggle on click
toggle.addEventListener('click', function() {
var current = html.getAttribute('data-theme');
var next = current === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
if (!localStorage.getItem('theme')) {
html.setAttribute('data-theme', e.matches ? 'dark' : 'light');
}
});
})();
</script>How It Works
- System detection: On first visit, it checks if the user's device is set to dark mode via
prefers-color-scheme. - Manual toggle: The floating button lets visitors switch manually, overriding the system preference.
- Persistence: Their choice is saved in
localStorageso it sticks across page loads and visits. - Live system updates: If someone changes their system preference while on your site, it updates automatically (unless they have manually overridden).
Handling Images in Dark Mode
Images can look harsh on a dark background. You have a few options:
/* Slightly dim images in dark mode */
[data-theme="dark"] img {
opacity: 0.85;
transition: opacity 0.3s ease;
}
[data-theme="dark"] img:hover {
opacity: 1;
}
/* Invert logos that are dark-on-light */
[data-theme="dark"] .header-title-logo img {
filter: invert(1);
}Things to Watch Out For
Building all of this by hand is doable, but it is a lot of CSS to get right. Our Dark Mode Toggle tool generates the complete code — variables, toggle button, system detection, image handling — all customized to your color scheme. Just pick your light and dark colors, and you are done.
