Form Template - Default
This template is suitable for most form input pages and can be customized to fit a variety of application types.
Usage
See the Introduction to Forms for guidance on layout principles and best practices for designing forms.
Required Elements
- Form pages may contain any combination of form input controls, such as text input fields, selects, radio buttons, checkboxes and sliders.
- Primary call-to-action button.
Optional Elements
Validation and Error Messages
When possible, display validation messages in real-time as the user performs an action (client-side) rather than waiting until after the user submits information (server-side).
There are four types of messages:
- Error
- Warning
- Success
- Informational
Each may appear at the page level, container level and/or field level. See Messages for more information.
Developer Notes
Creating form layouts requires an understanding of the Spark Layout Guidelines as well as Spark’s Responsive Grid System to ensure that the layout being developed is not only responsive, but that form fields are also properly aligned. Because each potential design varies from one to the next, it is important to apply the appropriate CSS classes that reflect the design/layout you are working on.
<a class="spark-skip-nav" href="#mainContent">Skip Navigation</a>
<div class="spark-content__wrapper--sticky-footer">
<header class="spark-header">
<nav class="spark-header__nav" role="navigation">
<button class="spark-menu__toggle spark-header__toggle" title="View Navigation">
<i class="spark-icon--fill spark-icon-menu-hamburger spark-icon--md"></i>
</button>
<span class="spark-header__logo"><i class="spark-logo spark-logo--sabre spark-logo--sm">Sabre</i></span>
<a href="#" class="spark-header__title">Product™</a>
<div class="spark-menu spark-header__menu" role="menu">
<div class="spark-menu__header">
<button class="spark-menu__toggle" title="Hide Navigation">
<i class="spark-icon--fill spark-icon-close"></i>
</button>
<span class="spark-menu__title"></span>
<button class="spark-header__logout spark-header__collapsed-show">Logout</button>
</div>
<ul class="spark-menu__list spark-header__list spark-header__list--overflow">
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Dashboard</a>
</li>
<li class="spark-menu__list-item active" role="menuitem">
<span class="spark-menu__list-links">
<a href="#" class="spark-menu__list-link">Flight Analysis</a>
<button class="spark-menu__list-expand" role="menuitemcheckbox" title="Expand"></button>
</span>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">First Level A</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<span class="spark-menu__list-links">
<a tabindex="0" class="spark-menu__list-link">First Level B</a>
<a tabindex="0" class="spark-menu__list-expand" role="menuitemcheckbox" title="Expand"></a>
</span>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level a</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<span class="spark-menu__list-links">
<a tabindex="0" class="spark-menu__list-link spark-menu__list-expand" role="menuitemcheckbox">Second Level b</a>
</span>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Third-level Item I</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Third-level Item II</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Third-level Item III</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Third-level Item IV</a>
</li>
</ul>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level c</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level d</a>
</li>
</ul>
</li>
<li class="spark-menu__list-item active" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Sample Single Panel Form Page</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link spark-menu__list-expand" role="menuitemcheckbox">First Level D</a>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level aa</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level bb</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a tabindex="0" class="spark-menu__list-link">Second Level cc</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="spark-menu__list-item" role="menuitem">
<span class="spark-menu__list-links">
<a href="#" class="spark-menu__list-link">Market Analysis</a>
<button class="spark-menu__list-expand" role="menuitemcheckbox" title="Expand"></button>
</span>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Menu Option 1</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<span class="spark-menu__list-links">
<a href="#" class="spark-menu__list-link">Menu Option 2</a>
<button class="spark-menu__list-expand" role="menuitemcheckbox" title="Expand"></button>
</span>
<ul class="spark-menu__list">
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Sub Nav Item 1</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Sub Nav Item 2</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Sub Nav Item 3</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Sub Nav Item 4 That Has A Really Long Title</a>
</li>
</ul>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Menu Option 3</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link"><i class="spark-icon-announce"></i> Menu Option 4 w/ Icon</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Menu Option 5 w/ A Really Long Title</a>
</li>
<li class="spark-header__list-cta">
<a href="#" class="spark-header__list-cta-link">View All Analyses</a>
</li>
</ul>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Nav Item 8</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Nav Item 9</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Nav Item 10</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Nav Item 11</a>
</li>
<li class="spark-menu__list-item" role="menuitem">
<a href="#" class="spark-menu__list-link">Nav Item 12</a>
</li>
</ul>
<ul class="spark-menu__list">
<li class="spark-menu__list-item spark-menu__list-item--secondary" role="menuitem">
<a href="#" class="spark-menu__list-link spark-menu__ignore">
<i class="spark-icon--fill spark-icon-search spark-icon--md"></i>
<span class="spark-header__collapsed-show">Search</span>
</a>
</li>
<li class="spark-menu__list-item spark-menu__list-item--secondary" role="menuitem">
<a href="#" class="spark-menu__list-link spark-menu__ignore">
<i class="spark-icon--fill spark-icon-cog spark-icon--md"></i>
<span class="spark-header__collapsed-show">Account Settings</span>
</a>
</li>
</ul>
</div>
<div class="spark-header__sign-in spark-popover">
<a href="#" class="spark-menu__list-link spark-popover__toggle">Sign In</a>
<form class="spark-popover__content--bottom col-xs-8 col-md-4" role="tooltip" onsubmit="return false;" data-anchor-x="right">
<a href="#" class="spark-popover__close" title="Close"></a>
<h4>Account Sign In</h4>
<label class="spark-input spark-mar-t-1">
<input class="spark-input__field" name="username" role="textbox">
<span class="spark-label">Username</span>
</label>
<label class="spark-input">
<input class="spark-input__field" name="password" type="password" role="textbox">
<span class="spark-label">Password</span>
</label>
<button class="spark-btn spark-btn--md spark-btn--block">Sign In</button>
<div class="spark-text-center spark-mar-t-1">
<button class="spark-btn--link spark-eta">Forgot username or password?</button>
</div>
<span class="spark-popover__caret"></span>
</form>
</div>
</nav>
</header>
<main class="spark-main--sticky-footer" id="mainContent">
<div class="container">
<div class="row spark-mar-b-2 spark-mar-t-2">
<div class="col-xs-12">
<h1>Page Title</h1>
</div>
<div class="col-xs-12">
<div class="spark-panel spark-mar-t-1">
<div class="spark-panel__content">
<section>
<div class="spark-step-indicator spark-mar-b-2--xs spark-mar-b-2--sm" data-type="standard-dropdown">
<h4 class="spark-step-indicator__title">Default</h4>
<div class="spark-step-indicator__body">
<div class="spark-step-indicator__subtitle">
2. Choose a Flight
</div>
<div class="spark-step-indicator__list">
<a href="javascript:void(0)" class="spark-step-indicator__item spark-step-indicator__item--current">
<span class="spark-step-indicator__icon">1</span>
<span class="spark-step-indicator__text">
Step 1
</span>
</a>
<a href="javascript:void(0)" class="spark-step-indicator__item">
<span class="spark-step-indicator__icon">2</span>
<span class="spark-step-indicator__text">
Step 2
</span>
</a>
<a href="javascript:void(0)" class="spark-step-indicator__item">
<span class="spark-step-indicator__icon">3</span>
<span class="spark-step-indicator__text">
Step 3
<small class="spark-step-indicator__subtext">(Sublabel)</small>
</span>
</a>
<a href="javascript:void(0)" class="spark-step-indicator__item">
<span class="spark-step-indicator__icon">4</span>
<span class="spark-step-indicator__text">
Step 4
</span>
</a>
<a href="javascript:void(0)" class="spark-step-indicator__item">
<span class="spark-step-indicator__icon">5</span>
<span class="spark-step-indicator__text">
Step 5
</span>
</a>
<a href="javascript:void(0)" class="spark-step-indicator__item">
<span class="spark-step-indicator__icon">6</span>
<span class="spark-step-indicator__text">
Step 6
</span>
</a>
</div>
</div>
</div>
<h3>Subheading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<div class="row spark-toggle-group spark-mar-b-2">
<label class="col-xs-6 col-sm-3 col-md-2 spark-toggle">
<input class="spark-toggle__input" type="radio" name="test-toggle-c" checked="checked">
<span class="spark-label">Toggle A</span>
</label>
<label class="col-xs-6 col-sm-3 col-md-2 spark-toggle">
<input class="spark-toggle__input" type="radio" name="test-toggle-c">
<span class="spark-label">Toggle B</span>
</label>
</div>
<div class="row">
<fieldset class="spark-mar-b-1 col-xs-12 col-lg-9">
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 1 Input Label 1</span>
</label>
<div class="row">
<div class="col-xs-12 col-sm-5 spark-mar-b-1--xs">
<label class="spark-input spark-date example-simple-calendar">
<input class="spark-input__field" type="date" role="textbox">
<span class="spark-label">Date</span>
<a class="spark-input__addon spark-date__calendar-toggle" title="Show Calendar"><i class="spark-icon-calendar"></i></a>
</label>
</div>
<div class="col-xs-12 col-sm-4 spark-pad-l-0--gte-sm">
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>8:00am</option>
<option>9:00am</option>
<option>10:00am</option>
</select>
<span class="spark-label">Time</span>
</label>
</div>
<div class="col-xs-12 col-sm-3 spark-pad-l-0--gte-sm">
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">Related Label</span>
</label>
</div>
</div>
</fieldset>
<fieldset class="col-xs-12 col-lg-9">
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 2 Input Label 1</span>
</label>
<div class="row">
<div class="col-xs-12 col-sm-5 spark-mar-b-1--xs">
<label class="spark-input spark-date example-simple-calendar">
<input class="spark-input__field" type="date" role="textbox">
<span class="spark-label">Date</span>
<a class="spark-input__addon spark-date__calendar-toggle" title="Show Calendar"><i class="spark-icon-calendar"></i></a>
</label>
</div>
<div class="col-xs-12 col-sm-4 spark-pad-l-0--gte-sm">
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>8:00am</option>
<option>9:00am</option>
<option>10:00am</option>
</select>
<span class="spark-label">Time</span>
</label>
</div>
<div class="col-xs-12 col-sm-3 spark-pad-l-0--gte-sm">
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">Related Label</span>
</label>
</div>
</div>
</fieldset>
</div>
<h3 class="spark-mar-t-2">Subheading</h3>
<div class="row">
<div class="col-xs-12 col-lg-9">
<div class="col-xs-12 col-md-5 spark-pad-l-0">
<div class="spark-slider--integrated">
<label class="spark-label">Slider Label</label>
<input type="number" min="-10" max="30" value="20" step="5">
<div class="spark-slider__controls">
<button class="spark-slider__handle"></button>
<span class="spark-slider__track">
<span class="spark-slider__track-fill"></span>
</span>
</div>
</div>
</div>
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">Group 3 Select Label 1</span>
</label>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-lg-9">
<label class="spark-select">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">Group 3 Select Label 2</span>
</label>
</div>
</div>
<div class="spark-panel__content spark-expand spark-pad-l-0 spark-pad-r-0">
<div class="spark-expand__content">
<p>Duis elit laborum cupidatat do cillum nulla est.</p>
<fieldset class="row spark-mar-b-1">
<label class="col-xs-12 spark-checkbox">
<input class="spark-checkbox__input" type="checkbox"> <!-- This has to be before .spark-checkbox__box! -->
<span class="spark-checkbox__box"></span>
<span class="spark-label">Check one...</span>
</label>
<label class="col-xs-12 spark-checkbox">
<input class="spark-checkbox__input" type="checkbox"> <!-- This has to be before .spark-checkbox__box! -->
<span class="spark-checkbox__box"></span>
<span class="spark-label">Check two...</span>
</label>
<label class="col-xs-12 spark-checkbox">
<input class="spark-checkbox__input" type="checkbox"> <!-- This has to be before .spark-checkbox__box! -->
<span class="spark-checkbox__box"></span>
<span class="spark-label">Check three...</span>
</label>
<label class="col-xs-12 spark-checkbox">
<input class="spark-checkbox__input" type="checkbox"> <!-- This has to be before .spark-checkbox__box! -->
<span class="spark-checkbox__box"></span>
<span class="spark-label">Check four...</span>
</label>
<label class="col-xs-12 spark-checkbox">
<input class="spark-checkbox__input" type="checkbox" disabled> <!-- This has to be before .spark-checkbox__box! -->
<span class="spark-checkbox__box"></span>
<span class="spark-label">Check five...</span>
</label>
</fieldset>
</div>
<button class="spark-btn spark-btn--text spark-expand__toggle spark-expand__hide--expanded">View More<span class="spark-expand__toggle-caret"></span></button>
<button class="spark-btn spark-btn--text spark-expand__toggle spark-expand__show--expanded">View Less<span class="spark-expand__toggle-caret"></span></button>
</div>
<nav class="spark-btn-group spark-mar-t-2">
<button class="spark-btn spark-btn--md spark-btn--secondary spark-btn-group-secondary spark-btn--block-xs">Secondary</button>
<button class="spark-btn spark-btn--md spark-btn-group-primary spark-btn--block-xs |">Primary</button>
</nav>
</section>
</div><!-- /spark-panel__content-->
</div>
</div>
</div>
</div>
</main>
<footer class="spark-footer">
<div class="container">
<a class="spark-footer__logo spark-hidden--lte-sm" title="Sabre"><i class="spark-logo spark-logo--sabre spark-logo--xs"></i></a>
<div class="spark-footer__content">
<div class="spark-footer__copyright">
© 2015-16 Sabre <span class="spark-hidden--lte-md">Curabitur blandit tempus porttitor.</span>
</div>
<ul class="spark-footer__list">
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" href="javascript: void(0);">
Legal Policy
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" href="javascript: void(0);">
Contact Us
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" href="javascript: void(0);">
Support
</a>
</li>
</ul>
</div>
<ul class="spark-footer__list spark-footer__list--right spark-footer__list--icons">
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" title="Twitter">
<i class="spark-icon-social-twitter spark-icon--fill"></i>
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" title="Facebook">
<i class="spark-icon-social-facebook spark-icon--fill"></i>
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" title="LinkedIn">
<i class="spark-icon-social-linkedin spark-icon--fill"></i>
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" title="Instagram">
<i class="spark-icon-social-instagram spark-icon--fill"></i>
</a>
</li>
<li class="spark-footer__list-item">
<a class="spark-footer__list-link" title="YouTube">
<i class="spark-icon-social-youtube spark-icon--fill"></i>
</a>
</li>
</ul>
</div>
</footer>
</div>
<style type="text/css">
.white-bg {
background-color: #ffffff;
}
</style>
<style type="text/css">
</style>
In the example above, the displayed form utilizes all 12 columns of the grid system at the extra small, small and medium breakpoints, and 9 columns at the large and extra large breakpoints. The code below illustrates how this could be achieved using provided CSS classes.
<div class="col-xs-12 col-lg-9">
...
</div>
Grouping fields
As noted in the form design best practices, related fields should be grouped particularly in longer forms. For fields that are to be displayed side-by-side, the spacing between fields needs to be adjusted to emphasize the relationship between the fields. By default, the spacing between columns defined by the grid system is 24px(2rem), but for related fields we need to reduce this space to 12px(1rem). This is achieved by adding a helper class (spark-pad-l-0--gte-sm
) to the second and subsequent fields in the same row. An example is illustrated below.
<fieldset>
<div class="row">
<div class="col-xs-12 col-sm-7 spark-mar-b-1--xs">
<label class="spark-select spark-mar-b-0">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">First Label</span>
</label>
</div>
<div class="col-xs-12 col-sm-5 spark-pad-l-0--gte-sm">
<label class="spark-select spark-mar-b-0">
<select class="spark-select__input"> <!-- This has to be before .spark-label! -->
<option></option>
<option>Don't pick this one.</option>
<option>A decent choice.</option>
<option>The best option.</option>
</select>
<span class="spark-label">Related Label</span>
</label>
</div>
</div>
</fieldset>
The spacing between a set of related fields and the fields or grouping beneath it should be 24px(2rem) and once again this can be achieved by using available spacing helper classes. In the example below, the class spark-mar-b-2
is applied to the first fieldset to create a 24px space between it and the second fieldset.
<fieldset class="spark-mar-b-2">
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 1 Input Label 1</span>
</label>
<label class="spark-input spark-mar-b-0">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 1 Input Label 2</span>
</label>
</fieldset>
<fieldset>
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 2 Input Label 1</span>
</label>
<label class="spark-input spark-mar-b-0">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 2 Input Label 2</span>
</label>
</fieldset>
Page-level button groups
Page-level actionable buttons have certain characteristics in Spark:
- Buttons are right-aligned on wider, desktop screens but justified on narrower, mobile screens.
- Buttons are as wide as the container they live in at the
xs
breakpoint i.e. 100% wide. - If there are multiple buttons, the primary button is placed right-most on larger screens but top-most on smaller screens where the buttons are stacked e.g. at the
xs
breakpoint.
To achieve the above characteristics, the following CSS classes (and other helper classes) can be utilized:
spark-btn-group
is applied to an element that contains page-level actionable buttons and will right-align the buttons.spark-btn--block-xs
will make the buttons it is applied to block elements at thexs
breakpoint. This is an example of a breakpoint-specific helper class, and documentation on other variations) is available.spark-btn-group-primary
andspark-btn-group-secondary
are used to identify the primary and secondary buttons in a button group and adjust the order of buttons on small screens such that the primary button in the group is top-most.
The example below illustrates these concepts:
<fieldset class="spark-mar-b-2">
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 1 Input Label 1</span>
</label>
<label class="spark-input spark-mar-b-0">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 1 Input Label 2</span>
</label>
</fieldset>
<fieldset>
<label class="spark-input">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 2 Input Label 1</span>
</label>
<label class="spark-input spark-mar-b-0">
<input class="spark-input__field" name="example1" placeholder="Helper text..." role="textbox">
<span class="spark-label">Group 2 Input Label 2</span>
</label>
</fieldset>
<nav class="spark-btn-group spark-mar-t-2">
<button class="spark-btn spark-btn--md spark-btn--secondary spark-btn-group-secondary spark-btn--block-xs">Secondary</button>
<button class="spark-btn spark-btn--md spark-btn-group-primary spark-btn--block-xs |">Primary</button>
</nav>
When adding components to forms, ensure that any javascript required at a component-level has been included. Refer to the Integrating Spark documentation for more information.