Angular Form Layout Component

Form Layout

Give your forms some structure — from inline to horizontal to custom grid implementations — with our Angular form layout options.

Forms

Every group of form fields should reside in a form element. CoreUI provides no default styling for the form element, but there are some powerful browser features that are provided by default.

  • New to browser forms? Consider reviewing the MDN form docs for an overview and complete list of available attributes.
  • cButton within a form default to type="submit", so strive to be specific and always include a type.
  • You can disable every form element within a form with the disabled attribute on the form.

Since CoreUI applies display: block and width: 100% to almost all our form controls, forms will by default stack vertically. Additional classes can be used to vary this layout on a per-form basis.

Utilities

Margin utilities are the easiest way to add some structure to forms. They provide basic grouping of labels, controls, optional form text, and form validation messaging. We recommend sticking to margin-bottom utilities, and using a single direction throughout the form for consistency.

Form grid

More complex forms can be built using our grid classes. Use these for form layouts that require multiple columns, varied widths, and additional alignment options.

import { Component } from '@angular/core';
import { ColComponent, FormControlDirective, RowComponent } from '@coreui/angular';

@Component({
  selector: 'docs-layout-form-grid',
  templateUrl: './layout-form-grid.component.html',
  imports: [RowComponent, ColComponent, FormControlDirective]
})
export class LayoutFormGridComponent {}
<c-row>
  <c-col [xs]>
    <input aria-label="First name" cFormControl placeholder="First name" />
  </c-col>
  <c-col [xs]>
    <input aria-label="Last name" cFormControl placeholder="Last name" />
  </c-col>
</c-row>

Gutters

By adding gutter modifier classes, you can have control over the gutter width in as well the inline as block direction.

import { Component } from '@angular/core';
import { ColComponent, FormControlDirective, RowComponent } from '@coreui/angular';

@Component({
  selector: 'docs-layout-gutters',
  templateUrl: './layout-gutters.component.html',
  imports: [RowComponent, ColComponent, FormControlDirective]
})
export class LayoutGuttersComponent {}
<c-row class="g-3">
  <c-col [xs]>
    <input aria-label="First name" cFormControl placeholder="First name" />
  </c-col>
  <c-col [xs]>
    <input aria-label="Last name" cFormControl placeholder="Last name" />
  </c-col>
</c-row>

More complex layouts can also be created with the grid system.

import { Component } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {
  ButtonDirective,
  ColComponent,
  FormCheckComponent,
  FormCheckInputDirective,
  FormCheckLabelDirective,
  FormControlDirective,
  FormDirective,
  FormLabelDirective,
  FormSelectDirective
} from '@coreui/angular';

@Component({
  selector: 'docs-layout-gutters-2',
  templateUrl: './layout-gutters-2.component.html',
  imports: [
    ReactiveFormsModule,
    FormsModule,
    FormDirective,
    ColComponent,
    FormLabelDirective,
    FormControlDirective,
    FormSelectDirective,
    FormCheckComponent,
    FormCheckInputDirective,
    FormCheckLabelDirective,
    ButtonDirective
  ]
})
export class LayoutGutters2Component {}
<form cForm class="row g-3">
  <c-col [md]="6">
    <label cLabel for="inputEmail4">Email</label>
    <input cFormControl id="inputEmail4" type="email" />
  </c-col>
  <c-col [md]="6">
    <label cLabel for="inputPassword4">Password</label>
    <input cFormControl id="inputPassword4" type="password" />
  </c-col>
  <c-col [xs]="12">
    <label cLabel for="inputAddress">Address</label>
    <input cFormControl id="inputAddress" placeholder="1234 Main St" />
  </c-col>
  <c-col [xs]="12">
    <label cLabel for="inputAddress2">Address 2</label>
    <input cFormControl id="inputAddress2" placeholder="Apartment, studio, or floor" />
  </c-col>
  <c-col [md]="6">
    <label cLabel for="inputCity">City</label>
    <input cFormControl id="inputCity" />
  </c-col>
  <c-col [md]="4">
    <label cLabel for="inputState">State</label>
    <select cSelect id="inputState">
      <option>Choose...</option>
      <option>...</option>
    </select>
  </c-col>
  <c-col [md]="2">
    <label cLabel for="inputZip">Zip</label>
    <input cFormControl id="inputZip" />
  </c-col>
  <c-col [xs]="12">
    <c-form-check>
      <input cFormCheckInput id="gridCheck" name="gridCheck" type="checkbox" />
      <label cFormCheckLabel for="gridCheck">Check me out</label>
    </c-form-check>
  </c-col>
  <c-col [xs]="12">
    <button cButton type="submit">Sign in</button>
  </c-col>
</form>

Horizontal form

Create horizontal forms with the grid by adding the .row class to form groups and using the .col-*-* classes to specify the width of your labels and controls. Be sure to add cLabel="col" to your label as well so they’re vertically centered with their associated form controls.

At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we’ve removed the padding-top on our stacked radio inputs label to better align the text baseline.

import { Component } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {
  ButtonDirective,
  ColComponent,
  ColDirective,
  FormCheckComponent,
  FormCheckInputDirective,
  FormCheckLabelDirective,
  FormControlDirective,
  FormLabelDirective,
  RowComponent
} from '@coreui/angular';

@Component({
  selector: 'docs-layout-horizontal-form',
  templateUrl: './layout-horizontal-form.component.html',
  imports: [
    ReactiveFormsModule,
    FormsModule,
    RowComponent,
    FormLabelDirective,
    ColDirective,
    ColComponent,
    FormControlDirective,
    FormCheckComponent,
    FormCheckInputDirective,
    FormCheckLabelDirective,
    ButtonDirective
  ]
})
export class LayoutHorizontalFormComponent {}
<form>
  <c-row class="mb-3">
    <label cLabel="col" cCol [sm]="2" for="inputEmail3">
      Email
    </label>
    <c-col [sm]="10">
      <input cFormControl id="inputEmail3" type="email" />
    </c-col>
  </c-row>
  <c-row class="mb-3">
    <label cLabel="col" cCol [sm]="2" for="inputPassword3">
      Password
    </label>
    <c-col [sm]="10">
      <input cFormControl id="inputPassword3" type="password" />
    </c-col>
  </c-row>
  <fieldset class="row mb-3">
    <legend cLabel="col" cCol [sm]="2" class="pt-0">Radios</legend>
    <c-col [sm]="10">
      <c-form-check>
        <input cFormCheckInput checked id="gridRadios1" name="gridRadios" type="radio" value="option1" />
        <label cFormCheckLabel for="gridRadios1">First radio</label>
      </c-form-check>
      <c-form-check>
        <input cFormCheckInput id="gridRadios2" name="gridRadios" type="radio" value="option2" />
        <label cFormCheckLabel for="gridRadios2">Second radio</label>
      </c-form-check>
      <c-form-check>
        <input cFormCheckInput id="gridRadios3" name="gridRadios" type="radio" value="option3" />
        <label cFormCheckLabel for="gridRadios3">Third disabled radio</label>
      </c-form-check>
    </c-col>
  </fieldset>
  <c-row class="mb-3">
    <c-col [sm]="10" class="offset-sm-2">
      <c-form-check>
        <input cFormCheckInput id="gridCheck1" name="gridCheck1" type="checkbox" />
        <label cFormCheckLabel for="gridCheck1">Example checkbox</label>
      </c-form-check>
    </c-col>
  </c-row>
  <button cButton type="submit">Sign in</button>
</form>

Horizontal form label sizing

Be sure to use .col-form-label-sm or .col-form-label-lg to your cLabel or legend to correctly follow the size of .form-control-lg and .form-control-sm.

import { Component } from '@angular/core';
import { ColComponent, ColDirective, FormControlDirective, FormLabelDirective, RowComponent } from '@coreui/angular';

@Component({
  selector: 'docs-layout-horizontal-form-label-sizing',
  templateUrl: './layout-horizontal-form-label-sizing.component.html',
  imports: [RowComponent, ColDirective, FormLabelDirective, ColComponent, FormControlDirective]
})
export class LayoutHorizontalFormLabelSizingComponent {}
<c-row class="mb-3">
  <label [sm]="2" cCol cLabel="col" for="colFormLabelSm" sizing="sm">
    Email
  </label>
  <c-col [sm]="10">
    <input cFormControl
           id="colFormLabelSm"
           placeholder="col-form-label-sm"
           sizing="sm"
           type="email"
    />
  </c-col>
</c-row>
<c-row class="mb-3">
  <label [sm]="2" cCol cLabel="col" for="colFormLabel">
    Email
  </label>
  <c-col [sm]="10">
    <input cFormControl id="colFormLabel" placeholder="col-form-label" type="email" />
  </c-col>
</c-row>
<c-row>
  <label [sm]="2" cCol cLabel="col" for="colFormLabelLg" sizing="lg">
    Email
  </label>
  <c-col [sm]="10">
    <input cFormControl
           id="colFormLabelLg"
           placeholder="col-form-label-lg"
           sizing="lg"
           type="email"
    />
  </c-col>
</c-row>

Column sizing

As shown in the previous examples, our grid system allows you to place any number of c-col within a c-row. They’ll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining cols equally split the rest, with specific column classes like c-col [sm]="7".

import { Component } from '@angular/core';
import { ColComponent, FormControlDirective, RowComponent } from '@coreui/angular';

@Component({
  selector: 'docs-layout-column-sizing',
  templateUrl: './layout-column-sizing.component.html',
  imports: [RowComponent, ColComponent, FormControlDirective]
})
export class LayoutColumnSizingComponent {}
<c-row class="g-3">
  <c-col [sm]="7">
    <input aria-label="City" cFormControl placeholder="City" />
  </c-col>
  <c-col [sm]>
    <input aria-label="State" cFormControl placeholder="State" />
  </c-col>
  <c-col [sm]>
    <input aria-label="Zip" cFormControl placeholder="Zip" />
  </c-col>
</c-row>

Auto-sizing

The example below uses a flexbox utility to vertically center the contents and changes to c-col xs="auto" so that your columns only take up as much space as needed. Put another way, the column sizes itself based on the contents.

import { Component } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {
  ButtonDirective,
  ColComponent,
  FormCheckComponent,
  FormCheckInputDirective,
  FormCheckLabelDirective,
  FormControlDirective,
  FormLabelDirective,
  FormSelectDirective,
  GutterDirective,
  InputGroupComponent,
  InputGroupTextDirective,
  RowDirective
} from '@coreui/angular';

@Component({
  selector: 'docs-layout-auto-sizing',
  templateUrl: './layout-auto-sizing.component.html',
  imports: [
    ReactiveFormsModule,
    FormsModule,
    RowDirective,
    GutterDirective,
    ColComponent,
    FormLabelDirective,
    FormControlDirective,
    InputGroupComponent,
    InputGroupTextDirective,
    FormSelectDirective,
    FormCheckComponent,
    FormCheckInputDirective,
    FormCheckLabelDirective,
    ButtonDirective
  ]
})
export class LayoutAutoSizingComponent {}
<form cRow [gutter]="{gy: 2, gx: 3}" class="align-items-center">
  <c-col xs="auto">
    <label cLabel class="visually-hidden" for="autoSizingInput">
      Name
    </label>
    <input cFormControl id="autoSizingInput" placeholder="Jane Doe" />
  </c-col>
  <c-col xs="auto">
    <label cLabel class="visually-hidden" for="autoSizingInputGroup">
      Username
    </label>
    <c-input-group>
      <span cInputGroupText>&#64;</span>
      <input cFormControl id="autoSizingInputGroup" placeholder="Username" />
    </c-input-group>
  </c-col>
  <c-col xs="auto">
    <label cLabel class="visually-hidden" for="autoSizingSelect">
      Preference
    </label>
    <select cSelect id="autoSizingSelect">
      <option>Choose...</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
  </c-col>
  <c-col xs="auto">
    <c-form-check>
      <input cFormCheckInput id="autoSizingCheck" name="autoSizingCheck" type="checkbox" />
      <label cFormCheckLabel for="autoSizingCheck">Remember me</label>
    </c-form-check>
  </c-col>
  <c-col xs="auto">
    <button cButton type="submit">Submit</button>
  </c-col>
</form>

You can then remix that once again with size-specific column classes.

import { Component } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {
  ButtonDirective,
  ColComponent,
  FormCheckComponent,
  FormCheckInputDirective,
  FormCheckLabelDirective,
  FormControlDirective,
  FormLabelDirective,
  FormSelectDirective,
  GutterDirective,
  InputGroupComponent,
  InputGroupTextDirective,
  RowDirective
} from '@coreui/angular';

@Component({
  selector: 'docs-layout-auto-sizing-2',
  templateUrl: './layout-auto-sizing-2.component.html',
  imports: [
    ReactiveFormsModule,
    FormsModule,
    RowDirective,
    GutterDirective,
    ColComponent,
    FormLabelDirective,
    FormControlDirective,
    InputGroupComponent,
    InputGroupTextDirective,
    FormSelectDirective,
    FormCheckComponent,
    FormCheckInputDirective,
    FormCheckLabelDirective,
    ButtonDirective
  ]
})
export class LayoutAutoSizing2Component {}
<form cRow [gutter]="{gy: 2, gx: 3}" class="align-items-center">
  <c-col [sm]="3">
    <label cLabel class="visually-hidden" for="specificSizeInputName">
      Name
    </label>
    <input cFormControl id="specificSizeInputName" placeholder="Jane Doe" />
  </c-col>
  <c-col [sm]="3">
    <label cLabel class="visually-hidden" for="specificSizeInputGroupUsername">
      Username
    </label>
    <c-input-group>
      <span cInputGroupText>&#64;</span>
      <input cFormControl id="specificSizeInputGroupUsername" placeholder="Username" />
    </c-input-group>
  </c-col>
  <c-col [sm]="3">
    <label cLabel class="visually-hidden" for="specificSizeSelect">
      Preference
    </label>
    <select cSelect id="specificSizeSelect">
      <option>Choose...</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
  </c-col>
  <c-col xs="auto">
    <c-form-check>
      <input cFormCheckInput id="autoSizingCheck2" name="autoSizingCheck2" type="checkbox" />
      <label cFormCheckLabel for="autoSizingCheck2">Remember me</label>
    </c-form-check>
  </c-col>
  <c-col xs="auto">
    <button cButton type="submit">Submit</button>
  </c-col>
</form>

Inline forms

Use the c-col xs="auto" to create horizontal layouts. By adding gutter modifier classes, we will have gutters in horizontal and vertical directions. The .align-items-center aligns the form elements to the middle, making the c-form-check align properly.

import { Component } from '@angular/core';
import {
  ButtonDirective,
  ColComponent,
  FormCheckComponent,
  FormCheckInputDirective,
  FormCheckLabelDirective,
  FormControlDirective,
  FormLabelDirective,
  FormSelectDirective,
  GutterDirective,
  InputGroupComponent,
  InputGroupTextDirective,
  RowDirective
} from '@coreui/angular';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@Component({
  selector: 'docs-layout-inline-forms',
  templateUrl: './layout-inline-forms.component.html',
  imports: [
    ReactiveFormsModule,
    FormsModule,
    RowDirective,
    GutterDirective,
    ColComponent,
    FormLabelDirective,
    InputGroupComponent,
    InputGroupTextDirective,
    FormControlDirective,
    FormSelectDirective,
    FormCheckComponent,
    FormCheckInputDirective,
    FormCheckLabelDirective,
    ButtonDirective
  ]
})
export class LayoutInlineFormsComponent {}
<form cRow lg="auto" [gutter]="3" class="align-items-center">
  <c-col [xs]="12">
    <label cLabel class="visually-hidden" for="inlineFormInputGroupUsername">
      Username
    </label>
    <c-input-group>
      <span cInputGroupText>&#64;</span>
      <input cFormControl id="inlineFormInputGroupUsername" placeholder="Username" />
    </c-input-group>
  </c-col>
  <c-col [xs]="12">
    <label cLabel class="visually-hidden" for="inlineFormSelectPref">
      Preference
    </label>
    <select cSelect id="inlineFormSelectPref">
      <option>Choose...</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
  </c-col>
  <c-col [xs]="12">
    <c-form-check inline>
      <input cFormCheckInput id="inlineFormCheck" name="inlineFormCheck" type="checkbox" />
      <label cFormCheckLabel for="inlineFormCheck">Remember me</label>
    </c-form-check>
  </c-col>
  <c-col [xs]="12">
    <button cButton type="submit">Submit</button>
  </c-col>
</form>