Dark mode has become a highly requested feature in modern applications, offering users a more comfortable and visually pleasing experience, particularly in low-light environments. Beyond improving user comfort, dark mode also reduces eye strain and conserves battery life on devices with OLED screens. As user expectations evolve, developers are increasingly incorporating dark mode into full-stack applications.
In this post, we will provide a comprehensive guide on how to implement dark mode within your full-stack web application, covering both front-end and back-end integration. Additionally, we will discuss strategies to ensure dark mode is customizable, persistent, and provides a seamless experience for users.
Why Implement Dark Mode?
Before delving into the implementation, it’s important to understand the value of dark mode:
- Enhanced User Experience: Many users prefer dark mode due to its ability to reduce eye strain, especially during prolonged use.
- Energy Efficiency: On OLED and AMOLED displays, dark mode can significantly reduce battery consumption, providing longer usage times.
- Accessibility: Dark mode can be beneficial for users with visual sensitivities, offering a more readable and less intense interface.
- Modern Appeal: Integrating dark mode helps position your application as modern and user-centric, which can enhance user engagement and retention.
With these benefits in mind, let’s explore the steps to effectively implement dark mode in your full-stack application.
Step 1: Design Your Dark Mode UI
Before diving into the technical implementation, it’s essential to plan the design changes needed to accommodate both light and dark modes. Key areas of focus include:
- Background Color: Use darker shades (e.g.,
#121212
) for dark mode and lighter tones (e.g.,#FFFFFF
) for light mode. - Text Color: Ensure light text (e.g.,
#FFFFFF
) for dark mode and dark text (e.g.,#000000
) for light mode for optimal contrast. - Interactive Elements: Ensure buttons, links, and other UI elements stand out appropriately in both modes.
- Images: Adjust image brightness or use alternative images that better fit the dark mode aesthetic.
While it is not necessary to redesign your entire interface, maintaining a visually harmonious and accessible experience across both themes is essential.
Step 2: Implementing Dark Mode in the Front-End
There are multiple ways to implement dark mode on the front-end, with the most common methods involving the use of CSS media queries or CSS variables. Below, we outline both approaches.
Using Media Queries
The simplest method to detect dark mode preference is by using the prefers-color-scheme
media query. This allows you to automatically apply the correct theme based on the user’s system settings.
Example:
/* Default theme (Light Mode) */
body {
background-color: #ffffff;
color: #000000;
}
/* Dark Mode */
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #ffffff;
}
}
This approach is straightforward and automatically adapts the theme based on the user’s system preferences.
Using CSS Variables
For more control over the theme and to provide a manual toggle option, you can utilize CSS variables. This allows dynamic switching between light and dark modes with a class toggle on the body
or html
element.
- Define CSS Variables:
/* Light Mode Variables */
:root {
--background-color: #ffffff;
--text-color: #000000;
--button-color: #007bff;
}
/* Dark Mode Variables */
[data-theme='dark'] {
--background-color: #121212;
--text-color: #ffffff;
--button-color: #007bff;
}
- Apply Variables to Your Styles:
body {
background-color: var(--background-color);
color: var(--text-color);
}
button {
background-color: var(--button-color);
}
- Toggle Theme with JavaScript:
javascriptCopyconst toggleButton = document.querySelector('#dark-mode-toggle');
toggleButton.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme); // Persist theme preference
});
- Persist User Theme Preference:
To ensure the theme is persistent across sessions, store the user’s preference in localStorage
and apply it upon page load.
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
}
This approach offers flexibility and customization for managing dark mode, including the option for users to toggle the theme manually.
Step 3: Implementing Dark Mode in the Back-End (Optional)
Although dark mode is primarily a front-end feature, you may wish to store the user’s theme preference on the back-end to ensure consistency across devices and sessions. This can be particularly useful for applications that require user authentication.
1. API Endpoint for Theme Preferences:
You can store the user’s theme preference in your database, allowing them to update it via an API. For example, in a MongoDB schema, you might add a theme
field to store the user’s preference.
// Example using Express.js
app.put('/api/user/theme', async (req, res) => {
const userId = req.user.id;
const { theme } = req.body;
if (['light', 'dark'].includes(theme)) {
const updatedUser = await User.findByIdAndUpdate(userId, { theme }, { new: true });
return res.json(updatedUser);
}
res.status(400).json({ error: 'Invalid theme' });
});
2. Fetch User’s Theme Preference on Login:
Upon login, you can retrieve the user’s theme preference from the database and apply it to the front-end.
// Example using React.js
useEffect(() => {
const fetchTheme = async () => {
const response = await fetch('/api/user/theme');
const data = await response.json();
const theme = data.theme || 'light';
document.documentElement.setAttribute('data-theme', theme);
};
fetchTheme();
}, []);
Step 4: Testing Dark Mode Implementation
Once you’ve implemented dark mode across both the front-end and back-end, it’s essential to thoroughly test the functionality. Consider testing the following scenarios:
- Automatic Theme Switching: Ensure the theme automatically switches based on the system preference or user settings.
- Manual Toggle: Verify that the theme toggle button correctly switches between light and dark modes.
- Persistence: Confirm that the user’s theme preference is saved and persists across sessions and devices.
- Accessibility and Contrast: Ensure that text, buttons, and interactive elements remain easily readable and accessible in both light and dark modes.
Implementing dark mode in your full-stack application provides a modern and user-centric feature that enhances the overall user experience. By following the steps outlined in this post, you can seamlessly integrate dark mode, leveraging both CSS media queries and variables to offer users a customizable and persistent theme. This not only demonstrates your commitment to accessibility and user preferences but also positions your application as contemporary and thoughtful in its design approach.
Happy coding!
At 7Shades Digital, we specialised in creating strategies that help businesses excel in the digital world. If you’re ready to take your website to the next level, contact us today!