https://open-props.style/
Open Props Get Started Try in browser RAD
Supercharged
CSS variables.
* Expertly crafted web design tokens
* Create consistent components
* Useful in any framework
v1.7.5 MIT
@import "https://unpkg.com/open-props";
.card {
border-radius: var(--radius-2);
padding: var(--size-fluid-3);
box-shadow: var(--shadow-2);
&:hover {
box-shadow: var(--shadow-3);
}
@media (--motionOK) {
animation: var(--animation-fade-in);
}
}
Built with Open Props
[hero-layout] [hero-layou]
Hero Layout
18 props + normalize.css
[adaptive-buttons] [adaptive-b]
Adaptive Buttons
10 props
[cards] [cards]
Adaptive Cards
8 props + normalize.css
[pagination] [pagination]
Pagination Example
10 props
[color-schemes] [color-sche]
4 Color Schemes
16 props
[theme-switch] [theme-swit]
Light / Dark Switch
+2 imports
[pop-animation] [pop-animat]
Make it pop
Example loads only the animations and easings for a springy scale-in
animation
[normalize-codepen] [normalize-]
Normalize Preview
Light + dark HTML5 minimal styles
Why Use Open Props?
It's non-prescriptive.
Design Consistently
Incidentally harmonious.
Predictable
Thanks to consistent naming conventions.
Incrementally Adoptable
Grab all the props, props as JS, or only what you need.
Customizable
Map the props from JS or customize builds from the command line.
Overview
File sizes and links to source:
File Sizes
The following sizes are for the minified files and after Brotli
compression.
Library bundles
4.0kB
open-props.min.css
500+ props
Extras
1.3kB
normalize.min.css demo
normalize.light.css
normalize.dark.css
theme.light.css
theme.dark.css
0.81kB
buttons.min.css demo
Individual PropPacks (tm)
0.49kB
animations.css demo
0.1kB
aspects.css
0.25kB
borders.css
1.3kB
colors.css (228)
pink.css
indigo.css
etc...
1.2kB
colors-hsl.css
pink-hsl.css
indigo-hsl.css
etc...
1.4kB
durations.css
0.2kB
easings.css
0.4kB
fonts.css
1.0kB
gradients.css
0.62kB
masks.edges.css
0.23kB
masks.corner-cuts.css
0.38kB
media.css
0.26kB
shadows.css
0.2kB
sizes.css
0.1kB
supports.css
0.05kB
zindex.css
Coming Soon?!
??
icons.css WIP
??
svg.css WIP
??
patterns.css WIP
??
at-property.css WIP
??
shapes.css WIP
??
layouts.css WIP
??
clips.css WIP
??
variable-fonts.css WIP
??
lists.css WIP
??
counters.css WIP
??
utilities.css WIP
This site
is built
with Open Props.
@import "https://unpkg.com/open-props";
.just-for-gap {
display: grid;
gap: var(--size-4);
}
blockquote {
--_accent-1: var(--lime-5);
--_accent-2: var(--lime-4);
--_bg: var(--surface-2);
--_ink: var(--text-1);
color: var(--_ink);
border-color: var(--_accent-2);
background-color: var(--_bg);
justify-self: flex-start;
}
.gradient-swatch {
border-radius: var(--radius-2);
aspect-ratio: var(--ratio-landscape);
}
pre > code {
box-shadow: var(--shadow-6);
font-family: var(--font-mono);
font-size: var(--font-size-2);
}
.yellow-badge {
padding-inline: var(--size-1);
border-width: var(--border-size-1);
border-color: var(--yellow-6);
color: var(--yellow-2);
border-radius: var(--radius-round);
@nest [data-theme="light"] & {
border-color: var(--orange-2);
color: var(--orange-6);
}
}
.block-wrap {
display: flex;
flex-wrap: wrap;
flex-basis: var(--size-content-2);
gap: var(--size-5) var(--size-8);
align-items: flex-start;
}
.demo-gallery figure {
border-radius: var(--radius-3);
box-shadow: var(--shadow-4);
}
.op-icon-p {
stroke: var(--indigo-2);
@nest a:hover & { stroke: var(--indigo-1); }
@nest [data-theme="light"] & {
stroke: var(--indigo-9);
@nest a:hover & { stroke: var(--indigo-8); }
}
}
.checkmark-list {
align-self: flex-start;
display: grid;
gap: var(--size-2);
font-size: var(--font-size-fluid-1);
font-weight: var(--font-weight-2);
padding-inline-start: 0;
}
Getting Started
These props come in many flavors: CSS, PostCSS, JSON, or Javascript.
Get em from a CDN or NPM. Try it in browser with Preact, Vite,
Vanilla Extract, Lit, Qwik, you name it, it's in this helpful
Stackblitz collection
Need help?
Ask a question on Discord
Learn with Jason & Adam
CDN
No installation required.
View all /
CSS
index.css
/* the props */
@import "https://unpkg.com/open-props";
/* optional imports that use the props */
@import "https://unpkg.com/open-props/normalize.min.css";
@import "https://unpkg.com/open-props/buttons.min.css";
/* just dark or light themes */
@import "https://unpkg.com/open-props/normalize.dark.min.css";
@import "https://unpkg.com/open-props/buttons.dark.min.css";
@import "https://unpkg.com/open-props/normalize.light.min.css";
@import "https://unpkg.com/open-props/buttons.light.min.css";
/* individual imports */
@import "https://unpkg.com/open-props/indigo.min.css";
@import "https://unpkg.com/open-props/indigo-hsl.min.css";
@import "https://unpkg.com/open-props/easings.min.css";
@import "https://unpkg.com/open-props/animations.min.css";
@import "https://unpkg.com/open-props/sizes.min.css";
@import "https://unpkg.com/open-props/gradients.min.css";
/* see PropPacks for the full list */
index.html
index.js
// the props
import 'https://unpkg.com/open-props';
// optional imports that use the props
import 'https://unpkg.com/open-props/normalize.min.css';
import 'https://unpkg.com/open-props/buttons.min.css';
// just go dark themed or light themed
import 'https://unpkg.com/open-props/normalize.dark.min.css';
import 'https://unpkg.com/open-props/buttons.dark.min.css';
import 'https://unpkg.com/open-props/normalize.light.min.css';
import 'https://unpkg.com/open-props/buttons.light.min.css';
// individual imports
import 'https://unpkg.com/open-props/indigo.min.css';
import 'https://unpkg.com/open-props/indigo-hsl.min.css';
import 'https://unpkg.com/open-props/easings.min.css';
import 'https://unpkg.com/open-props/animations.min.css';
import 'https://unpkg.com/open-props/sizes.min.css';
import 'https://unpkg.com/open-props/gradients.min.css';
// see PropPacks for the full list
PostCSS
CSS import examples
/* the props */
@import "https://unpkg.com/open-props/src/index.css";
/* optional imports that use the props */
@import "https://unpkg.com/open-props/src/extra/normalize.css";
@import "https://unpkg.com/open-props/src/extra/buttons.css";
/* individual imports */
@import "https://unpkg.com/open-props/src/indigo.min.css";
@import "https://unpkg.com/open-props/src/indigo-hsl.min.css";
@import "https://unpkg.com/open-props/src/easings.min.css";
@import "https://unpkg.com/open-props/src/animations.min.css";
@import "https://unpkg.com/open-props/src/sizes.min.css";
@import "https://unpkg.com/open-props/src/gradients.min.css";
/* see PropPacks for the full list */
Design Tokens
Not all props can be represented as a design token.
JSON
Follows the (draft) Design Tokens Spec
https://unpkg.com/open-props/open-props.tokens.json
Figma Tokens
Community created setup instructions.
https://unpkg.com/open-props/open-props.figma-tokens.json
https://unpkg.com/open-props/open-props.figma-tokens.sync.json
Style Dictionary
Preview the JSON Example usage (community added) Use with @csstools/
postcss-design-tokens More details
Tokens
import "open-props/style-dictionary-tokens"
// or
import "open-props/open-props.style-dictionary-tokens.json"
https://unpkg.com/open-props/open-props.style-dictionary-tokens.json
Web Components
NPM import examples
/* the props */
@import "open-props/shadow/style";
@import "open-props/open-props.shadow.min.css";
/* individual imports */
@import "open-props/shadow/indigo";
@import "open-props/shadow/indigo-hsl";
@import "open-props/shadow/easings";
@import "open-props/shadow/animations";
@import "open-props/shadow/sizes";
@import "open-props/shadow/gradients";
/* see PropPacks for the full list */
CDN import examples
These props are scoped to :host for use in shadow DOM.
/* the props */
@import "https://unpkg.com/open-props/open-props.shadow.min.css";
/* individual imports */
@import "https://unpkg.com/open-props/indigo.shadow.min.css";
@import "https://unpkg.com/open-props/indigo.shadow-hsl.min.css";
@import "https://unpkg.com/open-props/easings.shadow.min.css";
@import "https://unpkg.com/open-props/animations.shadow.min.css";
@import "https://unpkg.com/open-props/sizes.shadow.min.css";
@import "https://unpkg.com/open-props/gradients.shadow.min.css";
/* see PropPacks for the full list */
NPM
npm install open-props
CSS
CSS Imports
/* the props */
@import "open-props/style";
/* optional imports that use the props */
@import "open-props/normalize";
@import "open-props/buttons";
/* just light or dark themes */
@import "open-props/normalize/dark";
@import "open-props/buttons/dark";
@import "open-props/normalize/light";
@import "open-props/buttons/light";
/* individual imports */
@import "open-props/indigo";
@import "open-props/easings";
@import "open-props/animations";
@import "open-props/sizes";
@import "open-props/gradients";
/* see PropPacks for the full list */
Full Path Imports
/* the props */
@import "open-props/open-props.min.css";
/* optional imports that use the props */
@import "open-props/normalize.min.css";
@import "open-props/buttons.min.css";
/* individual imports */
@import "open-props/indigo.min.css";
@import "open-props/easings.min.css";
@import "open-props/animations.min.css";
@import "open-props/sizes.min.css";
@import "open-props/gradients.min.css";
/* see PropPacks for the full list */
PostCSS
CSS Imports
/* the props */
@import "open-props/postcss/style";
/* optional imports that use the props */
@import "open-props/postcss/normalize";
@import "open-props/postcss/buttons";
/* individual imports */
@import "open-props/postcss/indigo";
@import "open-props/postcss/easings";
@import "open-props/postcss/animations";
@import "open-props/postcss/sizes";
@import "open-props/postcss/gradients";
/* see PropPacks for the full list */
Full Path CSS Imports
/* the props */
@import "open-props/postcss/index.css";
/* optional imports that use the props */
@import "open-props/postcss/extra/normalize.css";
@import "open-props/postcss/extra/buttons.css";
/* individual imports */
@import "open-props/postcss/indigo.min.css";
@import "open-props/postcss/easings.min.css";
@import "open-props/postcss/animations.min.css";
@import "open-props/postcss/sizes.min.css";
@import "open-props/postcss/gradients.min.css";
/* see PropPacks for the full list */
JavaScript
All JavaScript imports
Bundles
// index.js loading JS object
import OpenProps from 'open-props'; // module
import OpenProps from 'open-props/src'; // unbundled ES module
import Colors from 'open-props/src/colors';
// object notation access is special to OpenProps
console.info(OpenProps.size1);
console.info(OpenProps['--size-1']);
console.info(Colors['--indigo-5']);
Individual imports
// import just 1 color set object
import {Indigo} from 'open-props/src/colors';
// import shadows without prop deps
import {StaticShadows} from 'open-props/src/shadows';
// import the gradients
import Gradients from 'open-props/src/gradients';
// see PropPacks for the full list
Design Tokens
/* 3 ways to import */
import 'open-props/tokens'
import 'open-props/json'
import 'open-props/design-tokens'
PostCSS JIT Props
Only ship the props you use. Learn more.
PostCSS
npm install postcss-jit-props
Stop importing Open Props in your CSS (if you were).
This plugin adds them to your stylesheet as you use them
Props as Javascript
// postcss.config.js
const postcssJitProps = require('postcss-jit-props');
const OpenProps = require('open-props');
module.exports = {
plugins: [
postcssJitProps(OpenProps),
]
}
Props from CSS
// postcss.config.js
const postcssJitProps = require('postcss-jit-props');
const path = require('path');
module.exports = {
plugins: [
postcssJitProps({
files: [
path.resolve(__dirname, 'node_modules/open-props/open-props.min.css'),
]
}),
]
}
CLI
git clone https://github.com/argyleink/open-props.git
Customize your build
Customize Bundles
// build src files
npm run gen:shadowdom // src files with `:host` instead of `html`
npm run gen:nowhere // src files without `:where()`
npm run gen:prefixed // each prop prefixed with `op`, like `--op-font-size-1`
// full custom! pass args with node to the props.js script
node props.js 'ns' true ':root' 'my'
|
// arg1: default '', is a custom namespace, props will be --ns-gray-1
// arg2: default false, indicates wrapping in :where() or not
// arg3: default '', set a custom selector like :scope, .my-class, etc
// arg4: default '', set a file prefix, files will be my.props.easing.css, etc
Build Locally
npm run gen:op // runs through `src/` js files and creates the PostCSS files in `src/`
npm run gen:shadowdom // runs through `src/` js files and creates the PostCSS files in `src/`
npm run build // does both gen:op and gen:shadowdom
npm run bundle // creates all the various minified bundles of props
npm run lib:js // builds the JS modules for NPM
Autocomplete
VScode
1. VScode has an intellisense feature which you can tap into, by
passing the path to the node_modules folder where open-props is
installed
2. In your VScode environment, navigate to the extensions
marketplace, and install this CSS Var Complete extension
3. When the extension is installed, you'll have to add open-prop's
css file path to a .vscode/settings.jsonfile. Take a look at an
illustration below
// .vscode/settings.json file
{
"cssvar.files": [
"./node_modules/open-props/open-props.min.css",
// if you have an alternative path to where your styles are located
// you can add it in this array of files
"assets/styles/variables.css"
],
// Do not ignore node_modules css files, which is ignored by default
"cssvar.ignore": [],
// add support for autocomplete in JS or JS like files
"cssvar.extensions": [
"css", "postcss", "jsx", "tsx"
]
}
4. Check details on settings and it's defaults in the repo
Sublime Text
1. There are number of ways with which the autocomplete engine of
Sublime Text can be extended. You can decide to use the
completion files, snippets or plugins.
2. An approach that is less strenuous is the "completion file"
approach. Here, all you'd be required to do is point the `scope`
keyword in the .sublime-completions file to the open-props
classes in the node_modules folder like so:
// .sublime-completions file
{
"scope": "./node_modules/open-props/open-props.min.css",
"completions": [
// here you'll add the classes you want autocomplete for.
]
}
3. You can also add an alternative path to your variables, if you
have one -- in the completions file, like so:
// .sublime-completions file
{
"scope": "path/to/your/variables",
}
4. Another approach for enabling autocomplete would be to open the
settings json file of Sublime Text via Preferences > Settings,
then you'll modify the file to include the snippet below --
replacing "source" with the path to your variables.
"auto-complete-selector": "source, text"
5. You can learn more about the completion process in Sublime Text
here.
Colors
Open Props includes Open Color, an open-source color scheme optimized
for UI development, and its extension, Colar.
Open the color picker in your browser dev tools, set the swatches
to the page's custom properties, and enjoy picking from the set!
The Props
--gray-{0-12}
--stone-{0-12}
--red-{0-12}
--pink-{0-12}
--purple-{0-12}
--violet-{0-12}
--indigo-{0-12}
--blue-{0-12}
--cyan-{0-12}
--teal-{0-12}
--green-{0-12}
--lime-{0-12}
--yellow-{0-12}
--orange-{0-12}
--choco-{0-12}
--brown-{0-12}
--sand-{0-12}
--camo-{0-12}
--jungle-{0-12}
Button Sample
button.blue {
color: var(--blue-6);
background-color: var(--blue-0);
border: 1px solid var(--blue-1);
text-shadow: 0 1px 0 var(--blue-2);
&:hover {
background-color: var(--blue-1);
}
}
Light & Dark Example
html {
--text-1: var(--gray-9);
--text-2: var(--gray-7);
@media (--OSdark) {
--text-1: var(--gray-1);
--text-2: var(--gray-2);
}
}
Modify Opacity Example
/* additional import required */
/* @import "open-props/gray-hsl"; */
@import "open-props/colors-hsl";
.backdrop {
background-color: hsl(var(--gray-9-hsl) / 30%);
}
Copy type
(*) CSS Property Ex: var(--gray-1)
( ) Color Code Ex: rgb(3, 5, 7)
Copy format
(*) RGB
( ) HEX
( ) HSL
Gray
*
*
*
*
*
*
*
*
*
*
*
*
*
Stone
*
*
*
*
*
*
*
*
*
*
*
*
*
Red
*
*
*
*
*
*
*
*
*
*
*
*
*
Pink
*
*
*
*
*
*
*
*
*
*
*
*
*
Purple
*
*
*
*
*
*
*
*
*
*
*
*
*
Violet
*
*
*
*
*
*
*
*
*
*
*
*
*
Indigo
*
*
*
*
*
*
*
*
*
*
*
*
*
Blue
*
*
*
*
*
*
*
*
*
*
*
*
*
Cyan
*
*
*
*
*
*
*
*
*
*
*
*
*
Teal
*
*
*
*
*
*
*
*
*
*
*
*
*
Green
*
*
*
*
*
*
*
*
*
*
*
*
*
Lime
*
*
*
*
*
*
*
*
*
*
*
*
*
Yellow
*
*
*
*
*
*
*
*
*
*
*
*
*
Orange
*
*
*
*
*
*
*
*
*
*
*
*
*
Choco
*
*
*
*
*
*
*
*
*
*
*
*
*
Brown
*
*
*
*
*
*
*
*
*
*
*
*
*
Sand
*
*
*
*
*
*
*
*
*
*
*
*
*
Camo
*
*
*
*
*
*
*
*
*
*
*
*
*
Jungle
*
*
*
*
*
*
*
*
*
*
*
*
*
Color Theming 101
1) Color theming
Low numbers are light and high numbers are dark. See how the Open
Props normalize.css implements light and dark modes.
See it live: auto, light, dark, dim and purple themes demonstrated
with Open Props!
Light
html {
--brand-light: var(--orange-6);
--text-1-light: var(--gray-8);
--text-2-light: var(--gray-7);
--surface-1-light: var(--gray-0);
--surface-2-light: var(--gray-1);
--surface-3-light: var(--gray-2);
--surface-4-light: var(--gray-3);
}
Dark
html {
--brand-dark: var(--orange-3);
--text-1-dark: var(--gray-3);
--text-2-dark: var(--gray-5);
--surface-1-dark: var(--gray-12);
--surface-2-dark: var(--gray-11);
--surface-3-dark: var(--gray-10);
--surface-4-dark: var(--gray-9);
}
Dim
html {
--brand-dim: var(--orange-4);
--text-1-dim: var(--gray-3);
--text-2-dim: var(--gray-4);
--surface-1-dim: var(--gray-8);
--surface-2-dim: var(--gray-7);
--surface-3-dim: var(--gray-6);
--surface-4-dim: var(--gray-5);
}
Purple
html {
--brand-purple: var(--purple-5);
--text-1-purple: var(--purple-9);
--text-2-purple: var(--purple-7);
--surface-1-purple: var(--purple-0);
--surface-2-purple: var(--purple-1);
--surface-3-purple: var(--purple-2);
--surface-4-purple: var(--purple-3);
}
2) Creating adaptive color schemes
It's not ideal for components to reference individual light or dark
theme colors. Instead, you should prefer to use these individual
variables to build a set of theme-agnostic aliases. This allows you
to reference a custom property without worrying about its underlying
value, which will dynamically adapt to the current context's theme.
No Preference (Light)
:root {
--brand: var(--brand-light);
--text-1: var(--text-1-light);
--text-2: var(--text-2-light);
--surface-1: var(--surface-1-light);
--surface-2: var(--surface-2-light);
--surface-3: var(--surface-3-light);
--surface-4: var(--surface-4-light);
}
Prefers Dark
@media (prefers-color-scheme: dark) {
:root {
--brand: var(--brand-dark);
--text-1: var(--text-1-dark);
--text-2: var(--text-2-dark);
--surface-1: var(--surface-1-dark);
--surface-2: var(--surface-2-dark);
--surface-3: var(--surface-3-dark);
--surface-4: var(--surface-4-dark);
}
}
Prefers Dim
@media (prefers-contrast: less) {
:root {
--brand: var(--brand-dim);
--text-1: var(--text-1-dim);
--text-2: var(--text-2-dim);
--surface-1: var(--surface-1-dim);
--surface-2: var(--surface-2-dim);
--surface-3: var(--surface-3-dim);
--surface-4: var(--surface-4-dim);
}
}
Prefers Purple
[color-scheme="purple"] {
--brand: var(--brand-purple);
--text-1: var(--text-1-purple);
--text-2: var(--text-2-purple);
--surface-1: var(--surface-1-purple);
--surface-2: var(--surface-2-purple);
--surface-3: var(--surface-3-purple);
--surface-4: var(--surface-4-purple);
}
3) Using the aliases
Your app is now free to use adaptive custom properties! Now, your
team only needs to remember a single naming convention rather than
wrestling with individual theming variables. Here are a few examples
of how the above color theme system could be used.
Page Styles Using Themes
html {
background-color: var(--surface-1);
color: var(--text-1);
accent-color: var(--link);
}
Utilities
.surface-1 {
background-color: var(--surface-1);
color: var(--text-2);
}
.surface-2 {
background-color: var(--surface-2);
color: var(--text-2);
}
.surface-3 {
background-color: var(--surface-3);
color: var(--text-1);
}
.surface-4 {
background-color: var(--surface-4);
color: var(--text-1);
}
Typography
h1,h2,h3,h4,p,dt {
color: var(--text-1);
}
h5,h6,small,dd {
color: var(--text-2);
}
Gradients
Open Props includes 30 handcrafted gradients. Linear gradient
direction can be changed with a custom property mixin.
Don't miss the noise props inspired by grainy-gradients.
The Props
--gradient-{1-30}
Hero Header Sample
header {
background-image: var(--gradient-5);
@media (--OSdark) {
background-image: var(--gradient-15);
}
}
Gradient Text Sample
.gradient-text {
background: var(--gradient-1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
Gradients
Noise
--noise-{1-5}
--noise-filter-{1-5}
.noise-noise-noise {
/* stack grain with a gradient */
background-image: var(--gradient-3), var(--noise-3);
/* force colors and noise to collide */
filter: var(--noise-filter-3);
/* fit noise image to element */
background-size: cover;
}
Noisy Examples
Shadows
Inner and outer shadows that adapt to light and dark modes.
The Props
--shadow-{1-6}
--inner-shadow-{0-4}
Card Sample
.card {
box-shadow: var(--shadow-1);
&:hover {
box-shadow: var(--shadow-3);
}
}
Aspect Ratios
Vars Sample
--ratio-square: 1;
--ratio-landscape: 4/3;
--ratio-portrait: 3/4;
--ratio-widescreen: 16/9;
--ratio-ultrawide: 18/5;
--ratio-golden: 1.6180/1;
Usage Sample
.video-thumbnail {
block-size: 480px;
aspect-ratio: var(--ratio-widescreen);
}
box
landscape
portrait
widescreen
golden ratio
ultrawide
Typography
Variable and static font sizes, smart line heights, modern font
stacks, and other familiar typography variables, all ready to go.
The Props
--font-size-{00-8}
--font-size-fluid-{0-3}
--font-weight-{1-9}
--font-letterspacing-{0-7}
--font-lineheight-{00-5}
Usage Sample
.hero {
line-height: var(--font-lineheight-1);
font-size: var(--font-size-fluid-3);
font-weight: var(--font-weight-9);
font-family: var(--font-sans);
}
Font Families
These rad font-families from Dan Klammer's modern font stacks provide
great typefaces that are entirely local. With these font stacks you
won't have to worry about slowing down your page load or layout shift
from external fonts!
--font-system-ui: system-ui, sans-serif;
--font-transitional: Charter, Bitstream Charter, Sitka Text, Cambria, serif;
--font-old-style: Iowan Old Style, Palatino Linotype, URW Palladio L, P052, serif;
--font-humanist: Seravek, Gill Sans Nova, Ubuntu, Calibri, DejaVu Sans, source-sans-pro, sans-serif;
--font-geometric-humanist: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif;
--font-classical-humanist: Optima, Candara, Noto Sans, source-sans-pro, sans-serif;
--font-neo-grotesque: Inter, Roboto, Helvetica Neue, Arial Nova, Nimbus Sans, Arial, sans-serif;
--font-monospace-slab-serif: Nimbus Mono PS, Courier New, monospace;
--font-monospace-code: Dank Mono, Operator Mono, Inconsolata, Fira Mono, ui-monospace, SF Mono,Monaco, Droid Sans Mono, Source Code Pro, Cascadia Code,Menlo, Consolas, DejaVu Sans Mono, monospace;
--font-industrial: Bahnschrift, DIN Alternate, Franklin Gothic Medium, Nimbus Sans Narrow, sans-serif-condensed, sans-serif;
--font-rounded-sans: ui-rounded, Hiragino Maru Gothic ProN, Quicksand, Comfortaa, Manjari, Arial Rounded MT, Arial Rounded MT Bold, Calibri, source-sans-pro, sans-serif;
--font-slab-serif: Rockwell, Rockwell Nova, Roboto Slab, DejaVu Serif, Sitka Small, serif;
--font-antique: Superclarendon, Bookman Old Style, URW Bookman, URW Bookman L, Georgia Pro, Georgia, serif;
--font-didone: Didot, Bodoni MT, Noto Serif Display, URW Palladio L, P052, Sylfaen, serif;
--font-handwritten: Segoe Print, Bradley Hand, Chilanka, TSCu_Comic, casual, cursive;
Unlike the other props, which are identical to their modern font
stack counterparts, --font-monospace-code is modified in
open-props.
--font-system-ui
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-transitional
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-old-style
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-humanist
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-geometric-humanist
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-classical-humanist
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-neo-grotesque
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-monospace-slab-serif
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-monospace-code
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-industrial
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-rounded-sans
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-slab-serif
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-antique
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-didone
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
--font-handwritten
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+=!@#%$
%^&
Font Weights
--font-weight-1: 100;
--font-weight-2: 200;
--font-weight-3: 300;
--font-weight-4: 400;
--font-weight-5: 500;
--font-weight-6: 600;
--font-weight-7: 700;
--font-weight-8: 800;
--font-weight-9: 900;
Aa
[4 ]
Letter Spacing
--font-letterspacing-0: -.05em;
--font-letterspacing-1: .025em;
--font-letterspacing-2: .050em;
--font-letterspacing-3: .075em;
--font-letterspacing-4: .150em;
--font-letterspacing-5: .500em;
--font-letterspacing-6: .750em;
--font-letterspacing-7: 1em;
Letter Spacing
[1 ]
Line Height
--font-lineheight-00: .95;
--font-lineheight-0: 1.1;
--font-lineheight-1: 1.25;
--font-lineheight-2: 1.375;
--font-lineheight-3: 1.5;
--font-lineheight-4: 1.75;
--font-lineheight-5: 2;
Sample paragraph content to provide a preview for OP's line heights
[1 ]
Font Sizes
--font-size-00: .5rem;
--font-size-0: .75rem;
--font-size-1: 1rem;
--font-size-2: 1.1rem;
--font-size-3: 1.25rem;
--font-size-4: 1.5rem;
--font-size-5: 2rem;
--font-size-6: 2.5rem;
--font-size-7: 3rem;
--font-size-8: 3.5rem;
var(--font-size-00) Almost before you knew it, we'd touched ground.
var(--font-size-0) Almost before you knew it, we'd touched ground.
var(--font-size-1) Almost before you knew it, we'd touched ground.
var(--font-size-2) Almost before you knew it, we'd touched ground.
var(--font-size-3) Almost before you knew it, we'd touched ground.
var(--font-size-4) Almost before you knew it, we'd touched ground.
var(--font-size-5) Almost before you knew it, we'd touched ground.
var(--font-size-6) Almost before you knew it, we'd touched ground.
var(--font-size-7) Almost before you knew it, we'd touched ground.
var(--font-size-8) Almost before you knew it, we'd touched ground.
Fluid Font Sizes
--font-size-fluid-0: clamp(.75rem, 2vw, 1rem);
--font-size-fluid-1: clamp(1rem, 4vw, 1.5rem);
--font-size-fluid-2: clamp(1.5rem, 6vw, 2.5rem);
--font-size-fluid-3: clamp(2rem, 9vw, 3.5rem);
var(--font-size-fluid-0) Almost before you knew it, we'd touched
ground. var(--font-size-fluid-1) Almost before you knew it, we'd
touched ground. var(--font-size-fluid-2) Almost before you knew it,
we'd touched ground. var(--font-size-fluid-3) Almost before you knew
it, we'd touched ground.
Easing
Five strengths for the classic ease, ease-out, ease-in, and
ease-in-out timing functions. Plus some extra easings for mock
elasticity and physics!
The Props
--ease-{1-5}
--ease-in-{1-5}
--ease-out-{1-5}
--ease-in-out-{1-5}
--ease-elastic-out-{1-5}
--ease-elastic-in-{1-5}
--ease-elastic-in-out-{1-5}
--ease-spring-{1-5}
--ease-bounce-{1-5}
--ease-step-{1-5}
/* will be removed in v2 */
--ease-elastic-{1-5} /* deprecated; equal to elastic-out */
--ease-squish-{1-5} /* deprecated; equal to elastic-in-out */
Usage Sample
.slight-ease {
animation: fade-in 300ms var(--ease-1);
}
.dramatic-ease {
animation: fade-in 1s var(--ease-5);
}
.bouncy {
animation: slide-in-up 3s var(--ease-bounce-2);
}
Ease
ease-1
ease-2
ease-3
ease-4
ease-5
Ease In
ease-in-1
ease-in-2
ease-in-3
ease-in-4
ease-in-5
Ease Out
ease-out-1
ease-out-2
ease-out-3
ease-out-4
ease-out-5
Ease In Out
ease-in-out-1
ease-in-out-2
ease-in-out-3
ease-in-out-4
ease-in-out-5
Ease Elastic Out
ease-elastic-out-1
ease-elastic-out-2
ease-elastic-out-3
ease-elastic-out-4
ease-elastic-out-5
Ease Elastic In
ease-elastic-in-1
ease-elastic-in-2
ease-elastic-in-3
ease-elastic-in-4
ease-elastic-in-5
Ease Elastic In Out
ease-elastic-in-out-1
ease-elastic-in-out-2
ease-elastic-in-out-3
ease-elastic-in-out-4
ease-elastic-in-out-5
Ease Spring
ease-spring-1
ease-spring-2
ease-spring-3
ease-spring-4
ease-spring-5
Ease Bounce
ease-bounce-1
ease-bounce-2
ease-bounce-3
ease-bounce-4
ease-bounce-5
Ease Steps
ease-step-1
ease-step-2
ease-step-3
ease-step-4
ease-step-5
Animations
Premade keyframe effects allow you to orchestrate your own
animations. Plus, a few nice attention-grabbers and indeterminate
state animations.
The Props
--animation-fade-{in,out}
--animation-fade-{in,out}-bloom
--animation-shake-{x,y,z}
--animation-slide-out-{up,down,left,right}
--animation-slide-in-{up,down,left,right}
--animation-spin
--animation-ping
--animation-blink
--animation-float
--animation-bounce
--animation-pulse
Usage Sample
.loaded {
animation: var(--animation-fade-in) forwards;
}
.actionsheet {
animation: var(--animation-slide-out-down) forwards;
&.open {
animation: var(--animation-slide-in-up) forwards;
}
}
.alert {
animation: var(--animation-blink);
}
Samples
Fade In
Fade Out
Bloom Fade In
Bloom Fade Out
Scale Up
Scale Down
Slide Out Up
Slide Out Down
Slide Out Right
Slide Out Left
Slide In Up
Slide In Down
Slide In Right
Slide In Left
Spin
Ping
Blink
Float
Bounce
Pulse
Shake X
Shake Y
Shake Z
Combine 'em!
Slide Fade
.slide-fade {
animation:
var(--animation-fade-out) forwards,
var(--animation-slide-out-down);
animation-timing-function: var(--ease-elastic-in-out-3);
animation-duration: 1s;
}
Shake In
.shake-in {
animation:
var(--animation-shake-y),
var(--animation-fade-in),
var(--animation-slide-in-left);
}
Push Out
.push-out {
animation:
var(--animation-scale-down),
var(--animation-fade-out);
animation-timing-function: var(--ease-elastic-in-out-4);
}
Sizes
Sizes use relative units by default with rem but static, px-based
units are also available. 0s are unsafe but common negative values,
while 1-N are safe.
The Props
--size-{000-15}
--size-px-{000-15}
--size-fluid-{1-10}
--size-content-{1-3}
--size-header-{1-3}
--size-relative-{000-15}
Document Relative Sizes
--size-000: -.5rem;
--size-00: -.25rem;
--size-1: .25rem;
--size-2: .5rem;
--size-3: 1rem;
--size-4: 1.25rem;
--size-5: 1.5rem;
--size-6: 1.75rem;
--size-7: 2rem;
--size-8: 3rem;
--size-9: 4rem;
--size-10: 5rem;
--size-11: 7.5rem;
--size-12: 10rem;
--size-13: 15rem;
--size-14: 20rem;
--size-15: 30rem;
Static Sizes
--size-px-000: -8px;
--size-px-00: -4px;
--size-px-1: 4px;
--size-px-2: 8px;
--size-px-3: 16px;
--size-px-4: 20px;
--size-px-5: 24px;
--size-px-6: 28px;
--size-px-7: 32px;
--size-px-8: 48px;
--size-px-9: 64px;
--size-px-10: 80px;
--size-px-11: 120px;
--size-px-12: 160px;
--size-px-13: 240px;
--size-px-14: 320px;
--size-px-15: 480px;
Usage Sample
article {
display: grid;
gap: var(--size-3);
}
li {
padding-inline-start: var(--size-2);
}
.icon {
inline-size: var(--size-5);
block-size: var(--size-5);
}
Fluid Sizes
--size-fluid-1: clamp(.5rem, 1vw, 1rem);
--size-fluid-2: clamp(1rem, 2vw, 1.5rem);
--size-fluid-3: clamp(1.5rem, 3vw, 2rem);
--size-fluid-4: clamp(2rem, 4vw, 3rem);
--size-fluid-5: clamp(4rem, 5vw, 5rem);
--size-fluid-6: clamp(5rem, 7vw, 7.5rem);
--size-fluid-7: clamp(7.5rem, 10vw, 10rem);
--size-fluid-8: clamp(10rem, 20vw, 15rem);
--size-fluid-9: clamp(15rem, 30vw, 20rem);
--size-fluid-10: clamp(20rem, 40vw, 30rem);
Usage Sample
body {
padding: var(--size-fluid-3);
}
hr {
margin-block: var(--size-fluid-5);
}
Reading Content Sizes
--size-content-1: 20ch;
--size-content-2: 45ch;
--size-content-3: 60ch;
Usage Sample
p {
max-inline-size: var(--size-content-3);
}
aside {
max-inline-size: var(--size-content-2);
}
Carrot cake gummi bears sweet caramels cotton candy topping.
Carrot cake gummi bears sweet caramels cotton candy topping. Jelly
candy apple pie gingerbread tootsie roll chupa chups.
Carrot cake gummi bears sweet caramels cotton candy topping. Jelly
candy apple pie gingerbread tootsie roll chupa chups. Gummi bears
lollipop apple pie pudding tart cake jelly. Souffle lollipop jelly-o
chocolate bar icing bonbon.
Headline Content Sizes
--size-header-1: 20ch;
--size-header-2: 25ch;
--size-header-3: 35ch;
Usage Sample
h1 {
max-inline-size: var(--size-header-2);
}
small {
max-inline-size: var(--size-header-1);
}
Carrot cake gummi bears sweet caramel candy.
Carrot cake gummi bears sweet caramels cotton candy topping.
Carrot cake gummi bears sweet caramels cotton candy topping. Jelly
candy apple pie gingerbread tootsie roll chupa chups.
Relative Sizes
--size-relative-000: -.5ch;
--size-relative-00: -.25ch;
--size-relative-1: .25ch;
--size-relative-2: .5ch;
--size-relative-3: 1ch;
--size-relative-4: 1.25ch;
--size-relative-5: 1.5ch;
--size-relative-6: 1.75ch;
--size-relative-7: 2ch;
--size-relative-8: 3ch;
--size-relative-9: 4ch;
--size-relative-10: 5ch;
--size-relative-11: 7.5ch;
--size-relative-12: 10ch;
--size-relative-13: 15ch;
--size-relative-14: 20ch;
--size-relative-15: 30ch;
Pick a different base font size: [--font-size-5]
Borders
Sizes, corner radii, a circle helper, conditional radii, radii that
produce a hand-drawn border, and some blobs.
Vars Sample
--border-size-{1-5}
--radius-{1-6}
--radius-round
--radius-drawn-{1-6}
--radius-blob-{1-5}
--radius-conditional-{1-6}
Usage Sample
.card {
/* no radius when fullscreen */
border-radius: var(--radius-conditional-3);
border: var(--border-size-1) solid var(--gray-1);
}
.circle {
inline-size: var(--size-5);
aspect-ratio: var(--ratio-square);
border-radius: var(--radius-round);
}
.drawn {
inline-size: var(--size-14);
border: var(--brown-12) var(--border-size-4) solid;
border-radius: var(--radius-drawn-1);
}
Border Size
1
2
3
4
5
Border Radius
1
2
3
4
5
round
Drawn Borders
1
2
3
4
5
6
Blobs
1
2
3
4
5
Z Index
All the z-index values you could possibly need!
The Props
--layer-{1-5}
--layer-important: 2147483647;
Usage Sample
figure {
position: relative;
& figcaption {
position: absolute;
z-index: var(--layer-1);
inset-inline: 0;
inset-block: auto 0;
}
}
.desperate-measures {
position: fixed;
z-index: var(--layer-important);
}
Media Queries
Currently one step ahead of the CSS spec, Open Props offers named
media queries with the @custom-media syntax. Available only with this
PostCSS plugin, for now
Media query widths also available as custom properties. Use like
var(--size-sm)
xxs
240px
xs
360px
sm
480px
md
768px
lg
1024px
xl
1440px
xxl
1920px
The Props
--portrait
--landscape
--{xxs,xs,sm,md,lg,xl,xxl}-only
--{xxs,xs,sm,md,lg,xl,xxl}-n-above
--{xxs,xs,sm,md,lg,xl,xxl}-n-below
--{xxs,xs,sm,md,lg}-phone
Viewport Vars Sample
@custom-media --portrait (orientation: portrait);
@custom-media --landscape (orientation: landscape);
@custom-media --md-only (480px <= width < 768px);
@custom-media --md-n-above (width >= 768px);
@custom-media --md-n-below (width < 768px);
@custom-media --md-phone (--md-only) and (--portrait);
@custom-media --xxl-only (1440px <= width < 1920px);
@custom-media --xxl-n-above (width >= 1920px);
@custom-media --xxl-n-below (width < 1920px);
Capability Vars
@custom-media --touch (hover: none) and (pointer: coarse);
@custom-media --stylus (hover: none) and (pointer: fine);
@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse (hover) and (pointer: fine);
@custom-media --HDcolor (dynamic-range: high) or (color-gamut: p3);
Preference Vars
@custom-media --OSdark (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);
@custom-media --motionOK (prefers-reduced-motion: no-preference);
@custom-media --motionNotOK (prefers-reduced-motion: reduce);
@custom-media --invertedColors (inverted-colors: inverted);
@custom-media --forcedColors (forced-colors: active);
Preference Vars Extended
@custom-media --highContrast (prefers-contrast: more);
@custom-media --lowContrast (prefers-contrast: less);
@custom-media --opacityOK (prefers-reduced-transparency: no-preference);
@custom-media --opacityNotOK (prefers-reduced-transparency: reduce);
@custom-media --useDataOK (prefers-reduced-data: no-preference);
@custom-media --useDataNotOK (prefers-reduced-data: reduce);
Light / Dark Usage Samples
html {
background: white;
color: var(--gray-8);
}
@media (--OSdark) {
html {
background: var(--gray-9);
color: var(--gray-1);
}
}
Reducing Motion Usage Samples
transform: translateX(100%);
@media (--motionOK) {
transition: transform .5s var(--ease-3);
}
Masks
Rad edges and corner-cuts ready to go. A huge shout out to Temani
Afif and their amazing mask work. Be sure to check out their CSS
Generators too; customize the size and distribution of these masks.
Try on Codepen.
Not part of the main bundle. Must be individually imported.
NPM Imported Usage Sample
@import "open-props/masks/edges";
@import "open-props/masks/corner-cuts";
.box-with-corner-cuts {
-webkit-mask: var(--mask-corner-cut-angles-2);
}
.box-with-zig-zag-on-bottom {
-webkit-mask: var(--mask-edge-zig-zag-bottom);
}
Mask Edges
/* NPM */
@import "open-props/masks/edges";
@import "open-props/src/props.masks.edges.css";
@import "open-props/masks.edges.min.css";
/* CDN */
@import "https://unpkg.com/open-props/masks.edges.min.css";
Scoops
Top
Right
Bottom
Left
Vertical
Horizontal
--mask-edge-scoop-{top,right,bottom,left,vertical,horizontal}
.mask-usage {
-webkit-mask: var(--mask-edge-scoop-top);
}
Scalloped
Top
Right
Bottom
Left
Vertical
Horizontal
All
--mask-edge-scalloped-{edges,top,right,bottom,left,vertical,horizontal}
.mask-usage {
-webkit-mask: var(--mask-edge-scalloped-edges);
}
Drips
Top
Right
Bottom
Left
Vertical
Horizontal
--mask-edge-drip-{top,right,bottom,left,vertical,horizontal}
.mask-usage {
-webkit-mask: var(--mask-edge-drip-bottom);
}
Zig-Zag
Top
Right
Bottom
Left
Vertical
Horizontal
--mask-edge-zig-zag-{top,right,bottom,left,vertical,horizontal}
.mask-usage {
-webkit-mask: var(--mask-edge-zig-zag-bottom);
}
Mask Corner Cuts
/* NPM */
@import "open-props/masks/corner-cuts";
@import "open-props/src/props.masks.corner-cuts.css";
@import "open-props/masks.corner-cuts.min.css";
/* CDN */
@import "https://unpkg.com/open-props/masks.corner-cuts.min.css";
Circles
1
2
3
--mask-corner-cut-circles-{1,2,3}
.mask-usage {
-webkit-mask: var(--mask-corner-cut-circles-2);
}
Squares
1
2
3
--mask-corner-cut-squares-{1,2,3}
.mask-usage {
-webkit-mask: var(--mask-corner-cut-squares-2);
}
Angles
1
2
3
--mask-corner-cut-angles-{1,2,3}
.mask-usage {
-webkit-mask: var(--mask-corner-cut-angles-2);
}
* Colors
* Gradients
* Shadows
* Aspect Ratios
* Typography
* Easing
* Animations
* Sizes
* Borders
* Z-Index
* Media Queries
* Masks
Getting Started
Features
Overview
CDN
Tooling
PostCSS
JIT Props
NPM
Showcase
Color helper
Connect
GitHub
Discord
Twitter