---
title: FormLayout
description: FormLayout
element: vaadin-form-layout
---

## Description

`<vaadin-form-layout>` is a Web Component providing configurable responsive
layout for form elements.

```html
<vaadin-form-layout>

  <vaadin-form-item>
    <label slot="label">First Name</label>
    <input class="full-width" value="Jane">
  </vaadin-form-item>

  <vaadin-form-item>
    <label slot="label">Last Name</label>
    <input class="full-width" value="Doe">
  </vaadin-form-item>

  <vaadin-form-item>
    <label slot="label">Email</label>
    <input class="full-width" value="jane.doe@example.com">
  </vaadin-form-item>

</vaadin-form-layout>
```

It supports any child elements as layout items.

By default, it makes a layout of two columns if the element width is equal or
wider than 40em, and a single column layout otherwise.

The number of columns and the responsive behavior are customizable with
the `responsiveSteps` property.

### Spanning Items on Multiple Columns

You can use `colspan` or `data-colspan` attribute on the items.
In the example below, the first text field spans on two columns:

```html
<vaadin-form-layout>

  <vaadin-form-item colspan="2">
    <label slot="label">Address</label>
    <input class="full-width">
  </vaadin-form-item>

  <vaadin-form-item>
    <label slot="label">First Name</label>
    <input class="full-width" value="Jane">
  </vaadin-form-item>

  <vaadin-form-item>
    <label slot="label">Last Name</label>
    <input class="full-width" value="Doe">
  </vaadin-form-item>

</vaadin-form-layout>
```

### Explicit New Row

Use the `<br>` line break element to wrap the items on a new row:

```html
<vaadin-form-layout>

  <vaadin-form-item>
    <label slot="label">Email</label>
    <input class="full-width">
  </vaadin-form-item>

  <br>

  <vaadin-form-item>
    <label slot="label">Confirm Email</label>
    <input class="full-width">
  </vaadin-form-item>

</vaadin-form-layout>
```

### Auto Responsive Mode

To avoid manually dealing with responsive breakpoints, Form Layout provides an auto-responsive mode
that automatically creates and adjusts fixed-width columns based on the container's available space.

The [`columnWidth`](/elements/vaadin-form-layout#columnwidth) and
[`maxColumns`](/elements/vaadin-form-layout#maxcolumns) properties define the width of
each column and the maximum number of columns that the component can create. By default, the component
creates up to 10 columns, each with a width of `12em` or the value of the `--vaadin-field-default-width`
CSS custom property, if defined.

The auto-responsive mode is disabled by default. To enable it for an individual instance, set the
`auto-responsive` attribute:

```html
<vaadin-form-layout auto-responsive>
  <vaadin-text-field label="First Name"></vaadin-text-field>
  <vaadin-text-field label="Last Name"></vaadin-text-field>
  <vaadin-text-area label="Address" colspan="2"></vaadin-text-area>
</vaadin-form-layout>
```

You can also enable it for all instances by enabling the following feature flag
before `<vaadin-form-layout>` elements are added to the DOM:

```js
window.Vaadin.featureFlags.defaultAutoResponsiveFormLayout = true;
```

#### Organizing Fields into Rows

By default, each field is placed on a new row. To organize fields into rows, you can either:

1. Manually wrap fields into [`<vaadin-form-row>`](/elements/vaadin-form-row) elements.

2. Enable the [`autoRows`](/elements/vaadin-form-layout#autorows) property to
   let Form Layout automatically arrange fields in available columns, wrapping to a new
   row when necessary. `<br>` elements can be used to force a new row.

Here is an example of using `<vaadin-form-row>`:

```html
<vaadin-form-layout auto-responsive>
  <vaadin-form-row>
    <vaadin-text-field label="First Name"></vaadin-text-field>
    <vaadin-text-field label="Last Name"></vaadin-text-field>
  </vaadin-form-row>
  <vaadin-form-row>
    <vaadin-text-area label="Address" colspan="2"></vaadin-text-area>
  </vaadin-form-row>
</vaadin-form-layout>
```

#### Expanding Columns and Fields

You can configure Form Layout to expand columns to evenly fill any remaining space after
all fixed-width columns have been created.
To enable this, set the [`expandColumns`](/elements/vaadin-form-layout#expandcolumns)
property to `true`.

Also, Form Layout can stretch fields to make them take up all available space within columns.
To enable this, set the [`expandFields`](/elements/vaadin-form-layout#expandfields)
property to `true`.

#### Customizing Label Position

By default, Form Layout displays labels above the fields. To put labels next to the fields,
enable the [`labelsAside`](/elements/vaadin-form-layout#labelsaside) property:

```html
<vaadin-form-layout auto-responsive labels-aside>
  <vaadin-form-row>
    <vaadin-text-field label="First Name"></vaadin-text-field>
    <vaadin-text-field label="Last Name"></vaadin-text-field>
  </vaadin-form-row>
  <vaadin-form-row>
    <vaadin-text-area label="Address" colspan="2"></vaadin-text-area>
  </vaadin-form-row>
</vaadin-form-layout>
```

When there isn't enough space for side labels, Form Layout returns the labels to
the default position above the fields.

All Vaadin input field components placed directly in the Form Layout support labels-aside
mode out of the box, showing their label next to the field. Checkable fields, such as
`<vaadin-checkbox>`, work differently: their label remains in place, and Form Layout only
indents such fields so they align with the input column.

Any other components, such as buttons or custom components, are just placed at the start of
the label column. How they should be laid out in this mode is left to the developer and can
be handled in one of two ways:

1. Wrap the component in a Form Item, with or without providing a label. The Form Item
   reserves space for the label, so the component ends up in the input column, aligned
   with the other fields:

   ```html
   <vaadin-form-item>
     <label slot="label">Name</label>
     <input type="text" />
   </vaadin-form-item>

   <vaadin-form-item>
     <vaadin-button>Submit</vaadin-button>
   </vaadin-form-item>
   ```

2. Write custom CSS. When labels are rendered next to fields, Form Layout sets the
   `has-labels-aside` attribute on its host element and the `data-form-layout-has-labels-aside`
   attribute on children. You can rely on these attributes to adapt your components to
   labels-aside mode, for example:

   ```css
   vaadin-button[data-form-layout-has-labels-aside] {
     margin-inline-start: calc(
       var(--vaadin-form-layout-label-width) +
       var(--vaadin-form-layout-label-spacing)
     );
   }
   ```

### CSS Properties Reference

The following custom CSS properties are available for styling:

Custom CSS property | Description | Default
---|---|---
`--vaadin-form-layout-column-spacing` | Length of the spacing between columns | `2em`
`--vaadin-form-layout-row-spacing` | Length of the spacing between rows | `1em`
`--vaadin-form-layout-label-width` | Width of the label when labels are displayed aside | `8em`
`--vaadin-form-layout-label-spacing` | Length of the spacing between the label and the field when labels are displayed aside | `1em`
`--vaadin-form-layout-label-text-align` | Alignment of the label when labels are displayed aside | `start`

The following state attributes are available for styling:

Attribute | Description
---|---
`has-labels-aside` | Set when the `labelsAside` property is enabled and there is enough space to display labels next to the fields

## Properties

### autoResponsive

**Type:** `boolean`

When set to `true`, the component automatically creates and adjusts columns based on
the container's width. Columns have a fixed width defined by `columnWidth` and their
number increases up to the limit set by `maxColumns`. The component dynamically adjusts
the number of columns as the container size changes. When this mode is enabled,
`responsiveSteps` are ignored.

By default, each field is placed on a new row. To organize fields into rows, there are
two options:

1. Use `<vaadin-form-row>` to explicitly group fields into rows.

2. Enable the `autoRows` property to automatically arrange fields in available columns,
   wrapping to a new row when necessary. `<br>` elements can be used to force a new row.

The auto-responsive mode is disabled by default. To enable it for an individual instance,
use this property. Alternatively, if you want it to be enabled for all instances by default,
enable the `defaultAutoResponsiveFormLayout` feature flag before `<vaadin-form-layout>`
elements are added to the DOM:

```js
window.Vaadin.featureFlags.defaultAutoResponsiveFormLayout = true;
```

### autoRows

**Type:** `boolean`

When enabled with `autoResponsive`, distributes fields across columns
by placing each field in the next available column and wrapping to
the next row when the current row is full. `<br>` elements can be
used to force a new row.

The default value is `false`.

### columnWidth

**Type:** `string`

When `autoResponsive` is enabled, defines the width of each column.
The value must be defined in CSS length units, e.g. `100px`.

If the column width isn't explicitly set, it defaults to `12em`
or `--vaadin-field-default-width` if that CSS property is defined.

### expandColumns

**Type:** `boolean`

When `autoResponsive` is enabled, specifies whether the columns should expand
in width to evenly fill any remaining space after all columns have been created.

The default value is `false`.

### expandFields

**Type:** `boolean`

When `autoResponsive` is enabled, specifies whether fields should stretch
to take up all available space within columns. This setting also applies
to fields inside `<vaadin-form-item>` elements.

The default value is `false`.

### labelsAside

**Type:** `boolean`

When enabled with `autoResponsive`, the layout puts labels next to
the fields. If the layout is too narrow for a single column with a
side label, the labels automatically return to their default position
above the fields.

The default value is `false`.

### maxColumns

**Type:** `number`

When `autoResponsive` is enabled, defines the maximum number of columns
that the layout can create. The layout will create columns up to this
limit based on the available container width.

The default value is `10`.

### minColumns

**Type:** `number`

When `autoResponsive` is enabled, defines the minimum number of columns
that the layout can create. The layout will create columns at least up
to this limit.

The default value is `1`.

### responsiveSteps

**Type:** `FormLayoutResponsiveStep[]`

Allows specifying a responsive behavior with the number of columns
and the label position depending on the layout width.

Format: array of objects, each object defines one responsive step
with `minWidth` CSS length, `columns` number, and optional
`labelsPosition` string of `"aside"` or `"top"`. At least one item is required.

NOTE: Responsive steps are ignored in auto-responsive mode, which may be
enabled explicitly via the `autoResponsive` property or implicitly
if the following feature flag is set:

```js
window.Vaadin.featureFlags.defaultAutoResponsiveFormLayout = true
```

#### Examples

```javascript
formLayout.responsiveSteps = [{columns: 1}];
// The layout is always a single column, labels aside.
```

```javascript
formLayout.responsiveSteps = [
  {minWidth: 0, columns: 1},
  {minWidth: '40em', columns: 2}
];
// Sets two responsive steps:
// 1. When the layout width is < 40em, one column, labels aside.
// 2. Width >= 40em, two columns, labels aside.
```

```javascript
formLayout.responsiveSteps = [
  {minWidth: 0, columns: 1, labelsPosition: 'top'},
  {minWidth: '20em', columns: 1},
  {minWidth: '40em', columns: 2}
];
// Default value. Three responsive steps:
// 1. Width < 20em, one column, labels on top.
// 2. 20em <= width < 40em, one column, labels aside.
// 3. Width >= 40em, two columns, labels aside.
```

See also: [FormLayoutResponsiveStep](#formlayoutresponsivestep)

## Types

### FormLayoutLabelsPosition

```ts
export type FormLayoutLabelsPosition = 'aside' | 'top';
```

### FormLayoutResponsiveStep

```ts
export type FormLayoutResponsiveStep = {
  minWidth?: string | 0;
  columns: number;
  labelsPosition?: FormLayoutLabelsPosition;
};
```


