> Markdown version of [Board](https://vaadin.com/docs/v24/components/board). Section index: [llms.txt](https://vaadin.com/docs/v24/components/llms.txt)

# Board

> **Note: Commercial Feature**
>
> A commercial Vaadin subscription is required to use Board in your project.
>
> - [Start Free Trial](https://vaadin.com/trial)
>
> - [See Pricing](https://vaadin.com/pricing)

Board is a powerful and easy-to-use layout element for building responsive views. It reorders the components inside it on different screen sizes while maximizing the use of available space.

**Lit** — `board-basic.ts`

```html
<vaadin-board>
  <vaadin-board-row>
    <example-indicator current="745" change="+33.7" title="Current users"></example-indicator>
    <example-indicator
      current="54.6k"
      change="-112.45"
      title="View events"
    ></example-indicator>
    <example-indicator
      current="18%"
      change="+3.9"
      title="Conversion rate"
    ></example-indicator>
    <example-indicator current="-123.45" title="Custom metric"></example-indicator>
  </vaadin-board-row>
  <vaadin-board-row>
    <example-chart></example-chart>
  </vaadin-board-row>
</vaadin-board>
```

**Lit** — `example-indicator.ts`

```typescript
import '@vaadin/icon';
import '@vaadin/icons';
import '@vaadin/vertical-layout';
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { applyTheme } from 'Frontend/generated/theme';

@customElement('example-indicator')
export class ExampleIndicator extends LitElement {
  static override styles = css`
    .title {
      margin: 0;
      font-size: var(--lumo-font-size-xxs);
      font-weight: 700;
      color: var(--lumo-contrast-50pct);
    }

    .current {
      font-size: var(--lumo-font-size-m);
      font-weight: 700;
    }

    .icon {
      font-size: var(--lumo-font-size-xxs);
    }

    .icon vaadin-icon {
      --vaadin-icon-width: var(--lumo-font-size-xxs);
      --vaadin-icon-height: var(--lumo-font-size-xxs);
    }

    @media (min-width: 1024px) {
      .title {
        font-size: var(--lumo-font-size-xxs);
      }

      .current {
        font-size: var(--lumo-font-size-xl);
      }

      .icon {
        font-size: var(--lumo-font-size-m);
      }

      .icon vaadin-icon {
        --vaadin-icon-width: var(--lumo-font-size-xs);
        --vaadin-icon-height: var(--lumo-font-size-xs);
      }
    }
  `;

  @property()
  title = 'Unknown';

  @property()
  current = '0';

  @property({ type: Number })
  change = 0;

  protected override createRenderRoot() {
    const root = super.createRenderRoot();
    // Apply custom theme (only supported if your app uses one)
    applyTheme(root);
    return root;
  }

  protected override render() {
    let theme;
    let icon;
    let sign;

    if (this.change === 0) {
      theme = '';
      icon = 'circle-thin';
      sign = '±';
    } else if (this.change < 0) {
      theme = 'error';
      icon = 'arrow-down';
      sign = '-';
    } else {
      theme = 'success';
      icon = 'arrow-up';
      sign = '+';
    }

    return html`
      <vaadin-vertical-layout>
        <div class="title">${this.title}</div>
        <div class="current">${this.current}</div>
        <span class="icon" theme="badge ${theme}">
          <vaadin-icon icon="vaadin:${icon}"></vaadin-icon>
          <span>${sign}${Math.abs(this.change).toFixed(2)}%</span>
        </span>
      </vaadin-vertical-layout>
    `;
  }
}
```

**Lit** — `example-chart.ts`

```typescript
import '@vaadin/charts';
import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { getViewEvents } from 'Frontend/demo/domain/DataService';
import type ViewEvent from 'Frontend/generated/com/vaadin/demo/domain/ViewEvent';

const monthNames = [
  'Jan',
  'Feb',
  'Mar',
  'Apr',
  'May',
  'Jun',
  'Jul',
  'Aug',
  'Sep',
  'Oct',
  'Nov',
  'Dec',
];

const chartOptions = {
  xAxis: { crosshair: true },
  yAxis: { min: 0 },
};

@customElement('example-chart')
export class Example extends LitElement {
  static override styles = css`
    .title {
      font-size: var(--lumo-font-size-l);
      font-weight: 700;
      margin-block-end: var(--lumo-space-m);
    }
  `;

  @state()
  private events: ViewEvent[] = [];

  protected override async firstUpdated() {
    this.events = await getViewEvents();
  }

  protected override render() {
    return html`
      <header class="title">View events</header>
      <vaadin-chart .additionalOptions="${chartOptions}" .categories="${monthNames}" type="area">
        ${repeat(
          this.events,
          ({ id }) => id,
          ({ city, data }) =>
            html`<vaadin-chart-series .title="${city}" .values="${data}"></vaadin-chart-series>`
        )}
      </vaadin-chart>
    `;
  }
}
```

**Flow** — `BoardBasic.java`

```java
Board board = new Board();
board.addRow(new ExampleIndicator("Current users", "745", "+33.7"),
        new ExampleIndicator("View events", "54.6k", "-112.45"),
        new ExampleIndicator("Conversion rate", "18%", "+3.9"),
        new ExampleIndicator("Custom metric", "-123.45"));
board.addRow(new ExampleChart());
```

**Flow** — `ExampleIndicator.java`

```java
package com.vaadin.demo.component.board;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;

@Tag("example-indicator")
public class ExampleIndicator extends Component {
    public ExampleIndicator(String title, String current, String change) {
        this.getElement().setAttribute("title", title)
                .setAttribute("current", current)
                .setAttribute("change", change);
    }

    public ExampleIndicator(String title, String current) {
        this.getElement().setAttribute("title", title).setAttribute("current",
                current);
    }
}
```

**Flow** — `ExampleChart.java`

```java
package com.vaadin.demo.component.board;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;

@Tag("example-chart")
public class ExampleChart extends Component {
}
```

**React** — `board-basic.tsx`

```tsx
<BoardRow>
  <ExampleIndicator current="745" change={+33.7} title="Current users" />
  <ExampleIndicator current="54.6k" change={-112.45} title="View events" />
  <ExampleIndicator current="18%" change={+3.9} title="Conversion rate" />
  <ExampleIndicator current="-123.45" title="Custom metric" />
</BoardRow>
<BoardRow>
  <ExampleChart />
</BoardRow>
```

**React** — `ExampleChart.tsx`

```tsx
const monthNames = [
  'Jan',
  'Feb',
  'Mar',
  'Apr',
  'May',
  'Jun',
  'Jul',
  'Aug',
  'Sep',
  'Oct',
  'Nov',
  'Dec',
];

const chartOptions = {
  xAxis: { crosshair: true },
  yAxis: { min: 0 },
};

function Example() {
  const events = useSignal<ViewEvent[]>([]);
  useEffect(() => {
    getViewEvents().then((viewEvents) => {
      events.value = viewEvents;
    });
  }, []);

  return (
    <div>
      <header style={titleStyle}>View events</header>

      <Chart additionalOptions={chartOptions} categories={monthNames} type="area">
        {events.value.map(({ id, city, data }) => (
          <ChartSeries title={city} values={data} key={id} />
        ))}
      </Chart>
    </div>
  );
}
```

**React** — `ExampleIndicator.tsx`

```tsx
function ExampleIndicator({ title = 'Unknown', current = '0', change = 0 }) {
  let theme;
  let icon;
  let sign;

  if (change === 0) {
    theme = '';
    icon = 'circle-thin';
    sign = '±';
  } else if (change < 0) {
    theme = 'error';
    icon = 'arrow-down';
    sign = '-';
  } else {
    theme = 'success';
    icon = 'arrow-up';
    sign = '+';
  }

  return (
    <VerticalLayout className="example-indicator">
      <div className="title">{title}</div>
      <div className="current">{current}</div>
      <span className={`icon badge`} {...{ theme: `badge ${theme}` }}>
        <Icon icon={`vaadin:${icon}`} />
        <span>
          {sign}
          {Math.abs(change).toFixed(2)}%
        </span>
      </span>
    </VerticalLayout>
  );
}
```

Use Board to create responsive views and dashboards that work on any screen size.

## <a id="responsive"></a>Responsive

Board is responsive by default, meaning that it doesn’t require any custom development. Its layout is automatically optimized and adjusted based on the screen size, ensuring that the components utilize all available space.

## <a id="rows-columns"></a>Rows & Columns

Board is made up of rows. Each row supports up to four columns and can contain up to four components.

### <a id="nested-rows"></a>Nested Rows

Rows can be nested for finer-grained control of how certain areas of the layout behave on resize, and how they are rendered.

**Lit** — `board-nested.ts`

```html
<vaadin-board>
  <vaadin-board-row>
    <example-statistics board-cols="2"></example-statistics>
    <vaadin-board-row board-cols="1">
      <example-indicator
        current="745"
        change="+33.7"
        title="Current users"
      ></example-indicator>
      <example-indicator
        current="18%"
        change="+3.9"
        title="Conversion rate"
      ></example-indicator>
    </vaadin-board-row>
  </vaadin-board-row>
</vaadin-board>
```

**Lit** — `example-indicator.ts`

```typescript
import '@vaadin/icon';
import '@vaadin/icons';
import '@vaadin/vertical-layout';
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { applyTheme } from 'Frontend/generated/theme';

@customElement('example-indicator')
export class ExampleIndicator extends LitElement {
  static override styles = css`
    .title {
      margin: 0;
      font-size: var(--lumo-font-size-xxs);
      font-weight: 700;
      color: var(--lumo-contrast-50pct);
    }

    .current {
      font-size: var(--lumo-font-size-m);
      font-weight: 700;
    }

    .icon {
      font-size: var(--lumo-font-size-xxs);
    }

    .icon vaadin-icon {
      --vaadin-icon-width: var(--lumo-font-size-xxs);
      --vaadin-icon-height: var(--lumo-font-size-xxs);
    }

    @media (min-width: 1024px) {
      .title {
        font-size: var(--lumo-font-size-xxs);
      }

      .current {
        font-size: var(--lumo-font-size-xl);
      }

      .icon {
        font-size: var(--lumo-font-size-m);
      }

      .icon vaadin-icon {
        --vaadin-icon-width: var(--lumo-font-size-xs);
        --vaadin-icon-height: var(--lumo-font-size-xs);
      }
    }
  `;

  @property()
  title = 'Unknown';

  @property()
  current = '0';

  @property({ type: Number })
  change = 0;

  protected override createRenderRoot() {
    const root = super.createRenderRoot();
    // Apply custom theme (only supported if your app uses one)
    applyTheme(root);
    return root;
  }

  protected override render() {
    let theme;
    let icon;
    let sign;

    if (this.change === 0) {
      theme = '';
      icon = 'circle-thin';
      sign = '±';
    } else if (this.change < 0) {
      theme = 'error';
      icon = 'arrow-down';
      sign = '-';
    } else {
      theme = 'success';
      icon = 'arrow-up';
      sign = '+';
    }

    return html`
      <vaadin-vertical-layout>
        <div class="title">${this.title}</div>
        <div class="current">${this.current}</div>
        <span class="icon" theme="badge ${theme}">
          <vaadin-icon icon="vaadin:${icon}"></vaadin-icon>
          <span>${sign}${Math.abs(this.change).toFixed(2)}%</span>
        </span>
      </vaadin-vertical-layout>
    `;
  }
}
```

**Lit** — `example-statistics.ts`

```typescript
import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { getServiceHealth } from 'Frontend/demo/domain/DataService';
import type ServiceHealth from 'Frontend/generated/com/vaadin/demo/domain/ServiceHealth';

@customElement('example-statistics')
export class ExampleStatistics extends LitElement {
  static override styles = css`
    :host {
      display: flex;
      flex-direction: column;
      font-size: var(--lumo-font-size-s);
    }

    .level {
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .level::before {
      content: '';
      width: var(--lumo-font-size-xxs);
      height: var(--lumo-font-size-xxs);
      border-radius: 50%;
    }

    .excellent::before {
      background-color: var(--lumo-success-color);
    }

    .ok::before {
      background-color: var(--lumo-primary-color);
    }

    .failing::before {
      background-color: var(--lumo-error-color);
    }

    .legend {
      display: flex;
    }

    .legend label {
      display: flex;
      align-items: center;
      margin-inline-end: var(--lumo-space-m);
    }

    .legend .level {
      margin-inline-end: var(--lumo-space-s);
    }

    .title {
      font-size: var(--lumo-font-size-l);
      font-weight: 700;
    }

    .table {
      overflow: auto;
      flex-grow: 1;
    }

    .table table {
      width: 100%;
      margin-block-start: var(--lumo-space-s);
    }

    .table .number {
      text-align: end;
    }

    .table th,
    .table td {
      white-space: nowrap;
    }
  `;

  @state()
  private serviceHealth: ServiceHealth[] = [];

  protected override async firstUpdated() {
    this.serviceHealth = await getServiceHealth();
  }

  protected override render() {
    return html`
      <header class="title">Service health</header>
      <section class="legend">
        <label>
          <span class="level excellent"></span>
          Excellent
        </label>
        <label>
          <span class="level ok"></span>
          Ok
        </label>
        <label>
          <span class="level failing"></span>
          Failing
        </label>
      </section>
      <div class="table">
        <table>
          <thead>
            <tr>
              <th></th>
              <th>City</th>
              <th>Input</th>
              <th>Output</th>
            </tr>
          </thead>
          <tbody>
            ${repeat(
              this.serviceHealth,
              ({ id }) => id,
              ({ city, input, output }) => html`
                <tr>
                  <td>
                    <span class="level ok"></span>
                  </td>
                  <td>${city}</td>
                  <td class="number">${input}</td>
                  <td class="number">${output}</td>
                </tr>
              `
            )}
          </tbody>
        </table>
      </div>
    `;
  }
}
```

**Flow** — `BoardNested.java`

```java
Row rootRow = new Row();
rootRow.add(new ExampleStatistics(), 2);

Row nestedRow = new Row(
        new ExampleIndicator("Current users", "745", "+33.7"),
        new ExampleIndicator("Conversion rate", "18%", "+3.9"));
rootRow.addNestedRow(nestedRow);

Board board = new Board();
board.add(rootRow);
```

**Flow** — `ExampleIndicator.java`

```java
package com.vaadin.demo.component.board;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;

@Tag("example-indicator")
public class ExampleIndicator extends Component {
    public ExampleIndicator(String title, String current, String change) {
        this.getElement().setAttribute("title", title)
                .setAttribute("current", current)
                .setAttribute("change", change);
    }

    public ExampleIndicator(String title, String current) {
        this.getElement().setAttribute("title", title).setAttribute("current",
                current);
    }
}
```

**Flow** — `ExampleStatistics.java`

```java
package com.vaadin.demo.component.board;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;

@Tag("example-statistics")
public class ExampleStatistics extends Component {
}
```

**React** — `board-nested.tsx`

```tsx
<Board className="board-nested">
  <BoardRow>
    <div {...{ 'board-cols': 2 }}>
      <ExampleStatistics {...{ 'board-cols': 2 }} />
    </div>
    <BoardRow {...{ 'board-cols': 1 }}>
      <ExampleIndicator current="745" change={+33.7} title="Current users" />
      <ExampleIndicator current="18%" change={+3.9} title="Conversion rate" />
    </BoardRow>
  </BoardRow>
</Board>
```

**React** — `ExampleIndicator.tsx`

```tsx
function ExampleIndicator({ title = 'Unknown', current = '0', change = 0 }) {
  let theme;
  let icon;
  let sign;

  if (change === 0) {
    theme = '';
    icon = 'circle-thin';
    sign = '±';
  } else if (change < 0) {
    theme = 'error';
    icon = 'arrow-down';
    sign = '-';
  } else {
    theme = 'success';
    icon = 'arrow-up';
    sign = '+';
  }

  return (
    <VerticalLayout className="example-indicator">
      <div className="title">{title}</div>
      <div className="current">{current}</div>
      <span className={`icon badge`} {...{ theme: `badge ${theme}` }}>
        <Icon icon={`vaadin:${icon}`} />
        <span>
          {sign}
          {Math.abs(change).toFixed(2)}%
        </span>
      </span>
    </VerticalLayout>
  );
}
```

**React** — `ExampleStatistics.tsx`

```tsx
function ExampleStatistics() {
  const serviceHealth = useSignal<ServiceHealth[]>([]);
  useEffect(() => {
    getServiceHealth().then((health) => {
      serviceHealth.value = health;
    });
  }, []);

  return (
    <div className="statistics">
      <header className="title">Service health</header>
      <section className="legend">
        <label>
          <span className="level excellent"></span>
          Excellent
        </label>
        <label>
          <span className="level ok"></span>
          Ok
        </label>
        <label>
          <span className="level failing"></span>
          Failing
        </label>
      </section>
      <div className="table">
        <table>
          <thead>
            <tr>
              <th></th>
              <th>City</th>
              <th>Input</th>
              <th>Output</th>
            </tr>
          </thead>
          <tbody>
            {serviceHealth.value.map(({ id, city, input, output }) => (
              <tr key={id}>
                <td>
                  <span className="level ok" />
                </td>
                <td>{city}</td>
                <td className="number">{input}</td>
                <td className="number">{output}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
```

### <a id="column-wrapping"></a>Column Wrapping

Columns automatically wrap on to new lines as the viewport narrows. The wrapping behavior for a row with four columns and four components is shown below.

> **Important:** Use the draggable split handle to resize the layout and see how the columns wrap.

**Lit** — `board-column-wrapping.ts`

```html
<vaadin-split-layout>
  <vaadin-board style="width: 100%">
    <vaadin-board-row class="row">
      <div class="cell color">Cell 1</div>
      <div class="cell color">Cell 2</div>
      <div class="cell color">Cell 3</div>
      <div class="cell color">Cell 4</div>
    </vaadin-board-row>
  </vaadin-board>
  <div></div>
</vaadin-split-layout>
```

**Flow** — `BoardColumnWrapping.java`

```java
Board board = new Board();
board.addRow(createCell("Cell 1"), createCell("Cell 2"),
        createCell("Cell 3"), createCell("Cell 4"));

SplitLayout splitLayout = new SplitLayout(board, new Div());
```

**React** — `board-column-wrapping.tsx`

```tsx
<SplitLayout className="board-column-wrapping">
  <Board style={{ width: '100%' }}>
    <BoardRow className="row">
      <div className="cell color">Cell 1</div>
      <div className="cell color">Cell 2</div>
      <div className="cell color">Cell 3</div>
      <div className="cell color">Cell 4</div>
    </BoardRow>
  </Board>
  <div></div>
</SplitLayout>
```

### <a id="column-span"></a>Column Span

By default, the components in a row share the space equally. A component can be made to stretch across two or three columns by setting its column span.

The possible combinations are shown below:

**Lit** — `board-column-span.ts`

```html
<vaadin-board>
  <vaadin-board-row>
    <div class="cell" board-cols="2">Span 2</div>
    <div class="cell">Span 1</div>
    <div class="cell">Span 1</div>
  </vaadin-board-row>
  <vaadin-board-row>
    <div class="cell">Span 1</div>
    <div class="cell" board-cols="2">Span 2</div>
    <div class="cell">Span 1</div>
  </vaadin-board-row>
  <vaadin-board-row>
    <div class="cell">Span 1</div>
    <div class="cell">Span 1</div>
    <div class="cell" board-cols="2">Span 2</div>
  </vaadin-board-row>
</vaadin-board>
<vaadin-board>
  <vaadin-board-row>
    <div class="cell" board-cols="3">Span 3</div>
    <div class="cell">Span 1</div>
  </vaadin-board-row>
  <vaadin-board-row>
    <div class="cell">Span 1</div>
    <div class="cell" board-cols="3">Span 3</div>
  </vaadin-board-row>
</vaadin-board>
<vaadin-board>
  <vaadin-board-row>
    <div class="cell" board-cols="2">Span 2</div>
    <div class="cell">Span 1</div>
  </vaadin-board-row>
  <vaadin-board-row>
    <div class="cell">Span 1</div>
    <div class="cell" board-cols="2">Span 2</div>
  </vaadin-board-row>
</vaadin-board>
```

**Flow** — `BoardColumnSpan.java`

```java
Board board1 = createBoard1();
Board board2 = createBoard2();
Board board3 = createBoard3();

...

private static Board createBoard1() {
    Row row1 = new Row();
    row1.add(createCell("Span 2"), 2);
    row1.add(createCell("Span 1"));
    row1.add(createCell("Span 1"));

    Row row2 = new Row();
    row2.add(createCell("Span 1"));
    row2.add(createCell("Span 2"), 2);
    row2.add(createCell("Span 1"));

    Row row3 = new Row();
    row3.add(createCell("Span 1"));
    row3.add(createCell("Span 1"));
    row3.add(createCell("Span 2"), 2);

    Board board = new Board();
    board.add(row1, row2, row3);

    return board;
}

private static Board createBoard2() {
    Row row1 = new Row();
    row1.add(createCell("Span 3"), 3);
    row1.add(createCell("Span 1"));

    Row row2 = new Row();
    row2.add(createCell("Span 1"));
    row2.add(createCell("Span 3"), 3);

    Board board = new Board();
    board.add(row1, row2);

    return board;
}

private static Board createBoard3() {
    Row row1 = new Row();
    row1.add(createCell("Span 2"), 2);
    row1.add(createCell("Span 1"));

    Row row2 = new Row();
    row2.add(createCell("Span 1"));
    row2.add(createCell("Span 2"), 2);

    Board board = new Board();
    board.add(row1, row2);

    return board;
}
```

**React** — `board-column-span.tsx`

```tsx
<Board className="board-column-span">
  <BoardRow>
    <div className="cell" {...{ 'board-cols': '2' }}>
      Span 2
    </div>
    <div className="cell">Span 1</div>
    <div className="cell">Span 1</div>
  </BoardRow>
  <BoardRow>
    <div className="cell">Span 1</div>
    <div className="cell" {...{ 'board-cols': '2' }}>
      Span 2
    </div>
    <div className="cell">Span 1</div>
  </BoardRow>
  <BoardRow>
    <div className="cell">Span 1</div>
    <div className="cell">Span 1</div>
    <div className="cell" {...{ 'board-cols': '2' }}>
      Span 2
    </div>
  </BoardRow>
</Board>

<Board className="board-column-span">
  <BoardRow>
    <div className="cell" {...{ 'board-cols': '3' }}>
      Span 3
    </div>
    <div className="cell">Span 1</div>
  </BoardRow>
  <BoardRow>
    <div className="cell">Span 1</div>
    <div className="cell" {...{ 'board-cols': '3' }}>
      Span 3
    </div>
  </BoardRow>
</Board>

<Board className="board-column-span">
  <BoardRow>
    <div className="cell" {...{ 'board-cols': '2' }}>
      Span 2
    </div>
    <div className="cell">Span 1</div>
  </BoardRow>
  <BoardRow>
    <div className="cell">Span 1</div>
    <div className="cell" {...{ 'board-cols': '2' }}>
      Span 2
    </div>
  </BoardRow>
</Board>
```

## <a id="breakpoints"></a>Breakpoints

Board adjusts its layout based on the layout container width. The following three container widths, called breakpoints, trigger a layout change:

| Breakpoint | Container width | Max number of columns         |
| ---------- | --------------- | ----------------------------- |
| large      | ≥ 960 pixels    | 4                             |
| medium     | 600–959 pixels  | 2 or 3\[[1](#_footnotedef_1)] |
| small      | < 600 pixels    | 1                             |

Breakpoints can be customized by overriding the CSS custom properties `--vaadin-board-width-small` and `--vaadin-board-width-medium`.

### <a id="breakpoint-specific-styling"></a>Breakpoint-Specific Styling

You can apply different styles for each breakpoint, for example to change the font size and space between components.

> **Important:** Use the draggable split handle to resize the layout and see how the board styling changes at different breakpoints.

**Lit** — `board-breakpoints.ts`

```typescript
protected override render() {
  return html`
    <vaadin-split-layout>
      <vaadin-board style="width: 100%">
        <!-- styles are defined separately, check the board.css snippet -->
        <vaadin-board-row>
          <div class="cell">Cell 1</div>
          <div class="cell">Cell 2</div>
          <div class="cell">Cell 3</div>
          <div class="cell">Cell 4</div>
        </vaadin-board-row>
      </vaadin-board>
      <div></div>
    </vaadin-split-layout>
  `;
}
```

**Lit** — `board.css`

```css
/* should be added to frontend/theme/[my-theme]/styles.css */
vaadin-board-row.large > .cell {
    background: var(--lumo-success-color-10pct);
    color: var(--lumo-success-color);
}

vaadin-board-row.medium > .cell {
    background: var(--lumo-primary-color-10pct);
    color: var(--lumo-primary-color);
}

vaadin-board-row.small > .cell {
    background: var(--lumo-error-color-10pct);
    color: var(--lumo-error-color);
}
```

**Flow** — `BoardBreakpoints.java`

```java
Board board = new Board();

// styles are defined separately, check the board.css snippet
board.addRow(createCell("Cell 1"), createCell("Cell 2"),
        createCell("Cell 3"), createCell("Cell 4"));

SplitLayout splitLayout = new SplitLayout(board, new Div());
```

**Flow** — `board.css`

```css
/* should be added to frontend/theme/[my-theme]/styles.css */
vaadin-board-row.large > .cell {
    background: var(--lumo-success-color-10pct);
    color: var(--lumo-success-color);
}

vaadin-board-row.medium > .cell {
    background: var(--lumo-primary-color-10pct);
    color: var(--lumo-primary-color);
}

vaadin-board-row.small > .cell {
    background: var(--lumo-error-color-10pct);
    color: var(--lumo-error-color);
}
```

**React** — `board-breakpoints.tsx`

```tsx
return (
  <SplitLayout className="board-breakpoints">
    <Board style={{ width: '100%' }}>
      <BoardRow>
        <div className="cell">Cell 1</div>
        <div className="cell">Cell 2</div>
        <div className="cell">Cell 3</div>
        <div className="cell">Cell 4</div>
      </BoardRow>
    </Board>
    <div></div>
  </SplitLayout>
);
```

`C2E98F9B-DC19-4C1D-8538-843235BA8701`

---

[1](#_footnoteref_1). A row with three equal-width components doesn’t wrap until the small breakpoint.
