Hero ASCIIPro
A hero with the product screenshot set in ASCII beside the headline. When it scrolls into view it resolves, once, from characters into the real screenshot.
On this page
Installation
Usage
import { HeroAscii } from "@/components/ui/chatcn/pro/hero-ascii"
<HeroAscii
title="Meetings, written down while they happen."
src="/shots/notes.png"
darkSrc="/shots/notes-dark.png"
alt="The notes for a pricing review"
url="app.example.com/meetings"
/>The screenshot waits as ASCII until half of it is on screen, then resolves row by row into the picture, once. The character density follows the width the shot first appears at (about one character per 8 px) and then holds, so a resize mid reveal never rebuilds the grid. It sits in a browser frame with your url, or bare with frame={false}. Pass darkSrc and the shot follows the theme: the reveal plays once with the matching screenshot, and a later theme switch crossfades to the other one without playing it again. Serve the screenshot from your own domain or with CORS, at 2x its display size.
Every section is full width with a 16 px gutter on phones and 32 px from 768 px, content capped at 1200 px. Layout follows the section's own width through a container query, not the viewport, so a section in a narrow column lays out like a phone.
Examples
Bare frame and error
The shot on the start side without a frame in coarse characters, and the error state.
Props
| Prop | Type | Notes |
|---|---|---|
title | ReactNode | Required. One idea; it balances over two or three lines |
description | ReactNode | The paragraph under or beside the headline |
actions | ReactNode | Buttons or links under the paragraph |
src, alt | string | Required. alt is what screen readers hear |
darkSrc | string | The shot in your dark theme. Shown wherever the hero sits on a dark surface |
aspectRatio | number | "16:10" | Default 16:10 |
frame, url | Browser frame and its URL. Default on | |
duration | number | Reveal length in ms. Default 2600 |
threshold | number | Share visible before it plays. Default 0.5 |
columns | number | Characters across. Default from the width, 48 to 128 |
imageSide | "start" | "end" | Default end |
onRevealed | () => void | Once, when the screenshot shows |
Keyboard
| Key | Action |
|---|---|
Tab | Reaches your actions. The screenshot takes no focus |
Accessibility
- The section is labelled by its headline. Heroes use an
h1, other sections anh2; render one hero per page. - The characters are
aria-hidden; the real screenshot with youraltis always in the page. - Under
forced-colors: activethe screenshot shows at once.
Motion
- Rows resolve top to bottom over 2.6 s, once per page view.
- Under reduced motion the ASCII crossfades into the screenshot.
- With
darkSrc, a theme switch after the reveal crossfades the shot in 200 ms instead of replaying it.