Hover Reveal Bento
A pure-CSS bento grid that reveals title and description on hover — the icon fades out to let the text through with a smooth spring transition, no JavaScript required.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Cards has 43 effects, including 6 free. Explore the category →
3 usage examples



How it works
The effect is entirely CSS-driven: no JavaScript is involved in the hover. Each .bento-cell holds two absolutely-positioned layers that fill the cell via inset: 0 — .reveal-front (icon) visible at rest, and .reveal-back (title + description) hidden behind it. A single :hover rule on the cell toggles both layers at once.
The transition uses cubic-bezier(.16, 1, .3, 1) over 0.5 s — a fast-spring curve that accelerates sharply at the start and eases out gently at the end. On hover entry, .reveal-front transitions to opacity: 0 with transform: scale(1.2) (zoom-out exit) while .reveal-back rises from opacity: 0; scale: 0.8 to its final size.
The bento grid is a display: grid with 4 columns and 3 rows of equal fractions and a 12 px gap. Cells occupy asymmetric surfaces via grid-area: cell-1 spans 2 columns × 2 rows (main cell), the others ranging from 1 to 2 columns depending on their position. This asymmetry is purely declarative — one property per cell in the CSS.
The icon in .reveal-front sits inside a 50 × 50 px container with border-radius: var(--radius-md) and a var(--gradient-primary) background. Each cell background uses var(--bg-elevated), and the border transitions from var(--border) to rgba(99, 102, 241, .3) on hover with a soft purple box-shadow — providing visual feedback even before mid-transition.
Accessibility
- prefers-reduced-motion not implemented: the code contains no
prefers-reduced-motionmedia query. The 0.5 s transition applies to all users. Minimal fix:@media (prefers-reduced-motion: reduce) { .bento-reveal .bento-cell .reveal-front, .bento-reveal .bento-cell .reveal-back { transition: none; } } - The effect fires on
:hoveronly — on mobile and keyboard, cells stay in their front state (icon visible). Revealed content is inaccessible without an alternative interaction (add:focus-withinor a JavaScript toggle). - No
aria-*attributes are defined in the provided HTML. The.reveal-backtext stays in the DOM and is read by screen readers even at rest — consider addingaria-hidden="true"to.reveal-frontif the icon is decorative. - The
--text-mutedcolor (#8b8b93) on--bg-elevated(#1a1a24) yields a contrast ratio of ~4.1:1 — slightly below the WCAG AA threshold of 4.5:1 for normal-size text. - The
--text-primarycolor (#ffffff) on dark background exceeds 15:1 — WCAG AAA confirmed for headings.
Browser compatibility
Requires CSS Grid and CSS Transitions — supported in all modern browsers. The effect is 100% CSS with zero JavaScript dependencies.
Without CSS Grid support, cells render as a vertical block. Without transitions, the front-to-back switch is instant — content remains readable, the animation disappears but no error is thrown.
The code
HTML structure to paste into your page (the CSS + JS come with Premium):
<div class="bento-container">
<div class="bento-grid bento-reveal">
<div class="bento-cell cell-1">
<div class="reveal-front">
<div class="icon"><!-- SVG icon --></div>
</div>
<div class="reveal-back">
<h5>Title</h5>
<p>Short description</p>
</div>
</div>
<div class="bento-cell cell-2">
<div class="reveal-front"><div class="icon"><!-- SVG --></div></div>
<div class="reveal-back"><h5>Title</h5><p>Description</p></div>
</div>
<div class="bento-cell cell-3">
<div class="reveal-front"><div class="icon"><!-- SVG --></div></div>
<div class="reveal-back"><h5>Title</h5><p>Description</p></div>
</div>
<div class="bento-cell cell-4">
<div class="reveal-front"><div class="icon"><!-- SVG --></div></div>
<div class="reveal-back"><h5>Title</h5><p>Description</p></div>
</div>
<div class="bento-cell cell-5">
<div class="reveal-front"><div class="icon"><!-- SVG --></div></div>
<div class="reveal-back"><h5>Title</h5><p>Description</p></div>
</div>
</div>
</div>
The full HTML + CSS + JS of Hover Reveal Bento, ready to paste — plus all 840 effects. Or $299 once, lifetime access.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| --gradient-primary | linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #d946ef 100%) | Background gradient of the icon container in each cell. Swap in your brand palette or a solid color. |
| --bg-elevated | #1a1a24 | Background color of each bento cell. Switch to a light value (e.g. #f8fafc) for a light theme. |
| --border | rgba(255, 255, 255, 0.08) | Border color of cells at rest. Increase opacity to 0.2–0.3 for a more defined outline. |
| --radius-lg | 0.75rem | Corner radius of each cell. Set to 0 for sharp angles or 1.5 rem for a premium rounded look. |
| transition (CSS on .bento-reveal .reveal-back, .bento-reveal .reveal-front) | 0.5s cubic-bezier(.16, 1, .3, 1) | Duration and easing of the reveal animation. Reduce to 0.25 s for a snappier feel or increase to 0.8 s for a cinematic effect. |
| gap (CSS on .bento-grid) | 12px | Spacing between cells. Increase to 16–20 px for an airy layout, reduce to 6 px for a compact grid. |
| .reveal-front .icon width/height | 50px × 50px | Icon container size. Modify in .bento-reveal .reveal-front .icon for larger SVGs (e.g. 64 × 64 px). |
| grid-template-columns (CSS on .bento-reveal) | repeat(4, 1fr) | Number of grid columns. Reduce to repeat(3, 1fr) and adapt each cell's grid-area for a 3-column layout. |
FAQ
:hover does not fire on touch screens — cells stay in their front state (icon visible). To add reveal on tap, listen to touchstart in JavaScript and toggle a .revealed class that applies the same rules as :hover: opacity: 0; transform: scale(1.2) on .reveal-front and opacity: 1; transform: scale(1) on .reveal-back.grid-area in .bento-reveal .cell-X (e.g. span 2 / span 2 for the main cell). The base grid is grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 1fr) — adjust the column/row counts and grid-area values for any other layout without touching the reveal mechanism.@media (prefers-reduced-motion: reduce) { .bento-reveal .bento-cell .reveal-front, .bento-reveal .bento-cell .reveal-back { transition: none; } }. The front-to-back switch remains functional but becomes instant for users sensitive to motion.