Layout primitives for building any kind of layout.

Layout components come unstyled and with a minimal API surface. LYTS is is less than 4kB when using all components and is also tree-shakable, so features that you don't use will not add to your bundle size.

Layout props

LYTS exposes layout-specific functionality as props on its components, each component has its own props specific for its problem domain. All layout components inherit props from Box making the following props available globally:

bleed: Optical alignment

Sometimes what is technically aligned is not visually aligned to our eyes. LYTS provides the bleed prop (as well as *Top/*Right/*Bottom/*Left), which makes it easy to nudge (or bleed) elements outside their bounding box to make them look visually aligned.

Slava Shestopalov's "Optical Effects in User Interfaces" dives into this topic in great detail.

xAlign/yAlign: Horizontal & vertical alignment

CSS Flexbox provides alignItems and justifyContent properties to control the alignment of children from the parent element. Depending on the flex-direction, each property controls a different axis.

LYTS normalizes this into xAlign and yAlign props, so you don't have to think about those details while writing layout code. Of course, manually setting alignItems/justifyContent still works as well.

asChild: Render as anything

By default, all LYTS components render a <div> element. This is not always desirable, because you should use semantic HTML wherever possible, which means changing the rendered element. To support this, LYTS provides the asChild prop on all components.

const MyComponent = function () {
  return (
    // Because of `asChild`, only the <a> element will be rendered, without an additionl wrapping div.
    <Row asChild gap={0.5}>
      <a href='/bla'>
        <span>Interesting link</span>
        <ArrowRightIcon />

The asChild API works exactly like all Radix UI components, and is even using their <Slot /> component under-the-hood. Check out the official documentation for Slot.