Composables

Placeholder

A visual placeholder container with a dashed border and hatch pattern for layout prototyping, wireframing, and empty states. Uses the recipe system with dark mode support.

Overview

The Placeholder is a visual container element used for layout prototyping, wireframing, and representing areas where content will eventually appear. It uses a single recipe: usePlaceholderRecipe() which creates a centered flex container with a dashed border and a subtle hatch background pattern. The recipe has no variant axes — it provides a single, consistent appearance with automatic dark mode support.

The Placeholder recipe integrates directly with the default design tokens preset and generates type-safe utility classes at build time with zero runtime CSS.

Why use the Placeholder recipe?

The Placeholder recipe helps you:

  • Prototype layouts quickly: Drop in a placeholder container to visualize spacing and structure before real content is ready.
  • Communicate intent: The dashed border and hatch pattern make it visually obvious that the area is a placeholder, not final content.
  • Support dark mode automatically: The hatch pattern and border color adapt to dark mode without any extra configuration.
  • Customize without forking: Override base styles through the options API to adjust the appearance for your specific use case.
  • Stay type-safe: Full TypeScript support with the Styleframe recipe system.
  • Integrate with your tokens: Every value references the design tokens preset, so theme changes propagate automatically.

Usage

Register the recipe

Add the Placeholder recipe to a local Styleframe instance. The global styleframe.config.ts provides design tokens and utilities, while the component-level file registers the recipe itself:

src/components/placeholder.styleframe.ts
import { styleframe } from 'virtual:styleframe';
import { usePlaceholderRecipe } from '@styleframe/theme';

const s = styleframe();

const placeholder = usePlaceholderRecipe(s);

export default s;

Build the component

Import the placeholder runtime function from the virtual module and call it with no arguments to compute the class name:

src/components/Placeholder.tsx
import { placeholder } from "virtual:styleframe";

interface PlaceholderProps {
    children?: React.ReactNode;
    className?: string;
}

export function Placeholder({ children, className }: PlaceholderProps) {
    return (
        <div className={`${placeholder()} ${className ?? ""}`}>
            {children}
        </div>
    );
}

See it in action

Appearance

The Placeholder recipe has a single, fixed appearance with no color, variant, or size axes. It renders as a centered flex container with:

  • A dashed border using @color.gray-300 (light mode) or @color.gray-600 (dark mode)
  • A hatch background pattern created with a repeating 45° linear gradient
  • Medium border radius (@border-radius.md)
  • Reduced opacity (0.75) to visually distinguish it from real content
  • One unit of padding (@1)

The hatch pattern uses semi-transparent diagonal lines (rgba(0, 0, 0, 0.04) in light mode, rgba(255, 255, 255, 0.04) in dark mode) so it works on any background color.

Good to know: The Placeholder recipe does not include size variants. To control dimensions, apply size utilities or inline styles directly on the element (e.g., class="_height:8" or style="height: 200px").

Anatomy

The Placeholder recipe is a single recipe with no sub-parts:

PartRecipeRole
ContainerusePlaceholderRecipe()Centered flex container with dashed border and hatch pattern
<!-- Single-part recipe -->
<div class="placeholder()">Placeholder content</div>
Pro tip: Since the Placeholder has no inherent dimensions, set a height or width on the element to define the space it occupies. This makes it useful for previewing different layout configurations.

Accessibility

  • Decorative element. Placeholders are visual aids for development and prototyping. If they appear in production, ensure they have aria-hidden="true" or are replaced with meaningful content before shipping.
  • Verify contrast ratios. The default opacity of 0.75 combined with the dashed border provides sufficient visual distinction. If you override the opacity or colors, verify the placeholder remains distinguishable from surrounding content.

Customization

Overriding Defaults

The composable accepts an optional second argument to override any part of the recipe configuration. Overrides are deep-merged with the defaults, so you only need to specify the properties you want to change:

src/components/placeholder.styleframe.ts
import { styleframe } from 'virtual:styleframe';
import { usePlaceholderRecipe } from '@styleframe/theme';

const s = styleframe();

const placeholder = usePlaceholderRecipe(s, {
    base: {
        borderRadius: '@border-radius.lg',
        borderColor: '@color.gray-400',
        opacity: '0.5',
    },
});

export default s;

API Reference

usePlaceholderRecipe(s, options?)

Creates the placeholder container recipe with a dashed border, hatch background pattern, and centered flex layout.

Parameters:

ParameterTypeDescription
sStyleframeThe Styleframe instance
optionsDeepPartial<RecipeConfig>Optional overrides for the recipe configuration
options.baseVariantDeclarationsBlockCustom base styles for the placeholder container

Variants:

The Placeholder recipe has no variant axes. The runtime function is called with no arguments:

const classes = placeholder();

Base styles:

PropertyValueDescription
displayflexFlex container
alignItemscenterVertically center content
justifyContentcenterHorizontally center content
borderWidth@border-width.thinThin border
borderStyle@border-style.dashedDashed border style
borderColor@color.gray-300Light gray border (light mode)
borderRadius@border-radius.mdMedium border radius
overflowhiddenClip overflowing content
opacity0.75Slightly transparent
padding@1One spacing unit of padding
backgroundImageCrosshatch pattern45° repeating linear gradients

Dark mode overrides:

PropertyValueDescription
borderColor@color.gray-600Lighter gray border for dark backgrounds
backgroundImageCrosshatch pattern (white)Same pattern with rgba(255, 255, 255, 0.04) stripes

Learn more about recipes →

Best Practices

  • Set explicit dimensions: The Placeholder has no inherent width or height. Always set dimensions using utility classes or inline styles so the placeholder represents the space it's standing in for.
  • Use for prototyping, not production: Placeholders are development aids. Replace them with real content or meaningful empty states before shipping to users.
  • Override base styles for branding: If your design system uses a different placeholder convention (e.g., dotted borders, different colors), override the base styles in the recipe options rather than wrapping with extra CSS.
  • Combine with text labels: Add descriptive text inside the placeholder (e.g., "Hero Image" or "Sidebar Widget") to communicate what content belongs in each area.

FAQ