---
name: Sizing principle
route: /principle-sizing/
---

import { Playground } from 'docz';
import { Vertical, Horizontal, Stretch, Content, Box } from '../..'; 
import * as demos from '../../demos'; 

<demos.Star/>

# Sizing
When thinking about the size of a container you need to think about *explicit* size and *implicit* sizing. We cover these concepts below.

## SizeProps (Explicit size)

```ts
/** 
 * Add support for explicit size
 */
export interface SizeProps {
  height?: CSSLength,
  minHeight?: CSSLength,
  maxHeight?: CSSLength,

  width?: CSSLength,
  minWidth?: CSSLength,
  maxWidth?: CSSLength,
}
```

Explicit sizes are driven by `width,height,minHeight,minWidth,maxHeight,maxWidth` arguments. You can have an explicit value on only one dimension e.g. here we have a simple `Vertical` container with explicit `height` only: 

<Playground>
  <Vertical height={100} style={{backgroundColor: "lightskyblue"}}>
    Hello world
  </Vertical>
</Playground>


This is essentially what you are doing in most design tools out there. Sadly explicit `height+width` sizing does not scale to *real* applications, where sizes need to be reactive to either their parent or their content. Fortunately we provide concepts to handle these cases with ***implicit sizing*** concepts we cover next.


## SizingProp (Implicit sizing)
> Implicit sizing controls the component behaviour when no explicit size properties are provided.

The `SizingProp` is what controls the implicit sizing (content / stretch / stretch-ratio) features: 

```ts
/** 
 * Specifies sizing interaction
 */
export interface SizingProp {
  /** 
   * Specifies `sizing` interaction
   */
  sizing?:
  | 'content' /** default */
  | 'stretch' /** Same as `1` */
  | number /** A stretch ratio */;
}
```

We cover these individually below:

### Content sized
A content sized component takes up as much space as needed by the children. This is the most common sizing that you want and is therefore the default for our containers.

In the example below, we have an explicit sized `Vertical` (background `lightskyblue`) with an inner content-sized `Vertical` (background `darkorange`). The inner vertical keeps it size to match whatever is needed by its children (observed below as you see the background of the parent-lightskyblue where the child-darkorange ends).

<Playground>
  <Vertical height={100} style={{backgroundColor: "lightskyblue"}}>
    <Vertical style={{backgroundColor: "darkorange"}}>
        I'm taking up as much space as needed by my children
    </Vertical>  
  </Vertical>
</Playground>

> You can set sizing to `content` explicitly as well if you want (`sizing={'content'}`)

### Stretch sized
A stretch sized component takes up as much space as offered by the parent. 

In the example below, we have an explicit sized `Vertical` (background `lightskyblue`) with an inner stretch-sized `Vertical` (background `darkorange`). The inner vertical keeps its size to match that of the outer container (observed below as you don't see the background of the parent-lightskyblue as it is filled in by the child-darkorange).

<Playground>
  <Vertical height={100} style={{backgroundColor: "lightskyblue"}}>
    <Vertical sizing={'stretch'} style={{backgroundColor: "darkorange"}}>
        I'm taking up all the space from the parent
    </Vertical>  
  </Vertical>
</Playground>

### Stretch ratios
With stretch sizing, you can specify `number` values. This controls how much you want different items dividing the space provided by their parent. e.g. We have `1` and `2` as the sizing on the children of the following horizontal:

<Playground>
  <Horizontal height={100} spacing={0} style={{backgroundColor: "lightskyblue"}}>
    <Stretch sizing={1} style={{backgroundColor: "darkorange"}}>
        I'm taking 1
    </Stretch>  
    <Stretch sizing={2} style={{backgroundColor: "lightpink"}}>
        I'm taking 2
    </Stretch>
  </Horizontal>
</Playground>

## Mixing

You can mix `Stretch`, `Content` and explicit sizing to match your design requirements as shown in the example below (`explicit,content,stretch 1,stretch 2`):

<Playground>
  <Horizontal height={100} spacing={0} style={{backgroundColor: "lightskyblue"}}>
    {/* Explicit width 100 */ }
    <Content width={100} style={{backgroundColor: "limegreen"}}>Exactly 100px</Content>
    {/* Implicit content */ }
    <Content style={{backgroundColor: "gold"}}>As much as I need</Content>
    {/* Implicit stretch sizing = 1 */ }
    <Stretch sizing={1} style={{backgroundColor: "darkorange"}}>
        I'm taking 1 from remainder
    </Stretch>  
    {/* Implicit stretch sizing = 2 */ }
    <Stretch sizing={2} style={{backgroundColor: "lightpink"}}>
        I'm taking 2 from remainder
    </Stretch>
  </Horizontal>
</Playground>

## Additional Guidance

### Explicit Size requires sizing='content'

`sizing=stretch` takes precedence on any explicit sizing e.g. `width` has no effect in the following example:

<Playground>
  <Horizontal height={100} spacing={0} style={{backgroundColor: "lightskyblue"}}>
    {/* Explicit width 100 */ }
    <Box sizing='stretch' width={100} style={{backgroundColor: "limegreen"}}>Width 100px will not work because of `sizing=stretch`</Box>
  </Horizontal>
</Playground>

For for explicit size to work sizing needs to be `content`. All our components are `sizing=content` by default so you don't need to think about it when using our components. The following example demonstrates this default: 

<Playground>
  <Horizontal height={100} spacing={0} style={{backgroundColor: "lightskyblue"}}>
    {/* Explicit width 100 */ }
    <Box width={100} style={{backgroundColor: "limegreen"}}>Width 100px works</Box>
  </Horizontal>
</Playground>
