Compositional Variables in Design Systems
Compositional variables are an advanced form of design tokens that encapsulate higher-order relationships between multiple individual variables (e.g., spacing, typography, colors, breakpoints). Instead of defining isolated properties like color-primary or font-size-lg, compositional variables represent reusable combinations, calculated outcomes, or adaptive rules that are context-aware. These variables extend the foundational concepts of design tokens to enable more sophisticated, dynamic, and efficient design systems.
Key Features of Compositional Variables:
1. Dynamic Context Awareness:
Compositional variables adapt based on user context, viewport size, theme, or state. For example:
--button-padding: calc(var(--spacing-sm) + var(--spacing-xs));
--card-shadow: var(--shadow-base, 0px 4px 6px rgba(0,0,0,0.1));
2. Relationships Between Variables:
They allow for dependency and composition between base tokens to create meaningful abstractions. For instance, instead of hardcoding paddings for buttons, a compositional variable might define it as:
--button-padding: clamp(8px, 2vw, 16px);
3. Adaptability to States and Themes:
They incorporate state-specific or theme-based logic. For example, a compositional color variable:
--button-bg: var(--color-primary-light, #f0f0f0);
4. Encapsulation of System Logic:
Compositional variables encapsulate logic for dynamic resizing, responsive design, and interaction states, reducing redundancy. Example:
--modal-max-width: min(90vw, 600px);
5. Behavioral Rules:
They can define transitions, animations, or responsive behaviors:
--hover-elevation: translateY(-2px);
--animation-duration: calc(0.1s + var(--base-animation-speed, 0.2s));
Examples of Compositional Variables:
1. Spacing:
--form-field-spacing: calc(var(--spacing-sm) * 2);
--content-spacing: clamp(16px, 4vw, 32px);
2. Typography:
--heading-font-size: calc(var(--base-font-size) * 1.5);
--responsive-font-size: clamp(1rem, 2vw, 2rem);
3. Color Palettes:
--button-primary-bg: var(--color-brand-500);
--button-primary-bg-hover: var(--color-brand-600);
--button-secondary-border: var(--color-gray-300);
4. Layout Adaptation:
--grid-gap: calc(var(--spacing-md) * 1.5);
--card-width: clamp(280px, 50%, 400px);
5. Interactive States:
--focus-ring-color: var(--color-primary-light);
--hover-scale-factor: 1.02;
Benefits of Compositional Variables in Design Systems:
1. Scalability:
By combining and abstracting tokens, compositional variables simplify scaling design systems across platforms, breakpoints, and themes.
2. Maintainability:
Centralized definitions reduce redundancy and make updates consistent. Adjusting a single base token can cascade updates across dependent variables.
3. Improved Consistency:
They ensure consistent application of complex rules (e.g., responsive typography or adaptive spacing).
4. Enhanced Flexibility:
Adaptable by nature, compositional variables make design systems more responsive to user needs, devices, and interactions.
5. Efficiency for Designers and Developers:
Designers can work with higher-order components while developers use pre-defined logic, reducing communication overhead and increasing speed of implementation.
6. Facilitating Theming:
Complex themes can be implemented efficiently with minimal duplication:
--button-primary-bg: var(--theme-color-primary);
Implementation Example: Button Component:
:root {
--spacing-sm: 8px;
--spacing-md: 16px;
--color-primary: #007bff;
--color-primary-hover: #0056b3;
--button-padding: calc(var(--spacing-sm) * 1.5);
--button-font-size: clamp(14px, 1.2vw, 18px);
--button-bg: var(--color-primary);
--button-bg-hover: var(--color-primary-hover);
}
.button {
padding: var(--button-padding);
font-size: var(--button-font-size);
background-color: var(--button-bg);
transition: background-color 0.3s ease, transform 0.2s ease;
}
.button:hover {
background-color: var(--button-bg-hover);
transform: translateY(-2px);
}
Conclusion:
Compositional variables elevate design systems by building relationships between tokens and encapsulating contextual rules. This approach promotes scalability, adaptability, and consistency while reducing redundancy, making them a useful tool for modern, high-performing design systems.