Icons
Scribe uses Font Awesome for all in-product icons. There are three different styles of icons that we use: regular, solid, and duotone. We do not use any sharp, light, or thin icon styles.
Icon Style | |
|---|---|
RegularStroke-style. Use for most icons.@fortawesome/pro-regular-svg-iconsstylus-icons/regular | |
SolidFill-style. Use to communicate active state, or when the icon is very small.@fortawesome/pro-solid-svg-iconsstylus-icons/solid | |
DuotoneUse for large, illustrative areas, like empty states or feature grids.@fortawesome/pro-duotone-svg-iconsstylus-icons/duotone |
Custom Icons
Custom icons are available in the stylus-icons package. Import icons from stylus-icons/regular, stylus-icons/solid or stylus-icons/duotone. Use them the same way you would use any FontAwesome icon.
import { Icon } from "stylus-ui/Icon";import { translateSparkle } from "stylus-icons/regular";
export default () => <Icon icon={translateSparkle} />;Regular
stylus-icons/regularDuotone
stylus-icons/duotoneUsage in Figma
We use the Font Awesome Official Icon Component to access icons in Figma.
To use an icon:
- Insert the
IconorIcon-Duotonecomponent from theStylus - Design Tokenslibrary. - Swap styles, change padding, and scale as needed.
- Type your desired icon name into the “icon-name” text property field. Search for icon names at https://fontawesome.com/icons
Usage in code
To use an icon, import the icon from the desired icon set along with the Icon component. For example, to use the faUser icon from the regular icon set:
import { faUser } from "@fortawesome/pro-regular-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => <Icon icon={faUser} />;Some Stylus components like Button have an icon prop that accepts an IconDefinition. Just pass the imported icon to the component.
import { faUserPlus } from "@fortawesome/pro-regular-svg-icons";import { Button } from "stylus-ui/Button";
export default () => ( <Button icon={faUserPlus} variant="secondary"> Add User </Button>);Sizing
By default, Icon will render at 1em, which is equivalent to 16px. If the parent text size changes, the icon will match it.
import { faUserPlus } from "@fortawesome/pro-regular-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <div className="flex items-center gap-3"> <div className="text-xs"> <Icon icon={faUserPlus} /> </div> <div className="text-sm"> <Icon icon={faUserPlus} /> </div> <div className="text-base"> <Icon icon={faUserPlus} /> </div> <div className="text-lg"> <Icon icon={faUserPlus} /> </div> <div className="text-xl"> <Icon icon={faUserPlus} /> </div> </div>);Explicit sizing
If you need to set an explicit size for the icon, use Tailwind’s size class, which is shorthand for setting both width and height.
import { faUserPlus } from "@fortawesome/pro-regular-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <div className="flex items-center gap-4"> <Icon icon={faUserPlus} className="size-4" /> <Icon icon={faUserPlus} className="size-5" /> <Icon icon={faUserPlus} className="size-6" /> </div>);Preventing icon reflow
Sometimes FontAwesome icon styles don’t load quickly enough. This can cause an oversized icon to flash briefly on first load. To avoid this, set an explicit size on the icon using Tailwind’s size class. This will preserve the correct space, even if the styles haven’t loaded.
// Giant icon reflows on page load! :(<Icon icon={faUserPlus} />
// Appropriate size, even if styles haven't loaded. :)<Icon icon={faUserPlus} className="size-6" />Color
Icons will adopt the current color of the text. To change the color of an icon, set the color of the text.
import { faFolderClosed, faSparkles, faFire,} from "@fortawesome/pro-regular-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <div className="flex items-center gap-3 text-3xl"> <Icon icon={faFolderClosed} className="text-brand-500" /> <Icon icon={faSparkles} className="text-yellow-500" /> <Icon icon={faFire} className="text-red-500" /> </div>);Duotone
Duotone icons adopt the color of the text, with the secondary layer appearing at 40% opacity.
import { faFolderClosed, faSparkles, faFire,} from "@fortawesome/pro-duotone-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <div className="flex items-center gap-3 text-3xl"> <Icon icon={faFolderClosed} className="text-brand-500" /> <Icon icon={faSparkles} className="text-yellow-500" /> <Icon icon={faFire} className="text-red-500" /> </div>);Swap opacity
The swapOpacity prop swaps the opacity of the primary and secondary layers.
import { faFire } from "@fortawesome/pro-duotone-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <div className="flex items-center gap-3 text-3xl"> <Icon icon={faFire} className="text-red-500" /> <Icon icon={faFire} className="text-red-500" swapOpacity /> </div>);Independent colors
To change the color of independent layers, use inline styles to modify the CSS variables for --fa-primary-color and --fa-secondary-color. You can do the same for opacity with --fa-primary-opacity and --fa-secondary-opacity.
import { faFire } from "@fortawesome/pro-duotone-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => ( <Icon icon={faFire} className="size-12" style={{ "--fa-primary-color": "#dc2626", // Red "--fa-primary-opacity": "1", // Default is 1 "--fa-secondary-color": "#f59e0b", // Yellow "--fa-secondary-opacity": "0.8", // Default is 0.4 }} />);If you want to use a color from the Tailwind palette instead of writing a plain-text CSS color value, import the Tailwind config and use the resolveConfig utility to get the theme colors.
import { faRocketLaunch } from "@fortawesome/pro-duotone-svg-icons";import { Icon } from "stylus-ui/Icon";
// 1. Import the Tailwind config and resolve colorsimport config from "stylus-ui/tailwind.config";import resolveConfig from "tailwindcss/resolveConfig";const colors = resolveConfig(config).theme.colors;
export default () => ( <Icon icon={faRocketLaunch} className="size-12" style={{ // 2. Use the Tailwind colors in the icon "--fa-primary-color": colors.brand[600], "--fa-secondary-color": colors.brand[300], }} />);Accessibility
There are a good number of folks with sight and hearing impairments: blindness, low vision, and visual impairment represent almost 10% of the total world population and disabling hearing loss represents over 5% of the total world population.
So it’s important to make sure that the technology supporting impairments, like screen readers, either ignore or better understand the icons you’re using on the web.
— Font Awesome Icons and Accessibility
| Icon Use | What to do |
|---|---|
| Decorative elements | If you’re using an icon to add some extra decoration or branding, it does not need to be announced to users as they are navigating your site or app aurally. Additionally, if you’re using an icon to visually re-emphasize or add styling to content already present in your HTML, it does not need to be repeated to an assistive technology-using user. In these cases, the icon should be hidden from the screenreader so it doesn’t interfere with the established meaning. |
| Semantic elements | When you’re using an icon to convey meaning, you need to make sure that this meaning is also conveyed to users by providing text-based alternatives. This goes for content you’re abbreviating via icons (e.g. shopping cart status, number of unread messages, etc.) as well as interactive controls (e.g. buttons, form elements, toggles, etc.). |
Font Awesome automatically handles some accessibility features. If an icon is rendered without an aria-label attribute, it will be considered decorative and ignored by screen readers.
Semantic elements should provide an aria-label to the icon which will be announced by screen readers.
import { faUserPlus } from "@fortawesome/pro-regular-svg-icons";import { Icon } from "stylus-ui/Icon";
export default () => <Icon icon={faUserPlus} aria-label="Add User" />;References
- Icon Usability, Nielsen Norman Group, 2014
- How to Use Icons in Design: UX and UI Best Practices, The Noun Project, 2024
- In Defense of Text Labels, Christopher Butler, 2025