Overview
This article explains how to automatically switch light and dark modes for any custom HTML In-app template. You can use this approach for any HTML structure, ensuring that you can adapt your own In-app message templates to respect the user's system color scheme preference.
To make your custom HTML template automatically switch between light and dark modes based on the user's system settings, you can use CSS media queries. This lightweight approach ensures your In-app message adapts seamlessly to the user’s preferences. The key CSS tools you’ll use are the prefers-color-scheme
media query and the color-scheme
property.
-
The
prefers-color-scheme
media query: This CSS feature detects whether the user’s system is set to light or dark mode. You can use the media query to apply different styles depending on the system setting to deliver a polished and user-friendly In-app message experience. The media query works in modern browsers and webviews, ensuring compatibility with In-app messages. -
The
color-scheme
property: This property instructs the browser that your template supports both light and dark modes, which can improve how certain elements (like form controls) are rendered.
With these tools, your template will dynamically adjust its appearance based on the user’s system preference, improving usability and accessibility.
Steps to Implement
Step 1: Start with Your Custom HTML Template
Use your existing HTML code as the foundation. You don’t need separate files for light and dark modes. The CSS will handle the switching within a single template. For more information on In-app HTML templates, refer to HTML In-App Templates and Sample HTML In-app Templates.
Step 2: Structure Your CSS for Light and Dark Modes
Organize your CSS to define styles for both light and dark modes:
- Define base styles: These are the default styles that apply when no specific color scheme is detected or when the user’s system is in the light mode. Typically, these will be your light mode styles. Include styles for all key elements in your template, such as backgrounds, text, buttons, and containers.
-
Add dark mode styles with media queries: To override or add styles specifically for dark mode, use the
@media (prefers-color-scheme: dark)
query. These styles will be activated when the user’s system is set to dark mode.
Here’s an example of how to structure your CSS:
/* Base styles (default for light mode) */
body {
background-color: #ffffff; /* White background */
color: #000000; /* Black text */
}
.container {
background-color: #f0f0f0; /* Light gray container */
}
button {
background-color: #007bff; /* Blue button */
color: #ffffff; /* White text */
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
body {
background-color: #121212; /* Dark background */
color: #ffffff; /* White text */
}
.container {
background-color: #333333; /* Dark gray container */
}
button {
background-color: #ffffff; /* White button */
color: #000000; /* Black text */
}
}
Some Key Points
In the code above:
- Base styles: These apply by default and should cover all elements in your template for the light mode.
- Dark mode styles: The media query adjusts styles for the dark mode, ensuring a smooth transition when the user’s preference changes.
- Flexibility: Adapt the class names (for example, container and button) and properties to match your template’s structure.
Step 3: Use the color-scheme Property
Add the color-scheme
property to the root of your CSS to signal that your template supports both modes:
css
:root {
color-scheme: light dark;
}
Doing so will:
- Help the browser understand that your content is ready for both light and dark modes.
- Automatically adjusts native elements (For example, form inputs, scrollbars) to match the user’s preference.
Include this at the top of your CSS file.
Step 4: Customize Styles for Your Template’s Elements
Since your HTML template is unique, identify the elements that need to adapt to the color scheme. Common elements of style include:
- Backgrounds: Body, sections, modals, or other containers.
- Text: Headings, paragraphs, links, or labels.
- Interactive elements: Buttons, forms, or navigation items.
- Overlays: Modal backdrops or pop-ups.
For each element, follow the steps below:
- In the base styles (light mode), use colors that work well with a light background (for example, dark text on light backgrounds).
- In the dark mode media query, adjust colors for dark backgrounds (for example, light text on dark backgrounds).
If your template uses a CSS framework (for example, Bootstrap), you may need to override framework-specific classes in the dark mode media query. For example:
css
/* Light mode default */
.bg-custom {
background-color: #e9ecef;
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.bg-custom {
background-color: #444444;
}
}
Step 5. Link the CSS to Your HTML
Ensure your CSS is linked to your HTML file in the <head> section:
<link rel="stylesheet" href="path/to/your/custom.css">
If your template already uses other stylesheets, place your custom CSS after them to allow your styles to take precedence.
Step 6. Test Your Implementation
Test your template in both modes to ensure it works as expected:
-
Light mode: Set your system to light mode and check that the base styles are applied correctly.
-
Dark mode: Switch to dark mode and verify that the media query styles override the base styles appropriately.
For more information, refer to Test Your In-App Campaign.
Example
Here’s an example template to show how this might look with a custom HTML structure:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Lunar - Free Bootstrap Modal and Popups</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://campaign-assets-pp.moengage.com/html-template2/assets/bootstrap/css/bootstrap.min.css">
<!-- Lunar CSS -->
<link rel="stylesheet" href="https://campaign-assets-pp.moengage.com/html-template2/assets/css/lunar.css">
<!-- Fonts -->
<link rel="stylesheet" href="https://campaign-assets-pp.moengage.com/html-template2/assets/css/animate.min.css">
<link href="https://fonts.googleapis.com/css?family=Work+Sans:600" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Overpass:300,400,600,700,800,900" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="https://campaign-assets-pp.moengage.com/html-template2/assets/img/lunar.png" />
<link rel="icon" href="https://campaign-assets-pp.moengage.com/html-template2/assets/img/lunar.png" type="image/png" sizes="16x16">
<!-- Custom CSS for light and dark mode -->
<style>
:root {
color-scheme: light dark;
}
/* Base styles for light mode */
body {
background-color: #ffffff;
color: #000000;
}
.modal-content {
background-color: #ffffff;
}
.modal-body {
color: #000000;
}
.text-muted {
color: #6c757d !important;
}
.btn-cstm-dark {
background-color: #343a40;
color: #ffffff;
}
.btn-cstm-dark:hover {
background-color: #23272b;
}
.modal-backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #ffffff;
}
.modal-content {
background-color: #1e1e1e;
}
.modal-body {
color: #ffffff;
}
.text-muted {
color: #a9a9a9 !important; /* Lighter gray for muted text */
}
.btn-cstm-dark {
background-color: #ffffff;
color: #000000;
}
.btn-cstm-dark:hover {
background-color: #e0e0e0;
}
.modal-backdrop {
background-color: rgba(255, 255, 255, 0.2);
}
/* Adjust image for dark mode if needed */
img {
filter: brightness(0.8); /* Optional: slightly dim image for dark mode */
}
}
</style>
</head>
<body class="modal-open">
<!-- Modal -->
<div class="modal show" id="demoModal" tabindex="-1" role="dialog" aria-labelledby="demoModal" aria-hidden="true" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<button type="button" id="close-btn" class="close close-btn light" data-dismiss="modal" onclick="moengage.trackDismiss('close-btn'); moengage.dismissMessage()" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<div class="py-5 text-center rounded-top" style="background-color: #3E4676; background-size: 10px; background-repeat: repeat-x; background-position: 0 100.1%;">
<img src="https://campaign-assets-pp.moengage.com/html-template2/assets/img/onboard.svg" alt="Welcome Image">
</div>
<div class="modal-body">
<div class="text-center">
<h3 class="pt-3">Welcome On Board</h3>
<p class="text-muted">
Ready to discover what's possible?
</p>
<a href="#" id="get started cta" class="btn btn-cstm-dark btn-cta" data-dismiss="modal" aria-label="Close" onclick="moengage.openRichLanding('https://www.moengage.com'); moengage.trackClick('get started cta'); moengage.dismissMessage()">Get Started</a>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Ends -->
<div id="image"></div>
<script src="https://campaign-assets-pp.moengage.com/html-template2/assets/js/jquery.min.js"></script>
<script src="https://campaign-assets-pp.moengage.com/html-template2/assets/js/popper.min.js"></script>
<script src="https://campaign-assets-pp.moengage.com/html-template2/assets/bootstrap/js/bootstrap.min.js"></script>
<script src="https://campaign-assets-pp.moengage.com/html-template2/assets/js/lunar.js"></script>
<div class="modal-backdrop show"></div>
</body>
</html>
In this example:
- The base styles define a light theme.
- The dark mode media query adjusts the styles for a dark theme.
Additional Considerations
Handling Images and Icons
If your template includes images or icons that don’t look good in both modes (for example, a dark icon on a dark background):
- Provide alternative versions for each mode and swap them using CSS.
- Use a CSS filter to adjust visibility.
css
@media (prefers-color-scheme: dark) {
.custom-icon {
filter: invert(1); /* Inverts the icon color */
}
}
Ensuring Accessibility
Check that your color choices provide sufficient contrast in both modes and verify readability with external tools.
Framework-Specific Adjustments
If your template uses a CSS framework, override any framework classes that don’t adapt automatically. Identify these classes in your HTML and adjust them in the dark mode media query as needed.