My Design System

Form Layout

Form Layout allows you to build responsive forms with multiple columns and to position input labels on top or to the side of the input.

Open in a
new tab
private responsiveSteps: FormLayoutResponsiveStep[] = [
  // Use one column by default
  { minWidth: 0, columns: 1 },
  // Use two columns, if layout's width exceeds 500px
  { minWidth: '500px', columns: 2 },
];

render() {
  return html`
    <vaadin-form-layout .responsiveSteps="${this.responsiveSteps}">
      <vaadin-text-field label="First name"></vaadin-text-field>
      <vaadin-text-field label="Last name"></vaadin-text-field>
      <!-- Stretch the username field over 2 columns -->
      <vaadin-text-field colspan="2" label="Username"></vaadin-text-field>
      <vaadin-password-field label="Password"> </vaadin-password-field>
      <vaadin-password-field label="Confirm password"> </vaadin-password-field>
    </vaadin-form-layout>
  `;
}

Columns

Form Layout has two columns by default meaning it displays two input fields per line. When the layout width is smaller it adjusts to a single column layout.

Custom Layout

You can define how many columns Form Layout should use based on the screen width.

Important
Use the draggable split handle to resize Form Layout’s available space and test its responsiveness.
Open in a
new tab
private responsiveSteps: FormLayoutResponsiveStep[] = [
  // Use one column by default
  { minWidth: 0, columns: 1 },
  // Use two columns, if the layout's width exceeds 320px
  { minWidth: '320px', columns: 2 },
  // Use three columns, if the layout's width exceeds 500px
  { minWidth: '500px', columns: 3 },
];

render() {
  return html`
    <vaadin-split-layout>
      <vaadin-form-layout .responsiveSteps="${this.responsiveSteps}">
        <vaadin-text-field label="First name"></vaadin-text-field>
        <vaadin-text-field label="Last name"></vaadin-text-field>
        <vaadin-email-field label="Email"></vaadin-email-field>
      </vaadin-form-layout>
      <div></div>
    </vaadin-split-layout>
  `;
}

A single column layout is preferable to a multi column one. A multi column layout is more prone to cause confusion and to be misinterpreted by the user.

However, closely related fields can be placed in line without issue. For example, first and last name, address fields such as postal code and city, as well as ranged input for dates, time, currency, etc.

Column Span

When using a multi column layout you can define a colspan for each component. colspan determines how many columns a component extends or stretches across.

For example, if you have a Form Layout with three columns and a component’s colspan is set to three, it takes up the entire width of the Form Layout.

Open in a
new tab
<vaadin-text-field label="Title" colspan="3"></vaadin-text-field>

Label Position

Input fields' built-in labels are positioned above the input. Form Layout supports side positioned labels provided they are wrapped in Form Items and the label position is set to aside.

The only reason for wrapping labels in Form Items is to put the labels to the side of the input.

Top

Forms using top-positioned labels generally produce faster completion rates because they provide a consistent scanning pattern (top-down as opposed to a zig-zag) while minimizing the distance between the label and input.

Top-positioned labels are also less prone to cause layout issues due to variable label lengths as is the case of multilingual applications.

They do however result in vertically longer forms which is why sectioning is important.

Side

Side-positioned labels help reduce a form’s overall height. This is especially useful for longer forms and/or when vertical space is limited. They’re also often used when there is a need to compare numeric data.

Open in a
new tab
<vaadin-form-layout>
  <!-- Wrap fields into form items, which 
       displays labels on the side by default -->
  <vaadin-form-item>
    <label slot="label">Revenue</label>
    <vaadin-text-field>
      <span slot="suffix">EUR</span>
    </vaadin-text-field>
  </vaadin-form-item>
  <vaadin-form-item>
    <label slot="label">Expenses</label>
    <vaadin-text-field>
      <span slot="suffix">EUR</span>
    </vaadin-text-field>
  </vaadin-form-item>
  <vaadin-form-item>
    <label slot="label">Invoices</label>
    <vaadin-text-field>
      <span slot="suffix">EUR</span>
    </vaadin-text-field>
  </vaadin-form-item>
</vaadin-form-layout>

Aim for similar length labels to keep the distance between the labels and input fields consistent. Inconsistent spacing can cause slower completion rates.

Forms using this position require more horizontal space which isn’t always ideal in narrow forms. It’s recommended to configure Form Layout to use top-positioned labels when the form’s width is small.

Caution
Accessibility
Form Item suffers from two accessibility issues: required indicators cannot be displayed and screen readers are unable to announce a field’s label.

Responsive Label Position

Like the number of columns, the label position is configurable based on the layout’s width. For example, you can position the labels on the side when there’s ample horizontal space available, and on top on narrower screens.

Native Input Fields

Form Item allows you to set a label for any type of component that you want to use in a Form Layout. It supports both Vaadin components and native HTML components.

Open in a
new tab
<vaadin-form-layout>
  <vaadin-form-item>
    <label slot="label">Revenue</label>
    <input type="text" />
  </vaadin-form-item>
</vaadin-form-layout>

Best Practises

Sectioning

Longer forms should be split into smaller, more manageable and user-friendly sections using subheadings, Tabs, Details or separate views when possible. Each section should consist of related content and/or fields.

Button Placement

Use the following guidelines for Button placement in forms:

  • Buttons should be placed below the form they’re associated with.

  • Buttons should be aligned left.

  • Primary action first, followed by other actions, in order of importance.

For more information, please see the Button documentation.