How to Integrate Open Props with Astro: Complete Guide
Step-by-step guide to integrating Open Props with your Astro website.
Open Props is a collection of CSS custom properties (variables) that provide a consistent design system out of the box. Instead of defining your own spacing scale, color palette, font sizes, shadows, and animations from scratch, you import Open Props and use pre-defined variables like --size-3, --blue-7, or --shadow-2. Think of it as a design token library, not a framework.
The difference from Tailwind or UnoCSS is that Open Props does not generate utility classes. It gives you CSS variables that you use in your own stylesheets, however you write them. This makes it a perfect fit for Astro projects that use scoped styles, plain CSS, or any CSS methodology.
Prerequisites
- Node.js 18+
- An Astro project (
npm create astro@latest)
Installation
npm install open-props
For the PostCSS plugin that removes unused variables from production builds:
npm install -D postcss-jit-props
Configuration
Open Props works with zero configuration. Import it in your global stylesheet:
/* src/assets/styles/global.css */
@import "open-props/style";
@import "open-props/normalize";
The style import gives you all the CSS custom properties. The normalize import is an optional reset that uses Open Props variables for sensible defaults.
If you want to tree-shake unused properties (recommended for production), set up PostCSS:
// postcss.config.cjs
const postcssJitProps = require("postcss-jit-props");
const OpenProps = require("open-props");
module.exports = {
plugins: [postcssJitProps(OpenProps)],
};
This analyzes your CSS and only includes the Open Props variables you actually use.
Import the global stylesheet in your layout:
---
// src/layouts/BaseLayout.astro
import "../assets/styles/global.css";
---
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><slot name="title" /></title>
</head>
<body>
<slot />
</body>
</html>
Basic Usage
Use Open Props variables in your Astro component scoped styles:
---
// src/components/Card.astro
export interface Props {
title: string;
description: string;
}
const { title, description } = Astro.props;
---
<div class="card">
<h3 class="card-title">{title}</h3>
<p class="card-description">{description}</p>
</div>
<style>
.card {
background: var(--surface-1);
border-radius: var(--radius-3);
padding: var(--size-5);
box-shadow: var(--shadow-2);
transition: box-shadow 0.2s var(--ease-2);
}
.card:hover {
box-shadow: var(--shadow-4);
}
.card-title {
font-size: var(--font-size-4);
font-weight: var(--font-weight-7);
color: var(--text-1);
margin-bottom: var(--size-2);
}
.card-description {
font-size: var(--font-size-2);
color: var(--text-2);
line-height: var(--font-lineheight-3);
}
</style>
Available Properties
Open Props provides variables across several categories:
Sizes and Spacing:
var(--size-1) /* 0.25rem */
var(--size-3) /* 1rem */
var(--size-5) /* 1.5rem */
var(--size-7) /* 2.5rem */
var(--size-10) /* 4rem */
Colors (15 hues, 13 shades each):
var(--blue-1) /* lightest */
var(--blue-7) /* mid */
var(--blue-12) /* darkest */
var(--green-5)
var(--red-9)
var(--gray-3)
Shadows:
var(--shadow-1) /* subtle */
var(--shadow-3) /* medium */
var(--shadow-6) /* dramatic */
Animations and Easings:
var(--ease-1) /* ease-in */
var(--ease-out-3) /* ease-out */
var(--animation-fade-in)
var(--animation-slide-in-up)
Typography:
var(--font-size-0) /* 0.75rem */
var(--font-size-3) /* 1.25rem */
var(--font-size-6) /* 2.5rem */
var(--font-weight-4) /* 400 */
var(--font-weight-7) /* 700 */
var(--font-lineheight-3) /* 1.5 */
Dark Mode
Open Props includes adaptive color properties that respond to prefers-color-scheme:
/* These adapt automatically in dark mode */
var(--surface-1) /* white in light, dark gray in dark */
var(--surface-2)
var(--text-1) /* near-black in light, near-white in dark */
var(--text-2) /* muted text, adapts to both modes */
If you control dark mode with a class:
/* Import the dark mode overrides */
@import "open-props/colors-hsl";
.dark {
--surface-1: var(--gray-9);
--surface-2: var(--gray-8);
--text-1: var(--gray-1);
--text-2: var(--gray-4);
}
Building a Component Library
Open Props is ideal for building reusable Astro components with consistent styling:
---
// src/components/Button.astro
export interface Props {
variant?: "primary" | "secondary" | "ghost";
size?: "sm" | "md" | "lg";
}
const { variant = "primary", size = "md" } = Astro.props;
const className = "btn btn-" + variant + " btn-" + size;
---
<button class={className}>
<slot />
</button>
<style>
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--size-2);
border: none;
border-radius: var(--radius-2);
font-weight: var(--font-weight-6);
cursor: pointer;
transition: all 0.2s var(--ease-2);
text-decoration: none;
}
.btn-sm { padding: var(--size-1) var(--size-3); font-size: var(--font-size-0); }
.btn-md { padding: var(--size-2) var(--size-4); font-size: var(--font-size-1); }
.btn-lg { padding: var(--size-3) var(--size-5); font-size: var(--font-size-2); }
.btn-primary {
background: var(--blue-7);
color: white;
}
.btn-primary:hover { background: var(--blue-8); }
.btn-secondary {
background: var(--surface-2);
color: var(--text-1);
border: 1px solid var(--gray-3);
}
.btn-secondary:hover { background: var(--surface-3); }
.btn-ghost {
background: transparent;
color: var(--text-1);
}
.btn-ghost:hover { background: var(--surface-2); }
</style>
Animations
Open Props includes pre-built animation keyframes:
---
// src/components/FadeIn.astro
---
<div class="fade-in">
<slot />
</div>
<style>
.fade-in {
animation: var(--animation-fade-in) forwards;
animation-duration: 0.5s;
animation-timing-function: var(--ease-out-3);
}
</style>
Available animations include fade-in, fade-out, slide-in-up, slide-in-down, slide-in-left, slide-in-right, scale-up, scale-down, shake-x, shake-y, spin, ping, and blink.
Combining with Tailwind
You can use Open Props alongside Tailwind CSS. Use Open Props variables in your Tailwind config:
// tailwind.config.mjs
export default {
theme: {
extend: {
colors: {
primary: "var(--blue-7)",
surface: "var(--surface-1)",
},
borderRadius: {
card: "var(--radius-3)",
},
boxShadow: {
card: "var(--shadow-2)",
},
},
},
};
This gives you Tailwind utility classes that reference Open Props tokens.
Production Tips
Always use postcss-jit-props. Open Props includes hundreds of variables. The JIT plugin tree-shakes unused ones, reducing your CSS from around 15KB to only what you reference.
Use the normalize. Open Props normalize sets sensible defaults using the design tokens. It replaces traditional resets like normalize.css with one that already uses your design system.
Stick to the scale. Open Props sizes follow a consistent scale. Using
--size-3then--size-5looks intentional. Jumping from--size-1to--size-10looks accidental. Follow the progression.Extend, do not override. If the provided colors or sizes do not fit your brand, create your own custom properties that reference Open Props as a base rather than overriding them.
Use HSL variants for custom palettes. Import
open-props/colors-hslto get HSL versions of all colors. This lets you create transparent variants with the HSL function.
Alternatives to Consider
- Tailwind CSS if you prefer utility classes over writing CSS with custom properties.
- UnoCSS if you want an atomic CSS engine with custom rule support.
- Vanilla Extract if you want type-safe CSS-in-TypeScript with build-time generation.
Wrapping Up
Open Props gives you a professional design system without imposing any framework opinions. For Astro projects, it works with scoped styles, global CSS, or any other approach you prefer. The variables are well-named, the scales are thoughtful, and the dark mode support works out of the box. If you want consistent design tokens without the overhead of a utility class framework, Open Props is the simplest path to a polished design system.
Related Articles
How to Use Algolia with Astro: Complete Guide
Step-by-step guide to integrating Algolia with your Astro website.
How to Integrate Auth0 with Astro: Complete Guide
Step-by-step guide to integrating Auth0 with your Astro website. Setup, configuration, and best practices.
How to Use AWS Amplify with Astro: Complete Guide
Step-by-step guide to integrating AWS Amplify with your Astro website.