Skip to content
Ringobook v3.27.0

Form Layouts

Forms are structured using a set of flexible container classes that handle spacing, alignment, and validation states. 📝

Use the .ro-form class as the main container for your form. Inside, use .ro-form-control to wrap each label and input pair. This ensures consistent vertical spacing.

<form class="ro-form ro-u-items-stretch">
<div class="ro-form-control">
<label class="ro-label" for="email">Email address</label>
<label class="ro-input-group">
<input type="email" id="email" placeholder="name@example.com" />
</label>
</div>
<div class="ro-form-control">
<label class="ro-label" for="password">Password</label>
<label class="ro-input-group">
<input type="password" id="password" placeholder="Password" />
</label>
</div>
<button class="ro-btn ro-color-scheme-product">Submit</button>
</form>
Preview

Add the .ro-dir-horizontal class to a .ro-form-control to align the label and input side-by-side. This is commonly used for switches or checkboxes.

<div class="ro-form-control ro-dir-horizontal">
<input type="checkbox" class="ro-switch" id="notifications" />
<label class="ro-label" for="notifications">Enable notifications</label>
</div>
Preview

To display validation errors, add the .ro-state-invalid class to the .ro-form-control container. Then, include an element with .ro-form-error-message inside the control. The error message will only be visible when the parent has the invalid state class.

<div class="ro-form-control ro-state-invalid">
<label class="ro-label" for="username">Username</label>
<label class="ro-input-group">
<input type="text" id="username" value="inv@lid" />
</label>
<span class="ro-form-error-message">
<i class="ro-icon ro-icon-warning-error"></i>
Invalid username format
</span>
</div>
Preview

Invalid username format

Use .ro-field with .ro-field-header, .ro-field-label, and label.ro-input-group wrapping the control.

<div class="ro-field">
<div class="ro-field-header">
<div class="ro-field-label">
<label for="email-field">Email</label>
</div>
</div>
<label class="ro-input-group">
<input id="email-field" class="ro-input" type="email" placeholder="you@example.com" />
</label>
</div>
Preview
<div class="ro-field ro-state-invalid">
<div class="ro-field-header">
<div class="ro-field-label">
<label for="company-field">
Company
<span class="ro-field-required-indicator" aria-hidden="true">*</span>
</label>
</div>
<div class="ro-label-description">Visible on your public profile</div>
</div>
<label class="ro-input-group">
<input id="company-field" class="ro-input" type="text" placeholder="Acme Inc." aria-required="true" aria-invalid="true" />
</label>
<span class="ro-field-error" role="alert">
<i class="ro-icon ro-icon-warning-error" aria-hidden="true"></i>
Company name is required
</span>
</div>
Preview
Visible on your public profile

Company name is required

Add .ro-dir-horizontal to .ro-field and stack several fields inside .ro-form. Use .ro-divider to separate groups — this works well for settings panels where the label and control sit on one row.

<form class="ro-form">
<div class="ro-field ro-dir-horizontal">
<div class="ro-field-label">
<label for="notify-email">Email notifications</label>
</div>
<input type="checkbox" class="ro-switch" id="notify-email" checked />
</div>
<div class="ro-field ro-dir-horizontal">
<div class="ro-field-label">
<label for="notify-push">Push notifications</label>
</div>
<input type="checkbox" class="ro-switch" id="notify-push" />
</div>
<hr class="ro-divider" />
<div class="ro-field ro-dir-horizontal">
<div class="ro-field-label">
<label for="profile-visibility">Profile visibility</label>
</div>
<input type="checkbox" class="ro-switch" id="profile-visibility" checked />
</div>
<hr class="ro-divider" />
<div class="ro-field ro-dir-horizontal">
<div class="ro-field-label">
<label for="usage-analytics">Usage analytics</label>
</div>
<input type="checkbox" class="ro-switch" id="usage-analytics" />
</div>
</form>
Preview


For multi-column layouts, combine .ro-form with Grid utilities — for example .ro-grid with responsive column classes.

<form class="ro-form">
<div class="ro-grid ro-cols-1 md:ro-cols-2 ro-u-gap-4">
<div class="ro-form-control">
<label class="ro-label" for="fname">First Name</label>
<label class="ro-input-group">
<input type="text" id="fname" placeholder="Jane" />
</label>
</div>
<div class="ro-form-control">
<label class="ro-label" for="lname">Last Name</label>
<label class="ro-input-group">
<input type="text" id="lname" placeholder="Doe" />
</label>
</div>
<div class="ro-form-control ro-col-span-1 md:ro-col-span-2">
<label class="ro-label" for="address">Address</label>
<label class="ro-input-group">
<input type="text" id="address" placeholder="123 Main St" />
</label>
</div>
</div>
<button class="ro-btn ro-color-scheme-product ro-u-self-end"><i class="ro-icon ro-icon-check-circle"></i>Save Profile</button>
</form>
Preview

Use .ro-radio-group or .ro-checkbox-group to group related options. Use .ro-input-option for a single checkbox, radio, or switch row.

<fieldset class="ro-radio-group">
<legend>Preferences</legend>
<label class="ro-input-option">
<input type="radio" class="ro-input-radio" name="pref" checked />
Option 1
</label>
<label class="ro-input-option">
<input type="radio" class="ro-input-radio" name="pref" />
Option 2
</label>
</fieldset>
Preview
Preferences

Add .ro-dir-horizontal on the group for a wrapping horizontal layout.

<fieldset class="ro-checkbox-group">
<legend>Notifications</legend>
<label class="ro-input-option">
<input type="checkbox" class="ro-input-checkbox" checked />
Email alerts
</label>
<label class="ro-input-option">
<input type="checkbox" class="ro-input-checkbox" />
Push notifications
</label>
</fieldset>
Preview
Notifications
ClassDescription
.ro-formMain container for forms. Vertical stack with var(--ro-size-4) gap.
.ro-form-sectionNested form grouping (layout stack only; no built-in title styles).
.ro-field, .ro-form-controlWrapper for a label and control pair.
.ro-field-inputTighter gap between label and control.
.ro-field-label, .ro-labelLabel styling.
.ro-field-error, .ro-form-error-messageError message (visible when parent is invalid).
.ro-dir-horizontalHorizontal label/control layout on .ro-field / .ro-form-control.
.ro-state-invalidShows error messages; danger border on inputs, counters, and selects.
.ro-radio-group, .ro-checkbox-groupOption groups with reset fieldset chrome.
.ro-input-optionSingle checkbox, radio, or switch row.

Changelog

Recent updates in @ringover/styles. See the full package changelog .

@ringover/styles@3.8.0
  • Updated form elements and inputs HTML structure.