Interpolation
Overview
Interpolation in Styleframe uses the css
template literal utility to create dynamic CSS values with full type safety and auto-complete. This powerful feature allows you to combine static CSS strings with variables, calculations, and complex expressions while maintaining the benefits of Styleframe's TypeScript support.
Why use interpolation?
Interpolation helps you:
- Create dynamic CSS values: Build flexible properties that adapt based on variables, conditions, or calculations.
- Maintain type safety: Get auto-complete and compile-time validation even within template literals.
- Compose complex values: Combine multiple variables and expressions into sophisticated CSS declarations.
- Generate clean output: Let Styleframe handle the proper formatting and optimization of interpolated values.
Basic Interpolation
You use interpolation with the css
template literal function:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, selector } = s;
const spacing = variable('spacing--md', '1rem');
selector('.button', {
padding: css`${ref(spacing)} calc(${ref(spacing)} * 2)`,
});
export default s;
:root {
--color--primary: #006cff;
--spacing--md: 1rem;
}
.button {
background-color: var(--color--primary);
padding: var(--spacing--md) calc(var(--spacing--md) * 2);
border: 2px solid var(--color--primary);
}
The css
template literal allows you to interpolate variables and expressions directly into CSS values while maintaining proper syntax and type safety.
css
template literal whenever you need to combine multiple values or create complex CSS expressions that involve variables.Variable Interpolation
Interpolate variables seamlessly within CSS values:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, selector } = s;
const fontSize = variable('font-size--base', '16px');
const lineHeight = variable('line-height--normal', '1.5');
const fontFamily = variable('font-family--sans', 'system-ui, sans-serif');
selector('.text', {
font: css`${ref(fontSize)}/${ref(lineHeight)} ${ref(fontFamily)}`,
textShadow: css`1px 1px 2px rgba(0, 0, 0, 0.1), 0 0 1em ${ref(fontSize)}`,
});
export default s;
:root {
--font-size--base: 16px;
--line-height--normal: 1.5;
--font-family--sans: system-ui, sans-serif;
}
.text {
font: var(--font-size--base)/var(--line-height--normal) var(--font-family--sans);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1), 0 0 1em var(--font-size--base);
}
Examples
Gradient and Color Interpolation
Build complex gradients and color schemes with interpolated values:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, selector } = s;
const primaryColor = variable('color--primary', '#006cff');
const secondaryColor = variable('color--secondary', '#ff6b6b');
const accentColor = variable('color--accent', '#4ecdc4');
selector('.gradient-bg', {
background: css`linear-gradient(135deg, ${ref(primaryColor)} 0%, ${ref(secondaryColor)} 50%, ${ref(accentColor)} 100%)`,
boxShadow: css`0 10px 20px rgba(0, 0, 0, 0.1), 0 0 0 1px ${ref(primaryColor)}`,
});
selector('.color-scheme', {
color: ref(primaryColor),
borderColor: css`color-mix(in srgb, ${ref(primaryColor)} 50%, ${ref(secondaryColor)})`,
backgroundColor: css`oklch(from ${ref(primaryColor)} calc(l + 0.4) c h / 0.1)`,
});
export default s;
:root {
--color--primary: #006cff;
--color--secondary: #ff6b6b;
--color--accent: #4ecdc4;
}
.gradient-bg {
background: linear-gradient(135deg, var(--color--primary) 0%, var(--color--secondary) 50%, var(--color--accent) 100%);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 0 0 1px var(--color--primary);
}
.color-scheme {
color: var(--color--primary);
border-color: color-mix(in srgb, var(--color--primary) 50%, var(--color--secondary));
background-color: oklch(from var(--color--primary) calc(l + 0.4) c h / 0.1);
}
Animation and Transform Interpolation
Create dynamic animations and transforms with interpolated values:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, keyframes, selector } = s;
const rotationAngle = variable('rotation--angle', '180deg');
const spinKeyframes = keyframes('spin', {
'0%': {
transform: 'rotate(0deg)',
},
'100%': {
transform: css`rotate(${ref(rotationAngle)})`,
},
});
const animationDuration = variable('animation--duration', '0.3s');
const transformScale = variable('transform--hover-scale', '1.05');
selector('.interactive-card', {
transform: 'scale(1) rotate(0deg)',
transition: css`all ${ref(animationDuration)} cubic-bezier(0.4, 0, 0.2, 1)`,
'&:hover': {
transform: css`scale(${ref(transformScale)}) rotate(${ref(rotationAngle)})`,
animation: css`${ref(spinKeyframes)} ${ref(animationDuration)} ease-in-out`,
},
});
export default s;
:root {
--animation--duration: 0.3s;
--transform--hover-scale: 1.05;
--rotation--angle: 180deg;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(var(--rotation--angle));
}
}
.interactive-card {
transform: scale(1) rotate(0deg);
transition: all var(--animation--duration) cubic-bezier(0.4, 0, 0.2, 1);
&:hover {
transform: scale(var(--transform--hover-scale)) rotate(var(--rotation--angle));
animation: spin var(--animation--duration) ease-in-out;
}
}
Grid and Layout Interpolation
Build responsive grid systems and complex layouts with interpolated values:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, selector, media } = s;
const gridColumns = variable('grid--columns', '12');
const gridGap = variable('grid--gap', '1rem');
const breakpointMd = variable('breakpoint--md', '768px');
selector('.responsive-grid', {
display: 'grid',
gridTemplateColumns: css`repeat(${ref(gridColumns)}, 1fr)`,
gap: ref(gridGap),
padding: css`clamp(1rem, 4vw, ${ref(gridGap)} * 2)`,
});
selector('.grid-item', {
gridColumn: css`span min(4, ${ref(gridColumns)})`,
});
media(css`(min-width: ${ref(breakpointMd)})`, ({ selector }) => {
selector('.grid-item', {
gridColumn: css`span min(6, ${ref(gridColumns)})`,
});
});
export default s;
:root {
--grid--columns: 12;
--grid--gap: 1rem;
--breakpoint--md: 768px;
}
.responsive-grid {
display: grid;
grid-template-columns: repeat(var(--grid--columns), 1fr);
gap: var(--grid--gap);
padding: clamp(1rem, 4vw, var(--grid--gap) * 2);
}
.grid-item {
grid-column: span min(4, var(--grid--columns));
}
@media (min-width: var(--breakpoint--md)) {
.grid-item {
grid-column: span min(6, var(--grid--columns));
}
}
Complex Calculations
Create sophisticated CSS calculations using calc()
and other CSS functions:
import { styleframe, css } from 'styleframe';
const s = styleframe();
const { variable, ref, selector } = s;
const containerWidth = variable('container--max-width', '1200px');
const sidebarWidth = variable('sidebar--width', '250px');
const spacing = variable('spacing--lg', '2rem');
selector('.main-content', {
width: css`calc(${ref(containerWidth)} - ${ref(sidebarWidth)} - ${ref(spacing)} * 2)`,
marginLeft: css`clamp(${ref(spacing)}, 5vw, calc(${ref(spacing)} * 2))`,
minHeight: css`max(100vh - ${ref(spacing)} * 4, 400px)`,
});
export default s;
:root {
--container--max-width: 1200px;
--sidebar--width: 250px;
--spacing--lg: 2rem;
}
.main-content {
width: calc(var(--container--max-width) - var(--sidebar--width) - var(--spacing--lg) * 2);
margin-left: clamp(var(--spacing--lg), 5vw, calc(var(--spacing--lg) * 2));
min-height: max(100vh - var(--spacing--lg) * 4, 400px);
}
Best Practices
- Use interpolation for complex values that combine multiple variables or require calculations.
- Maintain readable expressions by breaking complex interpolations into multiple lines when needed.
- Leverage CSS functions like
calc()
,clamp()
,min()
, andmax()
within interpolated values. - Combine with variables to create maintainable, theme-able expressions.
FAQ
Yes, the css
template literal supports all CSS functions including calc()
, clamp()
, color-mix()
, and modern CSS features.
Styleframe's TypeScript integration provides auto-complete and validation for CSS properties and values within template literals.
Yes, you can create complex nested expressions by combining multiple css
template literals and variable references.
CSS custom properties gracefully handle undefined values, and you can provide fallbacks using CSS's built-in fallback syntax.
No, interpolation happens at build time, generating clean CSS output with no runtime overhead.
Keyframes
Styleframe keyframes enable you to create smooth CSS animations with type-safe property definitions. Build engaging motion effects that enhance user experience across your application.
Utilities
Styleframe utilities provide reusable, single-purpose CSS classes with full type safety and recipe support. Build consistent, maintainable styling systems with atomic design patterns.