Teeny-tiny flexbox grid for React. 2kb gzipped.
- No boilerplate, no config
- Outputs Real CSS™
- Nestable
- Uses relative units (em)
- SSR API
ffx exports two components, Flex
and Box
. Flex
is designed to be the wrapper and immediate parent of Box
.
import { Flex, Box } from 'ffx'
<Flex>
<Box />
<Box />
</Flex>
Examples:
// 1em gutter
<Flex gutter={1} />
// 1em gutter, 2em gutter above 800px
<Flex gutter={[ 1, [ 800, 2 ] ]} />
// wrappable flexbox
<Flex wrap={true} />
// wrappable flexbox, nowrap above 800px
<Flex wrap={[ true, [ 800, false ] ]} />
// passed directly to align-items
<Flex alignItems='flex-start' />
// passed directly to justifyContent
<Flex justifyContent='flex-start' />
// 50% wide
<Box width={1/2} /> // or <Box width={0.5} />
// 100% wide, 50% wide above 800px
<Box width={[ 1, [ 800, 1/2 ] ]} />
// 200px wide
<Box width='200px' />
// fill available space
<Box width='auto' />
// 200px wide, auto width above 800px
<Box width={[ '200px', [ 800, 'auto' ] ]} />
// flex order
<Box order={-1} />
// flex order
<Box order={[ -1, [ 800, 'unset' ] ]} />
// offset by 25%
<Box offset={1/4} width={1/2} />
// offset by 50% above 800px
<Box offset={[[800, 1/2]]} width={[ 1, [ 800, 1/2 ] ]} />
CSS output from above elements:
.⚡︎0{margin-left: -0.5em; margin-right: -0.5em}.⚡︎1{flex-wrap: nowrap}.⚡︎3{margin-left: -0em; margin-right: -0em}.⚡︎4{flex-wrap: wrap}@media(min-width:50em){.⚡︎5{flex-wrap: nowrap}}@media(min-width:50em){.⚡︎2{margin-left: -1em; margin-right: -1em}}
Grids are fully nestable.
<Flex gutter={1}>
<Box width={1/3} />
<Box width={2/3}>
<Flex gutter={1}>
<Box width={1/2} />
<Box width={1/2} />
</Flex>
</Box>
</Flex>
This isn't production code, just a simplified example.
import { getCSS } from 'ffx'
const html = renderToString(<App />)
const css = getCSS()
res.send(`
<!DOCTYPE html>
<html>
<head>
<style id="ffx">${css}</style>
</head>
<body>${html}</body>
</html>
`)
MIT License