Iconography
Icons are rare on jsonresume.org: words do most of the work. When an icon helps (a download, a search, an external link), use Lucide outline icons at a 1.75 stroke, in the color of the text beside them.
Sizes
16px inline and in small controls, 20px in buttons and navigation, 24px on their own.
16px
20px
24px
icons/sizes.tsx
import { Stack, Text } from '@jsonresume/ui';
import { FileJson, Github, Palette } from 'lucide-react';
import * as styles from './sizes.css';
// Three sizes, one stroke width. Icons take the color of their text.
export default function IconSizes() {
return (
<Stack gap={4}>
{[16, 20, 24].map((size) => (
<Stack key={size} direction="row" gap={4} align="center">
<Text as="span" size="xs" tone="muted" className={styles.label}>
{size}px
</Text>
<FileJson size={size} strokeWidth={1.75} aria-hidden="true" />
<Palette size={size} strokeWidth={1.75} aria-hidden="true" />
<Github size={size} strokeWidth={1.75} aria-hidden="true" />
</Stack>
))}
</Stack>
);
}icons/sizes.css.ts
import { style } from '@vanilla-extract/css';
export const label = style({ width: '3rem' });| Size | Where |
|---|---|
| 16px | Inline with body text, badges, small buttons |
| 20px | Navigation, standard controls |
| 24px | Empty states and standalone icons |
In components
Inside a Button, icons scale with the label automatically (1em).
Show code
icons/in-components.tsx
import { Button, Link, Stack, Tooltip } from '@jsonresume/ui';
import { Download, ExternalLink, Search } from 'lucide-react';
import * as styles from './in-components.css';
// Inside buttons, icons size to the label (1em). Icon-only buttons need an
// aria-label; a tooltip shows the same words to sighted users.
export default function IconsInComponents() {
return (
<Stack direction="row" gap={4} align="center" wrap>
<Button variant="primary">
<Download aria-hidden="true" /> Export PDF
</Button>
<Tooltip content="Search themes">
<Button size="icon" aria-label="Search themes">
<Search aria-hidden="true" />
</Button>
</Tooltip>
<Link href="https://jsonresume.org" className={styles.iconLink}>
jsonresume.org <ExternalLink size={14} aria-hidden="true" />
</Link>
</Stack>
);
}icons/in-components.css.ts
import { style } from '@vanilla-extract/css';
// Keep a trailing icon on the link's baseline and with its text.
export const iconLink = style({
display: 'inline-flex',
alignItems: 'center',
gap: '0.3em',
});usage
import { Download } from 'lucide-react';
<Button variant="primary">
<Download aria-hidden="true" /> Export PDF
</Button>Accessibility
- Decorative icons next to text get
aria-hidden="true". - Icon-only controls need an
aria-labelnaming the action, plus a Tooltip with the same words. - Never use an icon alone to convey status; say it in words too.
Guidelines
Do
- Use Lucide, outline style, strokeWidth 1.75.
- Let icons inherit color from their text.
- Pair icons with labels.
Don’t
- Mix icon sets or filled and outline styles.
- Color icons for decoration.
- Use an icon where a word is clearer.