- Form Group
- Examples
- Basic Form Group
- Help Text
- Label with Tooltip
- Using Label Slot
- Controlling Column Spans
- Two-Column Layout
- Three-Column Layout
- Mixed Column Layouts
- Mixing Form Control Types
- Nested Groups with Different Sections
- Single-Column Layout
- Validation Example
- Responsive Behavior
- Styling with CSS Parts
- Accessibility
- Importing
- Slots
- Properties
Form Group
<zn-form-group> | ZnFormGroup
Short summary of the component’s intended use.
Form groups are used to organize multiple form controls under a shared label and help text. They provide a responsive grid layout that automatically adapts to different screen sizes, making it easy to create multi-column forms with consistent spacing and alignment.
<zn-form-group label="Contact Information" help-text="Please provide your contact details"> <zn-input label="First Name" placeholder="Enter your first name"></zn-input> <zn-input label="Last Name" placeholder="Enter your last name"></zn-input> <zn-input label="Email" type="email" placeholder="your.email@example.com"></zn-input> <zn-input label="Phone" type="tel" placeholder="(555) 123-4567"></zn-input> </zn-form-group>
Examples
Basic Form Group
Use the label attribute to give the form group an accessible label. Form controls within the
group are automatically laid out in a responsive grid that displays as a single column on mobile and up to 6
columns on larger screens.
<zn-form-group label="User Details"> <zn-input label="Username" placeholder="username"></zn-input> <zn-input label="Email" type="email" placeholder="email@example.com"></zn-input> </zn-form-group>
Help Text
Add descriptive help text to a form group with the help-text attribute. For help text that
contains HTML, use the help-text slot instead. Help text appears below the label and provides
guidance for the entire group of form controls.
<zn-form-group label="Shipping Address" help-text="Enter the address where you want your order delivered"> <zn-input label="Street Address" placeholder="123 Main St"></zn-input> <zn-input label="Apartment/Unit" placeholder="Apt 4B"></zn-input> <zn-input label="City" placeholder="New York"></zn-input> <zn-input label="Postal Code" placeholder="10001"></zn-input> </zn-form-group> <br /> <zn-form-group label="Billing Address"> <div slot="help-text">Enter the address associated with your <strong>payment method</strong></div> <zn-input label="Street Address" placeholder="123 Main St"></zn-input> <zn-input label="City" placeholder="New York"></zn-input> </zn-form-group>
Label with Tooltip
Use the label-tooltip attribute to add text that appears in a tooltip triggered by an info icon
next to the label.
Usage: Use a label tooltip to provide helpful but non-essential instructions or examples to guide people when filling in the form group. Use help text to communicate instructions or requirements for filling in the controls without errors.
<zn-form-group label="Payment Details" label-tooltip="Your payment information is encrypted and securely stored. We never share your financial data with third parties." help-text="Enter your credit or debit card information"> <zn-input label="Cardholder Name" placeholder="Name on card"></zn-input> <zn-input label="Card Number" placeholder="1234 5678 9012 3456"></zn-input> <zn-input label="Expiry Date" placeholder="MM/YY" span="2"></zn-input> <zn-input label="CVV" placeholder="123" span="2"></zn-input> </zn-form-group>
Using Label Slot
For labels that contain HTML or more complex content, use the label slot instead of the
attribute.
<zn-form-group help-text="Complete all required fields"> <span slot="label"> Account Settings <zn-chip variant="info" size="small">New</zn-chip> </span> <zn-input label="Display Name" placeholder="How should we address you?"></zn-input> <zn-input label="Bio" placeholder="Tell us about yourself"></zn-input> </zn-form-group>
Controlling Column Spans
By default, all form controls within a form group span the full width (6 columns) on mobile and maintain
that full width on larger screens. Use the span attribute on individual form controls to
control how many columns they occupy on medium and larger screens.
The grid supports spans from 1 to 6 columns. Spans only take effect on screens at the
md breakpoint and above (tablets and desktops). On smaller screens, all controls stack
vertically at full width.
<zn-form-group label="Product Information" help-text="Provide details about the product"> <zn-input label="Product Name" placeholder="Enter product name"></zn-input> <zn-input label="SKU" placeholder="Product code" span="2"></zn-input> <zn-input label="Price" type="currency" placeholder="0.00" span="2"></zn-input> <zn-input label="Quantity" type="number" placeholder="0" span="2"></zn-input> <zn-select label="Category" span="3"> <zn-option value="electronics">Electronics</zn-option> <zn-option value="clothing">Clothing</zn-option> <zn-option value="books">Books</zn-option> </zn-select> <zn-select label="Status" span="3"> <zn-option value="active">Active</zn-option> <zn-option value="inactive">Inactive</zn-option> </zn-select> </zn-form-group>
Two-Column Layout
Create a balanced two-column layout by giving each control a span of 3 columns.
<zn-form-group label="Personal Information"> <zn-input label="First Name" placeholder="First name" span="3"></zn-input> <zn-input label="Last Name" placeholder="Last name" span="3"></zn-input> <zn-input label="Email" type="email" placeholder="email@example.com" span="3"></zn-input> <zn-input label="Phone" type="tel" placeholder="(555) 123-4567" span="3"></zn-input> <zn-datepicker label="Date of Birth" span="3"></zn-datepicker> <zn-select label="Country" span="3"> <zn-option value="us">United States</zn-option> <zn-option value="ca">Canada</zn-option> <zn-option value="uk">United Kingdom</zn-option> </zn-select> </zn-form-group>
Three-Column Layout
Create a three-column layout by giving each control a span of 2 columns.
<zn-form-group label="Event Schedule" help-text="Set up the event timing"> <zn-datepicker label="Date" span="2"></zn-datepicker> <zn-input label="Start Time" type="time" span="2"></zn-input> <zn-input label="End Time" type="time" span="2"></zn-input> <zn-input label="Duration (hours)" type="number" span="2"></zn-input> <zn-select label="Time Zone" span="4"> <zn-option value="est">Eastern (EST)</zn-option> <zn-option value="cst">Central (CST)</zn-option> <zn-option value="mst">Mountain (MST)</zn-option> <zn-option value="pst">Pacific (PST)</zn-option> </zn-select> </zn-form-group>
Mixed Column Layouts
Combine different column spans to create flexible layouts that accommodate different types of inputs.
<zn-form-group label="Address Details"> <zn-input label="Street Address" placeholder="123 Main Street"></zn-input> <zn-input label="Apartment/Suite/Unit" placeholder="Apt 4B" span="2"></zn-input> <zn-input label="City" placeholder="New York" span="2"></zn-input> <zn-input label="State" placeholder="NY" span="1"></zn-input> <zn-input label="ZIP Code" placeholder="10001" span="1"></zn-input> <zn-select label="Country" span="3"> <zn-option value="us">United States</zn-option> <zn-option value="ca">Canada</zn-option> <zn-option value="mx">Mexico</zn-option> </zn-select> <zn-checkbox span="3">Set as default address</zn-checkbox> </zn-form-group>
Mixing Form Control Types
Form groups work with all Zinc form components including inputs, selects, textareas, datepickers, checkboxes, radios, and toggles.
<zn-form-group label="Project Settings" help-text="Configure your project preferences"> <zn-input label="Project Name" placeholder="My Awesome Project" span="4"></zn-input> <zn-select label="Priority" span="2"> <zn-option value="low">Low</zn-option> <zn-option value="medium" selected>Medium</zn-option> <zn-option value="high">High</zn-option> </zn-select> <zn-datepicker label="Start Date" span="3"></zn-datepicker> <zn-datepicker label="End Date" span="3"></zn-datepicker> <zn-textarea label="Description" placeholder="Describe your project..." rows="3"></zn-textarea> <zn-radio-group label="Status" span="3"> <zn-radio value="planning">Planning</zn-radio> <zn-radio value="active" checked>Active</zn-radio> <zn-radio value="complete">Complete</zn-radio> </zn-radio-group> <zn-checkbox-group label="Features" span="3"> <zn-checkbox value="notifications">Email notifications</zn-checkbox> <zn-checkbox value="reports">Weekly reports</zn-checkbox> <zn-checkbox value="api">API access</zn-checkbox> </zn-checkbox-group> </zn-form-group>
Nested Groups with Different Sections
Create complex forms by using multiple form groups to separate different sections of related information.
<form> <zn-form-group label="Account Information" help-text="Basic account details"> <zn-input label="Username" placeholder="username" span="3" required></zn-input> <zn-input label="Email" type="email" placeholder="email@example.com" span="3" required></zn-input> <zn-input label="Password" type="password" placeholder="••••••••" span="3" required></zn-input> <zn-input label="Confirm Password" type="password" placeholder="••••••••" span="3" required></zn-input> </zn-form-group> <br /> <zn-form-group label="Personal Details" help-text="Tell us about yourself"> <zn-input label="First Name" placeholder="First name" span="3"></zn-input> <zn-input label="Last Name" placeholder="Last name" span="3"></zn-input> <zn-input label="Phone" type="tel" placeholder="(555) 123-4567" span="3"></zn-input> <zn-datepicker label="Date of Birth" span="3"></zn-datepicker> </zn-form-group> <br /> <zn-form-group label="Preferences"> <zn-toggle name="newsletter" span="3">Subscribe to newsletter</zn-toggle> <zn-toggle name="sms" span="3">Receive SMS updates</zn-toggle> </zn-form-group> <br /> <zn-button type="submit" variant="primary">Create Account</zn-button> </form>
Single-Column Layout
By default, without span attributes, all controls stack vertically in a single column, which works well for forms with long labels or complex inputs.
<zn-form-group label="Application Form" help-text="Complete all fields to submit your application"> <zn-input label="Full Legal Name" placeholder="Enter your full name as it appears on government ID"></zn-input> <zn-input label="Email Address" type="email" placeholder="your.email@example.com"></zn-input> <zn-input label="Phone Number" type="tel" placeholder="Include country code"></zn-input> <zn-textarea label="Cover Letter" placeholder="Tell us why you're a great fit for this position..." rows="4"></zn-textarea> <zn-select label="How did you hear about us?"> <zn-option value="search">Search Engine</zn-option> <zn-option value="social">Social Media</zn-option> <zn-option value="referral">Friend or Colleague</zn-option> <zn-option value="other">Other</zn-option> </zn-select> </zn-form-group>
Validation Example
Form groups work seamlessly with form validation. Individual controls within the group can have their own validation rules.
<form class="form-group-validation"> <zn-form-group label="Registration Form" help-text="All fields are required"> <zn-input name="firstName" label="First Name" placeholder="First name" span="3" required> </zn-input> <zn-input name="lastName" label="Last Name" placeholder="Last name" span="3" required> </zn-input> <zn-input name="email" label="Email" type="email" placeholder="email@example.com" span="3" required> </zn-input> <zn-input name="phone" label="Phone" type="tel" placeholder="(555) 123-4567" span="3" required> </zn-input> <zn-datepicker name="birthdate" label="Date of Birth" span="3" required> </zn-datepicker> <zn-select name="country" label="Country" span="3" required> <zn-option value="us">United States</zn-option> <zn-option value="ca">Canada</zn-option> <zn-option value="uk">United Kingdom</zn-option> </zn-select> </zn-form-group> <br /> <zn-button type="submit" variant="primary">Submit</zn-button> <zn-button type="reset">Reset</zn-button> </form> <script type="module"> const form = document.querySelector('.form-group-validation'); // Wait for controls to be defined before attaching form listeners await Promise.all([ customElements.whenDefined('zn-button'), customElements.whenDefined('zn-input'), customElements.whenDefined('zn-datepicker'), customElements.whenDefined('zn-select') ]).then(() => { form.addEventListener('submit', (e) => { e.preventDefault(); const formData = new FormData(form); const data = Object.fromEntries(formData); alert('Form submitted successfully!\n\n' + JSON.stringify(data, null, 2)); }); }); </script>
Responsive Behavior
Form groups are responsive by default. The grid layout automatically adapts based on screen size:
- Small screens (mobile): All controls stack vertically at full width, regardless of span attributes
- Medium screens and up (tablets/desktops): The span attributes take effect, creating the multi-column layout
This ensures forms remain usable on all devices without additional configuration.
<zn-form-group label="Responsive Layout Demo" help-text="Resize your browser to see the layout adapt"> <zn-input label="Full width on mobile" span="6"></zn-input> <zn-input label="Half width on desktop" span="3"></zn-input> <zn-input label="Half width on desktop" span="3"></zn-input> <zn-input label="One third on desktop" span="2"></zn-input> <zn-input label="One third on desktop" span="2"></zn-input> <zn-input label="One third on desktop" span="2"></zn-input> </zn-form-group>
Styling with CSS Parts
Form groups expose several CSS parts that can be styled to customize their appearance. This example demonstrates how to create custom layouts using CSS grid.
<zn-form-group class="custom-form-group" label="Custom Styled Form Group" help-text="This form group has custom spacing and borders"> <zn-input label="Field 1" span="3"></zn-input> <zn-input label="Field 2" span="3"></zn-input> <zn-input label="Field 3" span="2"></zn-input> <zn-input label="Field 4" span="2"></zn-input> <zn-input label="Field 5" span="2"></zn-input> </zn-form-group> <style> .custom-form-group::part(form-control) { padding: var(--zn-spacing-large); border: 2px solid var(--zn-color-primary-300); border-radius: var(--zn-border-radius-medium); background-color: var(--zn-color-primary-50); } .custom-form-group::part(form-control-label) { color: var(--zn-color-primary-700); } .custom-form-group::part(form-control-help-text) { color: var(--zn-color-primary-600); } </style>
Accessibility
Form groups are built with accessibility in mind:
-
The component uses a
<fieldset>element to semantically group related form controls - The
labelis associated with the fieldset usingaria-labelledby - Help text is associated with the fieldset using
aria-describedby - All form controls within the group maintain their individual labels and accessibility features
<zn-form-group label="Accessible Form Group" help-text="Screen readers will announce the group label and help text" label-tooltip="Additional context for sighted users"> <zn-input label="Name" placeholder="Your name" required></zn-input> <zn-input label="Email" type="email" placeholder="your@email.com" required></zn-input> </zn-form-group>
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/@kubex/zinc@1.0.75/dist/components/form-group/form-group.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://cdn.jsdelivr.net/npm/@kubex/zinc@1.0.75/dist/components/form-group/form-group.js';
To import this component using a bundler:
import '@kubex/zinc/dist/components/form-group/form-group.js';
Slots
| Name | Description |
|---|---|
| (default) | The default slot. |
Learn more about using slots.
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
label
|
The form group’s label. Required for proper accessibility. If you need to display HTML, use the
label slot instead.
|
string
|
''
|
|
labelTooltip
label-tooltip
|
Text that appears in a tooltip next to the label. If you need to display HTML in the tooltip, use
the
label-tooltip slot instead.
|
string
|
''
|
|
helpText
help-text
|
The form groups help text. If you need to display HTML, use the help-text slot instead.
|
string
|
''
|
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.