# Styling

> Colors, border styles, and flexbox layout for voxal terminal UIs

Styling a voxal UI is colors, borders, and flexbox layout. Colors apply to `<Text>` and `<Box>`, borders to `<Box>`, and layout to every `<Box>` through the same props Yoga gives the web. This page covers the formats and a few recipes.

## Colors

The `color`, `backgroundColor`, and `borderColor` props (and the per-edge border colors) all accept the same color formats.

| Format | Example |
| --- | --- |
| Named color | `'green'`, `'brightRed'`, `'redBright'`, `'default'` |
| Hex | `'#0f0'`, `'#00ff00'` |
| RGB string | `'rgb(255, 128, 0)'` |
| ANSI 256 string | `'ansi256(208)'` |
| Palette index | `208` (a number 0 to 255) |
| RGB array | `[255, 128, 0]` |

The named colors are `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, and `gray` (also spelled `grey`), plus the bright variants written either way, like `brightRed` or `redBright`. `'default'` resets to the terminal's own default.

```jsx
<Text color="cyan">named</Text>
<Text color="#ff8800">hex</Text>
<Text color="rgb(255, 136, 0)">rgb</Text>
<Text color={[255, 136, 0]}>array</Text>
<Box backgroundColor="ansi256(236)" padding={1}>
  <Text>panel</Text>
</Box>
```

### Downsampling

Not every terminal renders 24-bit color. The [`colors` render option](/sdk/ui/rendering#renderoptions) sets the output depth and downsamples everything you write to it:

| Value | Output |
| --- | --- |
| `'truecolor'` | Full 24-bit color (default). |
| `'256'` | The 256-color palette. |
| `'16'` | The 16 standard ANSI colors. |
| `'none'` | No color; styles like `bold` still apply. |

```jsx
serve(() => <App />, { colors: '256' });
```

Author in truecolor and let downsampling handle older terminals. You do not pick palette indices by hand unless you want to.

## Border styles

Set `borderStyle` on a `<Box>` to one of these names:

| Name | Look |
| --- | --- |
| `single` | `┌─┐ │ └─┘` |
| `double` | `╔═╗ ║ ╚═╝` |
| `round` | `╭─╮ │ ╰─╯` |
| `bold` | `┏━┓ ┃ ┗━┛` |
| `singleDouble` | single sides, double top and bottom |
| `doubleSingle` | double sides, single top and bottom |
| `classic` | `+-+ | +-+` |
| `arrow` | corners drawn with arrows |

```jsx
<Box borderStyle="round" padding={1}>
  <Text>rounded</Text>
</Box>
```

You can also pass a custom object with the keys `topLeft`, `top`, `topRight`, `right`, `bottomRight`, `bottom`, `bottomLeft`, and `left`:

```jsx
<Box
  borderStyle={{
    topLeft: '*', top: '-', topRight: '*', right: '|',
    bottomRight: '*', bottom: '-', bottomLeft: '*', left: '|',
  }}
  padding={1}
>
  <Text>custom border</Text>
</Box>
```

Color the border with `borderColor` (or per edge with `borderTopColor` and friends), dim it with `borderDimColor`, and drop edges with `borderTop={false}` and the other per-edge toggles. See [Box borders](/sdk/ui/components#borders).

## Layout with flexbox

Layout is real flexbox, powered by Yoga. Every `<Box>` is a flex container, and you compose rows and columns by nesting boxes. The properties are the web's, applied to cells instead of pixels.

- `flexDirection` sets the main axis: `'row'` (default) lays children left to right, `'column'` top to bottom.
- `justifyContent` distributes children along the main axis: `'flex-start'`, `'center'`, `'flex-end'`, `'space-between'`, `'space-around'`.
- `alignItems` aligns children along the cross axis: `'flex-start'`, `'center'`, `'flex-end'`, `'stretch'`.
- `gap` puts space between children without adding it at the edges.
- `padding` adds space inside the border; `margin` adds it outside.
- `width` and `height` take cells (`20`), a percent of the parent (`'50%'`), or `'auto'`.
- `flexGrow` lets a box absorb free space; [`<Spacer />`](/sdk/ui/components#spacer) is shorthand for `flexGrow: 1`.

### Recipe: a centered box

Fill the viewport, then center on both axes.

```jsx
function Centered({ children }) {
  const { columns, rows } = useWindowSize();
  return (
    <Box width={columns} height={rows} justifyContent="center" alignItems="center">
      <Box borderStyle="round" padding={1}>{children}</Box>
    </Box>
  );
}
```

### Recipe: a two-column row

Two panels side by side. `flexGrow` splits the width; `gap` keeps them apart.

```jsx
<Box gap={1}>
  <Box flexGrow={1} borderStyle="single" padding={1}>
    <Text>left</Text>
  </Box>
  <Box flexGrow={1} borderStyle="single" padding={1}>
    <Text>right</Text>
  </Box>
</Box>
```

### Recipe: header, body, footer

A full-height column with a [`<Spacer />`](/sdk/ui/components#spacer) that pushes the footer to the bottom.

```jsx
function Layout() {
  const { rows } = useWindowSize();
  return (
    <Box flexDirection="column" height={rows}>
      <Box borderStyle="single" paddingX={1}>
        <Text bold>header</Text>
      </Box>
      <Box paddingX={1}>
        <Text>body content</Text>
      </Box>
      <Spacer />
      <Box paddingX={1}>
        <Text dimColor>footer</Text>
      </Box>
    </Box>
  );
}
```

<Callout title="Tip">
For a deeper walkthrough of composing layouts, see the [building UIs guide](/guides/building-uis).
</Callout>

---

Source: https://docs.voxal.sh/sdk/ui/styling
