Svelte 5 component · fractalsvelte-ui · Layout
Flex
A flexible flexbox layout utility providing granular control over direction, wrapping, and distribution. Supports independent axis gap tokens and inline flex formatting.
Install
Flex is a Svelte 5 flex component in @fractaldesign/fractalsvelte-ui. It works in SvelteKit and in any Svelte 5 app.
pnpm add @fractaldesign/fractalsvelte-uiImport
import { Flex } from '@fractaldesign/fractalsvelte-ui';Usage
<Flex direction={'row'} wrap={'nowrap'} gap={'none'}>Click me</Flex>Props
Also accepts every attribute of HTMLAttributes, spread onto
the root element.
| Name | Type | Default |
|---|---|---|
direction | StackDirection Flex flow direction | 'row' |
wrap | FlexWrap 'nowrap' | 'wrap' | 'wrap-reverse' Flex wrap behavior | 'nowrap' |
gap | Space 'none' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' Universal gap token across both axes | 'none' |
gapX | Space 'none' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' Horizontal column gap token | — |
gapY | Space 'none' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' Vertical row gap token | — |
align | Align 'start' | 'center' | 'end' | 'stretch' | 'baseline' Cross-axis alignment | 'stretch' |
justify | Justify 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' Main-axis distribution | 'start' |
inline | boolean Render as inline-flex container | false |
class | string Additional CSS classes | '' |
Snippets
| Name | Type | Default |
|---|---|---|
children | Snippet Slotted child elements | — |
Source
Show the Flex.svelte source
<script lang="ts">
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
import type { Space, Align, Justify } from '../../types';
import type { StackDirection } from './Stack.svelte';
export type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse';
interface Props extends HTMLAttributes<HTMLDivElement> {
/** Flex flow direction */
direction?: StackDirection;
/** Flex wrap behavior */
wrap?: FlexWrap;
/** Universal gap token across both axes */
gap?: Space;
/** Horizontal column gap token */
gapX?: Space;
/** Vertical row gap token */
gapY?: Space;
/** Cross-axis alignment */
align?: Align;
/** Main-axis distribution */
justify?: Justify;
/** Render as inline-flex container */
inline?: boolean;
/** Additional CSS classes */
class?: string;
/** Slotted child elements */
children?: Snippet;
}
let {
direction = 'row',
wrap = 'nowrap',
gap = 'none',
gapX,
gapY,
align = 'stretch',
justify = 'start',
inline = false,
class: className = '',
children,
...restProps
}: Props = $props();
function getSpaceVar(token?: Space): string | undefined {
if (!token || token === 'none') return undefined;
return `var(--f-space-${token})`;
}
const computedColumnGap = $derived(getSpaceVar(gapX) ?? getSpaceVar(gap));
const computedRowGap = $derived(getSpaceVar(gapY) ?? getSpaceVar(gap));
</script>
<div
class="f-flex {className}"
data-direction={direction}
data-wrap={wrap}
data-align={align}
data-justify={justify}
data-inline={inline ? 'true' : 'false'}
style:column-gap={computedColumnGap}
style:row-gap={computedRowGap}
{...restProps}
>
{#if children}
{@render children()}
{/if}
</div>
<style>
@layer fractalsvelte-ui.components {
.f-flex {
display: flex;
box-sizing: border-box;
}
.f-flex[data-inline='true'] {
display: inline-flex;
}
/* Directions */
.f-flex[data-direction='row'] {
flex-direction: row;
}
.f-flex[data-direction='column'] {
flex-direction: column;
}
.f-flex[data-direction='row-reverse'] {
flex-direction: row-reverse;
}
.f-flex[data-direction='column-reverse'] {
flex-direction: column-reverse;
}
/* Wrap */
.f-flex[data-wrap='nowrap'] {
flex-wrap: nowrap;
}
.f-flex[data-wrap='wrap'] {
flex-wrap: wrap;
}
.f-flex[data-wrap='wrap-reverse'] {
flex-wrap: wrap-reverse;
}
/* Alignment */
.f-flex[data-align='start'] {
align-items: flex-start;
}
.f-flex[data-align='center'] {
align-items: center;
}
.f-flex[data-align='end'] {
align-items: flex-end;
}
.f-flex[data-align='stretch'] {
align-items: stretch;
}
.f-flex[data-align='baseline'] {
align-items: baseline;
}
/* Distribution */
.f-flex[data-justify='start'] {
justify-content: flex-start;
}
.f-flex[data-justify='center'] {
justify-content: center;
}
.f-flex[data-justify='end'] {
justify-content: flex-end;
}
.f-flex[data-justify='between'] {
justify-content: space-between;
}
.f-flex[data-justify='around'] {
justify-content: space-around;
}
.f-flex[data-justify='evenly'] {
justify-content: space-evenly;
}
}
</style>Related components
Grid A CSS grid layout container featuring track templates for fixed column counts, auto-fit, and auto-fill.Section A semantic page section wrapper offering eyebrow labels, headings, subtitles, and header action slots.SelectableCard An interactive card with checkmark or radio indicator and active highlight border for option picking.SplitPane A resizable two-pane container with a draggable divider bar supporting horizontal and vertical orientations…Stack A linear layout container for organizing child elements in flex columns or rows.BentoCell A modular cell designed for bento grids with configurable column and row track spans.