Open Props

repository·main·Indexed 11 days ago

https://github.com/argyleink/open-props

A collection of open-source CSS variables providing design tokens for modern web development, including colors, typography, animations, and shadows. Version 1.7.23 includes utility classes for accessibility, text truncation, and animations, as well as normalization styles and component styles for buttons and brand customization.

Tokens
19K
Snippets
48
Records
52
Agent score
89%

What's inside Open Props

  1. Customize the color palette using base variables

    main

    The color palette is dynamic. You can change the theme's hue, saturation (chroma), and color distribution by overriding these three variables in your CSS:

    • --palette-hue: Sets the base hue value.
    • --palette-chroma: Sets the base chroma (saturation) value.
    • --palette-hue-rotate-by: Determines how much the hue shifts between each color step in the palette.

    All --color-n tokens are derived from these values using the oklch() function.

    :root {
      /* Example: Shift to a warmer, more saturated palette */
      --palette-hue: 30;
      --palette-chroma: 0.25;
      --palette-hue-rotate-by: 10;
    }
  2. Use light mode CSS normalization styles

    main

    To apply light mode normalization styles, import src/extra/normalize.light.css. This file imports the light theme, brand styles, and core normalization source. It also configures specific CSS variables for shadows to ensure consistent light-mode appearance.

    Key variables defined in this layer:

    • --shadow-color: Set to 220 3% 15%.
    • --shadow-strength: Set to 1%.
    • --inner-shadow-highlight: Set to inset 0 -.5px 0 0 #fff, inset 0 .5px 0 0 #0001.
    @import "src/extra/normalize.light.css";
  3. Import Open Props via CSS

    main

    To use the full suite of Open Props CSS variables in your project, import the main src/index.css file. This entry point imports all available property modules, including media queries, fonts, sizes, easing, z-index, shadows, aspect ratios, colors, gradients, animations, borders, and the color palette.

    If you only need specific subsets of properties, you can import the individual modules directly (e.g., @import 'props.colors.css';) to reduce the amount of CSS loaded.

    @import 'src/index.css';
  4. Apply dark mode CSS normalization styles

    main

    To apply the dark mode normalization styles provided by open-props, import the normalize.dark.css file into your stylesheet. This file imports theme.dark.css, brand.css, and normalize.src.css to ensure a consistent dark theme baseline.

    It applies specific background colors to form elements and dialogs, adjusts shadow properties for dark mode, and sets placeholder text styles using Open Props variables.

    @import "src/extra/normalize.dark.css";
  5. Use the button component styles

    main

    The button styles target several standard HTML elements and classes. To use the pre-styled button component, you can use the .btn class or standard HTML tags. The styles also automatically apply to file input upload buttons.

    Target Selectors

    • .btn class
    • button tag
    • input[type="button"]
    • input[type="submit"]
    • input[type="reset"]
    • input[type="file"] (including ::file-selector-button and ::-webkit-file-upload-button)

    Default Behaviors

    • Hover State: When hovering (and not active), a highlight effect is applied using --_highlight and --_highlight-size.
    • Disabled State: When [disabled] is present, the background is removed, text color becomes var(--gray-6), and the cursor changes to not-allowed.
    • Icons: SVGs placed directly inside the button will automatically scale to --_icon-size and use --_icon-color for their strokes.
    <!-- Standard button -->
    <button class="btn">Click Me</button>
    
    <!-- Submit button with custom accent -->
    <input type="submit" style="--_accent: var(--green-6);" value="Submit">
    
    <!-- Button with an icon -->
    <button class="btn">
      <svg viewBox="0 0 24 24"><path d="..." /></svg>
      Icon Button
    </button>
  6. Reference: Edge Mask CSS variables

    main

    The following CSS variables are exported for edge masking effects:

    '--mask-edge-scoop-bottom': 'radial-gradient(20px at 50% 100%,#0000 97%,#000) 50% / calc(1.9 * 20px) 100%',
    '--mask-edge-scoop-top': 'radial-gradient(20px at 50% 0,#0000 97%,#000) 50% / calc(1.9 * 20px) 100%',
    '--mask-edge-scoop-vertical': 'radial-gradient(20px at 50% 20px,#0000 97%,#000) 50% -20px/ calc(1.9 * 20px) 100%',
    '--mask-edge-scoop-left': 'radial-gradient(20px at 0 50%,#0000 97%,#000) 50%/ 100% calc(1.9 * 20px)',
    '--mask-edge-scoop-right': 'radial-gradient(20px at 100% 50%,#0000 97%,#000) 50%/ 100% calc(1.9 * 20px)',
    '--mask-edge-scoop-horizontal': 'radial-gradient(20px at 20px 50%,#0000 97%,#000) -20px/ 100% calc(1.9 * 20px)',
    '--mask-edge-scalloped': `
        radial-gradient(farthest-side,#000 97%,#0000) 0 0 / 20px 20px round,
        linear-gradient(#000 0 0) 50%/calc(100% - 20px) calc(100% - 20px) no-repeat
      ',
    '--mask-edge-scalloped-bottom': `
        linear-gradient(to top,#0000 20px,#000 0),
        radial-gradient(20px at top,#000 97%,#0000) bottom / calc(1.9 * 20px) 20px
      ',
    '--mask-edge-scalloped-top': `
        linear-gradient(to bottom,#0000 20px,#000 0),
        radial-gradient(20px at bottom,#000 97%,#0000) top / calc(1.9 * 20px) 20px
      ',
    '--mask-edge-scalloped-vertical': `
        linear-gradient(0deg,#0000 calc(2 * 20px),#000 0) 0 20px,
        radial-gradient(20px,#000 97%,#0000) 50% / calc(1.9 * 20px) calc(2 * 20px) repeat space
      ',
    '--mask-edge-scalloped-left': `
        linear-gradient(to right,#0000 20px,#000 0),
        radial-gradient(20px at right,#000 97%,#0000) left / 20px calc(1.9 * 20px)
      ',
    '--mask-edge-scalloped-right': `
        linear-gradient(to left,#0000 20px,#000 0),
        radial-gradient(20px at left,#000 97%,#0000) right / 20px calc(1.9 * 20px)
      ',
    '--mask-edge-scalloped-horizontal': `
        linear-gradient(-90deg,#0000 calc(2 * 20px),#000 0) 20px,
        radial-gradient(20px,#000 97%,#0000) 50% / calc(2 * 20px) calc(1.9 * 20px) space repeat
      ',
    '--mask-edge-drip-bottom': `
        radial-gradient(20px at bottom,#0000 97%,#000) 50% calc(100% - 20px) / calc(2 * 20px) 100% repeat-x,
        radial-gradient(20px at 25% 50%,#000 97%,#0000) calc(50% - 20px) 99% / calc(4 * 20px) calc(2 * 20px) repeat-x
      ',
    '--mask-edge-drip-top': `
        radial-gradient(20px at top,#0000 97%,#000) 50% 20px / calc(2 * 20px) 100% repeat-x,
        radial-gradient(20px at 25% 50%,#000 97%,#0000) calc(50% - 20px) 1% / calc(4 * 20px) calc(2 * 20px) repeat-x
      ',
    '--mask-edge-drip-vertical': `
        radial-gradient(20px at top   ,#0000 97%,#000) 50%             20px  / calc(2 * 20px) 51% repeat-x,
        radial-gradient(20px at bottom,#0000 97%,#000) 50% calc(100% - 20px) / calc(2 * 20px) 51% repeat-x,
        radial-gradient(20px at 25% 50%,#000 97%,#0000) calc(50% -   20px) 1%  / calc(4 * 20px) calc(2 * 20px) repeat-x,
        radial-gradient(20px at 25% 50%,#000 97%,#0000) calc(50% - 3*20px) 99% / calc(4 * 20px) calc(2 * 20px) repeat-x
      ',
    '--mask-edge-drip-left': `
        radial-gradient(20px at left,#0000 97%,#000) 20px 50% / 100% calc(2 * 20px) repeat-y,
        radial-gradient(20px at 50% 25%,#000 97%,#0000) 1% calc(50% - 20px) / calc(2 * 20px) calc(4 * 20px) repeat-y
      ',
    '--mask-edge-drip-right': `
        radial-gradient(20px at right,#0000 97%,#000) calc(100% - 20px) 50% / 100% calc(2 * 20px) repeat-y,
        radial-gradient(20px at 50% 25%,#000 97%,#0000) 99% calc(50% - 20px) / calc(2 * 20px) calc(4 * 20px) repeat-y
      ',
    '--mask-edge-drip-horizontal': `
        radial-gradient(20px at left ,#0000 97%,#000)             20px  50% / 51% calc(2 * 20px) repeat-y,  
        radial-gradient(20px at right,#0000 97%,#000) calc(100% - 20px) 50% / 51% calc(2 * 20px) repeat-y,
        radial-gradient(20px at 50% 25%,#000 97%,#0000) 1%  calc(50% -   20px) / calc(2 * 20px) calc(4 * 20px) repeat-y,
        radial-gradient(20px at 50% 25%,#000 97%,#0000) 99% calc(50% - 3*20px) / calc(2 * 20px) calc(4 * 20px) repeat-y
      ',
    '--mask-edge-zig-zag-top': 'conic-gradient(from 135deg at top,#0000,#000 1deg 90deg,#0000 91deg) 50% / 40px 100%',
    '--mask-edge-zig-zag-bottom': 'conic-gradient(from -45deg at bottom,#0000,#000 1deg 90deg,#0000 91deg) 50% / 40px 100%',
    '--mask-edge-zig-zag-left': 'conic-gradient(from 45deg at left,#0000,#000 1deg 90deg,#0000 91deg) 50% / 100% 40px',
    '--mask-edge-zig-zag-right': 'conic-gradient(from -135deg at right,#0000,#000 1deg 90deg,#0000 91deg) 50% / 100% 40px',
    '--mask-edge-zig-zag-horizontal': `repeating-conic-gradient(from 45deg at 20px 50%,#0000,#000 1deg 90deg,#0000 91deg 180deg) -20px 50% / 100% 40px`,
    '--mask-edge-zig-zag-vertical': `repeating-conic-gradient(from 135deg at 50% 20px,#0000,#000 1deg 90deg,#0000 91deg 180deg) 50% -20px / 40px 100%`,
    }
  7. Hide elements visually while keeping them accessible

    main

    Use the .visually-hidden or .sr-only classes to hide elements from the visual layout while ensuring they remain available to screen readers. This is achieved by setting inline-size and block-size to 0 and hiding the overflow.

    <span class="visually-hidden">This text is for screen readers only</span>
  8. Customize dark mode button styles

    main

    The dark mode button component styles target .btn, button, and specific input types (button, submit, reset). You can customize the appearance by overriding the following internal CSS variables:

    • --_accent: The primary accent color (defaults to var(--link)).
    • --_text: The text color (defaults to initial).
    • --_size: The font size (defaults to initial).

    Note that certain types have specialized behaviors:

    • [type="submit"] and form button:not([type]) automatically use --_accent for their text color.
    • [type="reset"] uses --red-2 for text and --red-6 for focus-visible outlines.
    • [disabled] buttons use var(--gray-5) for text and have cursor: not-allowed.
    /* Example: Customizing a button's accent and size */
    .btn {
      --_accent: var(--blue-5);
      --_size: 1.2rem;
    }
  9. Animate elements with fade-up-and-in

    main

    The .fade-up-and-in class applies a combined animation that fades the element in and slides it upward. It relies on the following Open Props variables:

    • --animation-fade-in
    • --animation-slide-in-up

    The animation has a total duration of up to 1s and a 0.3s delay for the fade effect.

    <div class="fade-up-and-in">
      I will fade in and slide up.
    </div>
  10. Customize button styles using CSS variables

    main

    The button component styles in buttons.light.css are designed to be highly customizable via a set of internal CSS variables. You can override these variables to change the appearance of elements matching .btn, button, or specific input types (button, submit, reset).

    Available Customization Variables

    VariableDescription
    --_accentThe primary accent color (defaults to var(--link) for text/icons)
    --_textThe text color
    --_sizeThe font size
    --_bgThe background color (defaults to white)
    --_borderThe border color (defaults to var(--surface-3))
    --_icon-sizeThe size of SVG icons inside the button (defaults to var(--size-relative-7))
    --_icon-colorThe color of SVG icons (defaults to --_accent)

    Usage Example

    To apply a custom theme to a button, define these variables on the element or a parent container:

    /* Example: Creating a custom primary button */
    .my-custom-btn {
      --_accent: var(--blue-6);
      --_text: white;
      --_bg: var(--blue-6);
      --_border: var(--blue-7);
    }
  11. Add borders between child elements (Inline and Block)

    main

    Use these utility classes to add borders between adjacent children in a container, preventing a border from appearing on the first child.

    • .border-between-inline: Adds a border-inline-start-width using the --border variable to every child except the first.
    • .border-between-block: Adds a border-block-start-width using the --border variable to every child except the first.
    <div class="border-between-inline">
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>
    </div>