glass-gallery
v0.1.1
Published
A glassmorphic gallery component for React. Frosted-glass cards with hover shine, badges, and lightbox-ready callbacks.
Maintainers
Readme
glass-gallery
A glassmorphic gallery component for React — frosted-glass cards with an Apple-style finish: heavy backdrop blur, boosted saturation, a glossy sheen, and a soft hover lift.
Features
- Grid mode — responsive card gallery with the image on top and the title below (or at the top when there's no image).
- Carousel mode — one glass card cycles through multiple items, with progress-pill dots below the card that fill over time as autoplay advances.
- Themeable — every color, blur, and radius is a CSS variable.
- Accessible — native buttons/links, keyboard navigation,
inerthidden slides,prefers-reduced-motionsupport. - Zero dependencies — React is the only peer dependency. No CSS framework required.
Install
npm install glass-galleryQuick start
import { GlassGallery } from 'glass-gallery'
import type { GalleryItem } from 'glass-gallery'
import 'glass-gallery/styles.css'
const items: GalleryItem[] = [
{ id: '1', src: '/aurora.jpg', title: 'Aurora', caption: 'Soft violet light.', badge: 'New' },
{ id: '2', title: 'Pure Glass', caption: 'No image — the title sits at the top.' },
{ id: '3', src: '/sunset.jpg', title: 'Sunset', href: 'https://example.com' },
]
export function App() {
return (
<GlassGallery
items={items}
columns={3}
padding="md"
rounded="md"
onSelect={(item) => console.log(item)}
/>
)
}Carousel
Pass all the data for one card as the items, set variant="carousel", and optionally enable
autoplay. The active pill fills over interval ms, then the carousel advances to the next slide.
<GlassGallery
items={items}
variant="carousel"
autoplay
interval={4000}
showDots
onSelect={(item) => console.log(item)}
/>Props
| Prop | Type | Default | Description |
| ----------- | --------------------------------- | -------------- | -------------------------------------------------- |
| items | GalleryItem[] | — | Gallery items to render. |
| variant | 'grid' \| 'carousel' | 'grid' | Grid of cards, or one card that cycles through the items. |
| columns | 2 \| 3 \| 4 | 3 | Grid columns (shrinks responsively on small screens). |
| gap | number | 16 | Gap between cards in px. |
| padding | 'sm' \| 'md' \| 'lg' | 'md' | Card body padding: 8px, 16px, or 32px. |
| rounded | 'sm' \| 'md' \| 'lg' | 'md' | Card corner radius. |
| autoplay | boolean | false | Carousel only: auto-advance slides. |
| interval | number | 4000 | Carousel only: autoplay delay in ms. |
| showDots | boolean | true | Carousel only: show the progress dots below the card. |
| onSelect | (item: GalleryItem) => void | — | Fired on card/slide click. Cards become focusable buttons. |
| ariaLabel | string | 'Image gallery' | Accessible label for the gallery region. |
| className | string | '' | Extra class for the gallery container. |
GalleryItem
| Field | Type | Description |
| --------- | -------- | -------------------------------------------- |
| id | string | Required unique id. |
| src | string | Image URL shown at the top of the card. Omit for a text-only card. |
| alt | string | Image alt text (falls back to title). |
| title | string | Card heading. Below the image, or at the top when no image. |
| caption | string | Card subtext below the title. |
| badge | string | Small pill shown on the top-right corner. |
| href | string | If set, the whole card becomes a link. |
Theming
Cards are styled with --gg-* CSS variables. Override them on any parent container:
:root {
--gg-accent: #0ea5e9;
--gg-blur: 24px;
--gg-line: rgba(255, 255, 255, 0.2);
--gg-text: #e2e8f0;
}Light backgrounds — the defaults are tuned for dark UIs. For light mode, override the glass surface and text colors:
.light-theme {
--gg-bg: rgba(255, 255, 255, 0.35);
--gg-bg-strong: rgba(255, 255, 255, 0.55);
--gg-line: rgba(255, 255, 255, 0.55);
--gg-line-strong: rgba(255, 255, 255, 0.9);
--gg-text: #111827;
--gg-text-muted: rgba(17, 24, 39, 0.72);
--gg-accent: #7c3aed;
}Available variables: --gg-bg, --gg-bg-strong, --gg-line, --gg-line-strong,
--gg-text, --gg-text-muted, --gg-accent, --gg-blur, --gg-saturate, --gg-shine,
--gg-pad.
Tip: for the frosted effect to be visible, put colorful content behind the gallery —
backdrop-filterblurs whatever is behind the cards.
Responsive & accessibility
- The grid collapses responsively:
4columns →3at1024px,4/3→2at900px, and everything →1column at600px. - Clickable cards render as native
<button>(or<a>whenhrefis set), so they are keyboard-focusable and screen-reader friendly with a visible:focus-visiblering. - The carousel is
role="group"witharia-roledescription="carousel", non-active slides are hidden withinert+aria-hidden, and controls are labeled buttons. - Images are lazy-loaded with
decoding="async"and usealt(falling back totitle). prefers-reduced-motiondisables the hover lift, shine sweep, and carousel animation.
License
MIT
