Variables and theme switching
Variables and Theme Switching
CSS3 introduced custom properties (CSS Variables), making theme switching more flexible and efficient. By defining variables and modifying their values in different scenarios, dynamic theme switching can be easily achieved without the need to rewrite large amounts of style code.
Basic Usage of CSS Variables
CSS variables start with --
and are defined in the :root
pseudo-class to represent the global scope. Variables are called using the var()
function and support default values:
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
}
body {
color: var(--text-color);
background-color: var(--bg-color, #f8f9fa); /* With default value */
}
.button {
background: var(--primary-color);
}
Implementing Dynamic Theme Switching
By modifying the variable values of the root element with JavaScript, real-time theme switching can be achieved. Here is a complete example:
<!DOCTYPE html>
<html>
<head>
<style>
:root {
--bg-color: #ffffff;
--text-color: #333333;
--primary: #4285f4;
}
body {
background: var(--bg-color);
color: var(--text-color);
transition: all 0.3s ease;
}
button {
background: var(--primary);
padding: 10px 15px;
border: none;
color: white;
}
</style>
</head>
<body>
<h1>Theme Switching Demo</h1>
<button onclick="toggleTheme()">Toggle Theme</button>
<script>
const themes = {
light: {
'--bg-color': '#ffffff',
'--text-color': '#333333',
'--primary': '#4285f4'
},
dark: {
'--bg-color': '#1a1a1a',
'text-color': '#f0f0f0',
'--primary': '#0d47a1'
}
};
function toggleTheme() {
const root = document.documentElement;
const currentBg = getComputedStyle(root).getPropertyValue('--bg-color').trim();
const newTheme = currentBg === '#ffffff' ? 'dark' : 'light';
Object.entries(themes[newTheme]).forEach(([property, value]) => {
root.style.setProperty(property, value);
});
}
</script>
</body>
</html>
Multi-Theme Management System
For complex theme systems, a more structured management approach can be adopted:
/* Define base variables */
:root {
--base-font-size: 16px;
--base-spacing: 8px;
}
/* Default theme */
[data-theme="default"] {
--primary: #3498db;
--secondary: #e74c3c;
--background: #ecf0f1;
}
/* Dark theme */
[data-theme="dark"] {
--primary: #2980b9;
--secondary: #c0392b;
--background: #2c3e50;
}
/* High-contrast theme */
[data-theme="high-contrast"] {
--primary: #000000;
--secondary: #ffffff;
--background: #ffff00;
}
body {
font-size: var(--base-font-size);
padding: calc(var(--base-spacing) * 4);
background: var(--background);
}
Themes can be switched by modifying the data-theme
attribute:
function setTheme(themeName) {
document.documentElement.setAttribute('data-theme', themeName);
localStorage.setItem('theme', themeName); // Save user preference
}
// Read saved theme on initialization
const savedTheme = localStorage.getItem('theme') || 'default';
setTheme(savedTheme);
Responsive Theme Adaptation
Combined with media queries, theme switching based on system preferences can be achieved:
:root {
--primary: #3498db;
--background: #ffffff;
--text: #333333;
}
@media (prefers-color-scheme: dark) {
:root {
--primary: #2980b9;
--background: #1a1a1a;
--text: #f0f0f0;
}
}
/* Consider manually selected themes */
[data-theme="dark"] {
--primary: #2980b9;
--background: #1a1a1a;
--text: #f0f0f0;
}
[data-theme="light"] {
--primary: #3498db;
--background: #ffffff;
--text: #333333;
}
Performance Optimization for Theme Switching
- Variable Grouping: Group related variables for better maintainability
:root {
/* Color variables */
--color-primary: #3498db;
--color-secondary: #e74c3c;
/* Spacing variables */
--spacing-small: 8px;
--spacing-medium: 16px;
/* Font variables */
--font-body: 16px/1.5 'Helvetica', sans-serif;
}
- Using CSS Preprocessors: Manage variables with Sass/Less
$themes: (
light: (
bg: #fff,
text: #333,
primary: #4285f4
),
dark: (
bg: #1a1a1a,
text: #f0f0f0,
primary: #0d47a1
)
);
@mixin theme() {
@each $theme, $map in $themes {
[data-theme="#{$theme}"] & {
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get($map, $key);
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
@function themed($key) {
@return map-get($theme-map, $key);
}
body {
@include theme() {
background: themed('bg');
color: themed('text');
}
}
Animation Effects for Theme Switching
To enhance user experience, smooth transitions can be added for theme switching:
:root {
--transition-time: 0.4s;
}
body {
transition:
background-color var(--transition-time) ease,
color var(--transition-time) ease;
}
button, a {
transition:
background-color var(--transition-time) ease,
border-color var(--transition-time) ease;
}
Browser Compatibility for Theme Switching
Although modern browsers widely support CSS variables, fallback solutions should still be considered:
/* Fallback solution */
body {
background: #ffffff; /* Default value */
background: var(--bg-color, #ffffff);
}
/* Use @supports to detect support */
@supports not (--css: variables) {
body.light {
background: #ffffff;
color: #333333;
}
body.dark {
background: #1a1a1a;
color: #f0f0f0;
}
}
Theme Switching in Component Libraries
Component libraries can implement theme customization through CSS variables:
/* Component base styles */
.button {
padding: 0.5em 1em;
border-radius: 4px;
background: var(--button-bg, #eee);
color: var(--button-text, #333);
}
/* Theme customization */
:root {
--button-bg: #4285f4;
--button-text: white;
--button-hover: #3367d6;
}
[data-theme="dark"] {
--button-bg: #0d47a1;
--button-text: rgba(255,255,255,0.87);
--button-hover: #1565c0;
}
User Experience Considerations for Theme Switching
- Persisting User Preferences: Use localStorage to save user preferences
- System Preference Detection: Automatically match the user's OS theme
- Switch Control Design: Provide clear theme-switching UI
- Transition Animations: Avoid abrupt color changes
// Detect system theme changes
window.matchMedia('(prefers-color-scheme: dark)').addListener(e => {
setTheme(e.matches ? 'dark' : 'light');
});
// Initialize theme
function initTheme() {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
setTheme(savedTheme);
} else {
setTheme(prefersDark ? 'dark' : 'light');
}
}
Advanced Modes for Theme Switching
- Partial Theme Switching: Only change styles for specific areas of the page
.container[data-theme="dark"] {
--bg-color: #333;
--text-color: #fff;
}
- Dynamic Theme Generation: Allow users to customize theme colors
function createCustomTheme(primary, secondary, background) {
const root = document.documentElement;
root.style.setProperty('--primary', primary);
root.style.setProperty('--secondary', secondary);
root.style.setProperty('--background', background);
}
- Theme Mixing: Combine features of multiple themes
[data-theme="dark"] [data-component-theme="light"] {
--component-bg: #ffffff;
--component-text: #333333;
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn