10.1 Nested Variables and Functions
To achieve more complex and dynamic styles, you can use combinations of CSS variables and functions along with advanced techniques like nested variables, dynamically changing values through JavaScript, and complex gradients. Let's explore some more intricate examples and techniques.
1. Nested Variables and Functions
In this example, nested variables are used to create dynamically adjustable element sizes:
:root {
--base-size: 16px;
--scale-factor: 1.5;
--scaled-size: calc(var(--base-size) * var(--scale-factor));
}
.container {
font-size: var(--scaled-size);
padding: calc(var(--scaled-size) / 2);
margin: calc(var(--scaled-size) / 4);
}
2. Theming with Dynamic Hue Changes
Creating themes using hsl() and dynamically changing hues with CSS variables and JavaScript.
Clicking the button changes the --base-hue value, which dynamically alters the background color:
:root {
--base-hue: 200;
--saturation: 70%;
--lightness: 50%;
--primary-color: hsl(var(--base-hue), var(--saturation), var(--lightness));
}
body {
background-color: var(--primary-color);
transition: background-color 0.3s;
}
<button id="change-color">Change Color</button>
// Get the element with id "change-color"
document.getElementById('change-color').addEventListener('click', () => {
// Get the root element of the document (HTML)
const root = document.documentElement;
// Generate a random number between 0 and 359 for the color hue in HSL format
const newHue = Math.floor(Math.random() * 360);
// Set a new value for the custom CSS variable --base-hue
// This variable is probably used in styles to determine the primary color
root.style.setProperty('--base-hue', newHue);
});
10.2 Complex Gradients
3. Complex Multilevel Gradients
In this example, a multilevel linear gradient is used to create complex backgrounds with multiple color stops:
:root {
--color-stop1: hsla(200, 100%, 50%, 0.8);
--color-stop2: hsla(340, 100%, 50%, 0.8);
--color-stop3: hsla(120, 100%, 50%, 0.8);
--color-stop4: hsla(60, 100%, 50%, 0.8);
}
.complex-gradient {
background: linear-gradient(
45deg,
var(--color-stop1) 25%,
var(--color-stop2) 25%,
var(--color-stop2) 50%,
var(--color-stop3) 50%,
var(--color-stop3) 75%,
var(--color-stop4) 75%
);
}
4. Creating Dynamic Adaptive Components
Using CSS variables and functions to create adaptive components that change their properties depending on screen size and other factors.
An adaptive component changes its padding and background color based on screen size:
<div class="dynamic-component">Dynamic Component</div>
:root {
--base-padding: 20px;
--scale-factor: 1.5;
--dynamic-padding: calc(var(--base-padding) * var(--scale-factor));
}
@media (max-width: 600px) {
:root {
--scale-factor: 1;
}
}
.dynamic-component {
padding: var(--dynamic-padding);
background-color: hsl(calc(100 + var(--scale-factor) * 50), 100%, 50%);
}
5. Generating Gradients Using JavaScript and CSS Variables
Dynamically creating gradients based on data obtained via JavaScript.
Upon clicking the button, new colors and an angle for the gradient are generated randomly:
:root {
--color1: hsl(200, 100%, 50%);
--color2: hsl(340, 100%, 50%);
--angle: 45deg;
}
.dynamic-gradient {
background: linear-gradient(var(--angle), var(--color1), var(--color2));
}
<button id="generate-gradient">Generate Gradient</button>
<div class="dynamic-gradient">Content</div>
// Get the element with id "generate-gradient"
document.getElementById('generate-gradient').addEventListener('click', () => {
// Get the root element of the document (HTML)
const root = document.documentElement;
// Generate two random colors in HSL format with maximum saturation and medium brightness
const newColor1 = `hsl(${Math.floor(Math.random() * 360)}, 100%, 50%)`;
const newColor2 = `hsl(${Math.floor(Math.random() * 360)}, 100%, 50%)`;
// Generate a random angle for the gradient
const newAngle = `${Math.floor(Math.random() * 360)}deg`;
// Set new values for the custom CSS variables
root.style.setProperty('--color1', newColor1);
root.style.setProperty('--color2', newColor2);
root.style.setProperty('--angle', newAngle);
});
10.3 Using CSS Variables for Dynamic Themes
Example 1: Dynamic Theme Switching with CSS Variables and JavaScript
Create a dynamic theme system where CSS variables are changed based on the selected theme:
:root {
--background-color: #ffffff;
--text-color: #000000;
--primary-color: #3498db;
--secondary-color: #2ecc71;
}
body {
background-color: var(--background-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
.container {
padding: 20px;
}
button {
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: var(--secondary-color);
}
.content {
margin-top: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Theme Switching</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<button onclick="switchTheme()">Switch Theme</button>
<div class="content">
<h1>Title</h1>
<p>Example text for dynamic theme switching.</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
// Define theme object
const themes = {
light: {
// Colors for light theme
'--background-color': '#ffffff', // Background color
'--text-color': '#000000', // Text color
'--primary-color': '#3498db', // Primary color
'--secondary-color': '#2ecc71' // Secondary color
},
dark: {
// Colors for dark theme
'--background-color': '#2c3e50', // Background color
'--text-color': '#ecf0f1', // Text color
'--primary-color': '#e74c3c', // Primary color
'--secondary-color': '#8e44ad' // Secondary color
}
};
// Currently selected theme
let currentTheme = 'light';
// Function to switch theme
function switchTheme() {
// Invert the value of currentTheme (light -> dark, dark -> light)
currentTheme = currentTheme === 'light' ? 'dark' : 'light';
// Get the color object for the current theme
const theme = themes[currentTheme];
// Loop over all key-value pairs in the theme object
for (let [variable, value] of Object.entries(theme)) {
// Set the CSS variable to the corresponding value from the theme
document.documentElement.style.setProperty(variable, value);
}
}
Example 2: Responsive Design Using calc(), min(), max(), and clamp() for Font Sizes and Padding
Create a responsive layout with flexible font sizes and padding that adapt based on the viewport width:
:root {
--base-font-size: 16px;
--base-padding: 10px;
--min-font-size: 14px;
--max-font-size: 24px;
--preferred-font-size: 2vw;
--min-padding: 8px;
--max-padding: 20px;
--preferred-padding: 1.5vw;
}
body {
font-size: clamp(var(--min-font-size), var(--preferred-font-size), var(--max-font-size));
padding: clamp(var(--min-padding), var(--preferred-padding), var(--max-padding));
transition: font-size 0.3s, padding 0.3s;
}
.responsive-container {
margin: 0 auto;
max-width: 800px;
padding: calc(var(--base-padding) * 2);
text-align: center;
}
h1 {
font-size: clamp(calc(var(--base-font-size) * 1.5), 3vw, 36px);
}
p {
font-size: clamp(var(--base-font-size), 2vw, 24px);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Design with Dynamic Sizes</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="responsive-container">
<h1>Responsive Title</h1>
<p>This text adapts to the viewport size, changing font sizes and padding accordingly.</p>
</div>
</body>
</html>
GO TO FULL VERSION