A customizable, modern CSS/SCSS library for creating beautiful frosted glass effects with backdrop blur, highlights, and smooth animations. Perfect for creating frosted glass UI components with macOS-style aesthetics.
View Demo | Documentation | Examples
- Highly Customizable - 30+ CSS custom properties for complete control
- Framework Agnostic - Works with any JavaScript framework or vanilla HTML
- Multiple Import Options - Use SCSS source or compiled CSS
- Built-in Variants - Rounded corners, different sizes, and more
- Performance Optimized - Efficient transitions and GPU-accelerated effects
- Zero Dependencies - Pure CSS/SCSS implementation
- Responsive - Works seamlessly across all screen sizes
npm install frostpaneOption 1: Import SCSS (Recommended for customization)
import 'frostpane/scss';Option 2: Import Compiled CSS
import 'frostpane/css';Option 3: Link in HTML
<link rel="stylesheet" href="node_modules/frostpane/dist/frostpane.css" /><div class="glass-container">
<div class="glass-content">Your content here</div>
</div><!-- Rounded corners -->
<div class="glass-container glass-container--rounded">
<div class="glass-content">Rounded glass effect</div>
</div>
<!-- Small size -->
<div class="glass-container glass-container--small">
<div class="glass-content">Small glass element</div>
</div>- Node.js (v18 or higher recommended)
- npm (v7 or higher for workspace support)
# Clone the repository
git clone https://github.com/cameronrye/frostpane.git
cd frostpane
# Install all dependencies
npm install# Start the development server (runs example site)
npm run devOpen http://localhost:5173 in your browser. Changes to the library or example site will hot-reload automatically.
To modify the library:
- Edit
packages/frostpane/src/frostpane.scssorpackages/frostpane/src/frostpane-core.scss - Changes automatically reload in the example site (no rebuild needed)
To modify the example site:
- Edit
packages/example/src/pages/index.astroor other Astro component files - Changes automatically reload in the browser
# Build all packages
npm run build
# Build only the library
npm run build:lib
# Build only the example site
npm run build:example
# Preview the built example site
npm run previewFrostpane includes a comprehensive test suite with 64 automated tests.
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run linting
npm run lint
# Auto-fix linting issues
npm run lint:fixFor detailed testing procedures, see TESTING.md.
This is a monorepo using npm workspaces with two packages:
frostpane/
├── packages/
│ ├── frostpane/ # frostpane - The publishable library
│ │ ├── src/
│ │ │ ├── frostpane.scss
│ │ │ └── frostpane-core.scss
│ │ ├── dist/
│ │ │ ├── frostpane.css
│ │ │ └── frostpane-core.css
│ │ ├── package.json
│ │ └── README.md
│ └── example/ # Example site (Astro)
│ ├── src/
│ │ ├── pages/
│ │ │ └── index.astro
│ │ ├── components/
│ │ ├── layouts/
│ │ └── styles/
│ ├── astro.config.mjs
│ ├── package.json
│ └── README.md
├── package.json # Root workspace configuration
└── README.md # This file
- frostpane - The standalone, publishable CSS/SCSS library
- example - Example site that showcases the library (private, not published)
The example package depends on the core library via workspace reference, demonstrating real-world usage.
<div class="glass-container" style="--fp-backdrop-blur: 12px;">
<div class="glass-content">Stronger blur effect</div>
</div>.dark-glass {
--fp-bg-color: rgba(0, 0, 0, 0.4);
--fp-highlight: rgba(255, 255, 255, 0.3);
--fp-backdrop-blur: 8px;
}.elevated-glass {
--fp-shadow-offset-y: 12px;
--fp-shadow-blur-primary: 12px;
--fp-shadow-blur-secondary: 30px;
}The glass effect is fully customizable using CSS custom properties (CSS variables). Override any of these properties to create your own unique glass effects.
--fp-bg-color: rgba(255, 255, 255, 0.25); /* Glass background tint */
--fp-highlight: rgba(255, 255, 255, 0.75); /* Glass highlight/specular color */
--fp-text: #ffffff; /* Text color */
--fp-red: #fb4268; /* Accent color (red) */
--fp-grey: #444739; /* Secondary text color */--fp-border-radius: 2rem; /* Default border radius */
--fp-border-radius-rounded: 3rem; /* Rounded variant */
--fp-border-radius-small: 0.5rem; /* Small elements */--fp-shadow-color-primary: rgba(0, 0, 0, 0.2); /* Primary shadow color */
--fp-shadow-color-secondary: rgba(0, 0, 0, 0.1); /* Secondary shadow color */
--fp-shadow-blur-primary: 6px; /* Primary shadow blur */
--fp-shadow-blur-secondary: 20px; /* Secondary shadow blur */
--fp-shadow-offset-x: 0; /* Horizontal shadow offset */
--fp-shadow-offset-y: 6px; /* Vertical shadow offset */--fp-backdrop-blur: 4px; /* Backdrop blur amount */--fp-filter-saturate: 120%; /* Color saturation */
--fp-filter-brightness: 1.15; /* Brightness adjustment */--fp-inset-highlight-offset: 1px; /* Highlight position offset */
--fp-inset-highlight-blur: 0; /* Highlight blur amount */
--fp-inset-glow-blur: 5px; /* Inner glow blur */--fp-transition-duration: 0.4s; /* Main transition duration */
--fp-transition-timing: cubic-bezier(0.175, 0.885, 0.32, 2.2); /* Timing function */
--fp-transition-fast: 0.2s; /* Fast interactions */
--fp-transition-medium: 0.25s; /* Medium interactions */
--fp-transition-slow: 0.3s; /* Slow interactions */--fp-content-padding-x: 28px; /* Horizontal padding */
--fp-content-padding-y: 12px; /* Vertical padding */
--fp-content-gap: 1rem; /* Gap between elements */--fp-hover-scale: 1.1; /* Scale on hover */
--fp-active-scale: 0.95; /* Scale on active/click */.dark-glass {
--fp-bg-color: rgba(0, 0, 0, 0.4);
--fp-highlight: rgba(255, 255, 255, 0.3);
--fp-backdrop-blur: 8px;
}.strong-blur {
--fp-backdrop-blur: 12px;
--fp-filter-saturate: 150%;
}.elevated-glass {
--fp-shadow-offset-y: 12px;
--fp-shadow-blur-primary: 12px;
--fp-shadow-blur-secondary: 30px;
}.snappy-glass {
--fp-transition-duration: 0.2s;
--fp-transition-timing: ease-out;
}.pill-glass {
--fp-border-radius: 50px;
}<div class="glass-container" style="--fp-backdrop-blur: 8px; --fp-bg-color: rgba(0, 0, 0, 0.3);">
<!-- content -->
</div>.glass-container.custom-variant {
--fp-backdrop-blur: 8px;
--fp-bg-color: rgba(0, 0, 0, 0.3);
}:root {
--fp-backdrop-blur: 8px;
--fp-bg-color: rgba(0, 0, 0, 0.3);
}- Easy Customization - Change values without modifying the core CSS
- Consistency - Use the same variables across multiple components
- Theming - Create multiple themes by overriding variables
- Maintainability - Update values in one place
- Performance - Specific transition properties prevent unnecessary recalculations
- Flexibility - Mix and match properties for different effects
npm run dev # Run example site in development mode
npm run build # Build all packages
npm run build:lib # Build library only
npm run build:example # Build example site only
npm run preview # Preview built example sitenpm run build # Compile SCSS to CSS
npm run watch # Watch and rebuild on changesnpm run dev # Start Vite dev server
npm run build # Build example site
npm run preview # Preview built siteThe frostpane library can be published to npm:
cd packages/frostpane
npm run build
npm publishThe prepublishOnly script ensures the library is built before publishing.
This project uses npm workspaces for monorepo management, providing:
- Separation of Concerns - Core library is independent from example site
- Reusability - Library can be published and used in other projects
- Simplified Development - Both packages can be developed and tested together
- Dependency Management - Shared dependencies are hoisted to the root
Root (frostpane-monorepo)
├── frostpane
│ └── devDependencies: sass
└── example
├── dependencies: frostpane (workspace:*)
└── devDependencies: vite
The example package depends on the core library through a workspace reference, which npm automatically resolves to the local package during development.
- Library Documentation: packages/frostpane/README.md
- Example Site: packages/example/README.md
- Publishing & Versioning Guide: docs/PUBLISHING.md
- Testing Guide: docs/TESTING.md
- Contributing Guide: docs/CONTRIBUTING.md
- Security Policy: docs/SECURITY.md
- Changelog: docs/CHANGELOG.md
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Test your changes:
npm run devandnpm run build - Commit your changes using conventional commits:
git commit -m 'feat: add new feature' - Push to the branch:
git push origin feature/my-feature - Submit a pull request
Note: We use Semantic Versioning and Conventional Commits for automated changelog generation. Please format your commit messages accordingly.
MIT
Inspired by modern glassmorphic design trends and macOS UI aesthetics.
Made with ❤️ by Cameron Rye