The Input
class applies Champion branding to most text-based form elements.
<input class="Input" type="text" value="Text">
<input class="Input" type="search" placeholder="Search by keyword…">
<input class="Input" type="email" value="info@championpowerequipment.com">
<input class="Input" type="date" value="2017-05-17">
<input class="Input" type="number" value="9000" pattern="[0-9]*" inputmode="numeric">
<input class="Input" type="file">
<input class="Input" type="file" disabled>
<input class="Input" type="text" value="Disabled" disabled>
<input class="Input" type="text" value="Read-only" readonly>
<select class="Input">
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
<textarea class="Input">Champion’s totally automatic solution provides security, convenience, health and safety — all things that every homeowner holds dear. Don’t put these things at risk during a power outage. Millions of individuals suffer from the effects of a power outage annually.
</textarea>
The following cosmetic modifiers are available for different scenarios:
Input--contrast
adjusts border and focus colors for display against
saturated colors.Input--onDark
optimized border and focus colors for darker backgrounds.Input--success
for validated form fields.Input--danger
for invalid form fields.Input--withDropdown
for JavaScript interactions that use an <input>
element to trigger a dropdown.Inputs and buttons may be visually "joined" using the InputGroup
pattern and
associated child classes:
InputGroup-input
for text-based input elements.InputGroup-action
for buttons or other actionable elements.InputGroup-iconLabel
for iconographic labels that appear inset in adjacent
InputGroup-input
elements.Works well with existing Input
and Button
patterns, though they aren't
strictly required.
If you add js-InputGroup
and js-InputGroup-input
classes and there is only
one of the latter, focus ring of the input will surround the entire group. Be
sure to add the InputGroup--contrast
modifier if the Input--contrast
modifier is in use.
<div class="u-pad1">
<div class="InputGroup js-InputGroup">
<label class="InputGroup-iconLabel" for="demo-input-group">
<svg width="28" height="28" viewBox="0 0 28 28" aria-labelledby="demo-input-group-label" class="Icon">
<title id="demo-input-group-label">Label text</title>
<path d="M28 11.094v12.406c0 1.375-1.125 2.5-2.5 2.5h-23c-1.375 0-2.5-1.125-2.5-2.5v-12.406c0.469 0.516 1 0.969 1.578 1.359 2.594 1.766 5.219 3.531 7.766 5.391 1.313 0.969 2.938 2.156 4.641 2.156h0.031c1.703 0 3.328-1.188 4.641-2.156 2.547-1.844 5.172-3.625 7.781-5.391 0.562-0.391 1.094-0.844 1.563-1.359zM28 6.5c0 1.75-1.297 3.328-2.672 4.281-2.438 1.687-4.891 3.375-7.313 5.078-1.016 0.703-2.734 2.141-4 2.141h-0.031c-1.266 0-2.984-1.437-4-2.141-2.422-1.703-4.875-3.391-7.297-5.078-1.109-0.75-2.688-2.516-2.688-3.938 0-1.531 0.828-2.844 2.5-2.844h23c1.359 0 2.5 1.125 2.5 2.5z" />
</svg> </label>
<input class="Input InputGroup-input js-InputGroup-input" type="text" placeholder="Example" id="demo-input-group">
<button class="Button InputGroup-action">
Action
</button>
</div>
</div>
<div class="u-bgBlack u-pad1">
<div class="InputGroup js-InputGroup">
<label class="InputGroup-iconLabel" for="demo-input-group">
<svg width="28" height="28" viewBox="0 0 28 28" aria-labelledby="demo-input-group-label" class="Icon">
<title id="demo-dark-input-group-label">Label text</title>
<path d="M28 11.094v12.406c0 1.375-1.125 2.5-2.5 2.5h-23c-1.375 0-2.5-1.125-2.5-2.5v-12.406c0.469 0.516 1 0.969 1.578 1.359 2.594 1.766 5.219 3.531 7.766 5.391 1.313 0.969 2.938 2.156 4.641 2.156h0.031c1.703 0 3.328-1.188 4.641-2.156 2.547-1.844 5.172-3.625 7.781-5.391 0.562-0.391 1.094-0.844 1.563-1.359zM28 6.5c0 1.75-1.297 3.328-2.672 4.281-2.438 1.687-4.891 3.375-7.313 5.078-1.016 0.703-2.734 2.141-4 2.141h-0.031c-1.266 0-2.984-1.437-4-2.141-2.422-1.703-4.875-3.391-7.297-5.078-1.109-0.75-2.688-2.516-2.688-3.938 0-1.531 0.828-2.844 2.5-2.844h23c1.359 0 2.5 1.125 2.5 2.5z" />
</svg> </label>
<input class="Input InputGroup-input Input--onDark js-InputGroup-input" type="text" placeholder="Dark Example" id="demo-dark-input-group">
<button class="Button InputGroup-action u-bgSilver u-textBlack">
Action
</button>
</div>
</div>
<div class="u-bgYellow u-pad1">
<div class="InputGroup js-InputGroup InputGroup--contrast">
<label class="InputGroup-iconLabel" for="demo-input-group">
<svg width="28" height="28" viewBox="0 0 28 28" aria-labelledby="demo-input-group-label" class="Icon">
<title id="demo-contrast-input-group-label">Label text</title>
<path d="M28 11.094v12.406c0 1.375-1.125 2.5-2.5 2.5h-23c-1.375 0-2.5-1.125-2.5-2.5v-12.406c0.469 0.516 1 0.969 1.578 1.359 2.594 1.766 5.219 3.531 7.766 5.391 1.313 0.969 2.938 2.156 4.641 2.156h0.031c1.703 0 3.328-1.188 4.641-2.156 2.547-1.844 5.172-3.625 7.781-5.391 0.562-0.391 1.094-0.844 1.563-1.359zM28 6.5c0 1.75-1.297 3.328-2.672 4.281-2.438 1.687-4.891 3.375-7.313 5.078-1.016 0.703-2.734 2.141-4 2.141h-0.031c-1.266 0-2.984-1.437-4-2.141-2.422-1.703-4.875-3.391-7.297-5.078-1.109-0.75-2.688-2.516-2.688-3.938 0-1.531 0.828-2.844 2.5-2.844h23c1.359 0 2.5 1.125 2.5 2.5z" />
</svg> </label>
<input class="Input InputGroup-input Input--contrast js-InputGroup-input" type="text" placeholder="Contrast Example" id="demo-contrast-input-group">
<button class="Button InputGroup-action">
Action
</button>
</div>
</div>
Custom checkbox and radio styles optimized for easier touch behavior and more
branded appearance. Works using a hidden <input>
and adjacent selectors,
which gives much more consistent behavior without requiring JavaScript.
<p>
<label class="Toggle u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="checkbox" id="patterns.elements.forms.toggles" name="Toggles" checked>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Checkbox (Checked)
</span>
</label>
</p>
<p>
<label class="Toggle u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="checkbox" id="patterns.elements.forms.toggles" name="Toggles">
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Checkbox
</span>
</label>
</p>
<p>
<label class="Toggle u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="checkbox" id="patterns.elements.forms.toggles" name="Toggles" checked disabled>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Disabled Checkbox (Checked)
</span>
</label>
</p>
<p>
<label class="Toggle u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="checkbox" id="patterns.elements.forms.toggles" name="Toggles" disabled>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Disabled Checkbox
</span>
</label>
</p>
<p>
<label class="Toggle Toggle--radio u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="radio" id="patterns.elements.forms.toggles" name="drizzleRadioDemo" checked>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Radio 1
</span>
</label>
</p>
<p>
<label class="Toggle Toggle--radio u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="radio" id="patterns.elements.forms.toggles" name="drizzleRadioDemo">
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Radio 2
</span>
</label>
</p>
<p>
<label class="Toggle Toggle--radio u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="radio" id="patterns.elements.forms.toggles" name="drizzleRadioDemoDisabled" checked disabled>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Disabled Radio 1 (Checked)
</span>
</label>
</p>
<p>
<label class="Toggle Toggle--radio u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="radio" id="patterns.elements.forms.toggles" name="drizzleRadioDemoDisabled" disabled>
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Disabled Radio 2
</span>
</label>
</p>
Toggles have a few more tricks up their sleeve.
You can add Toggle
to a non-<label>
element by including the <label>
as
a child with the class Toggle-delegate
. This also allows you to add the
Toggle-expand
class to a different adjacent element, allowing you to toggle
the visibility of a sibling for simple progressive disclosure form fields
without JavaScript.
<div class="Toggle u-flex u-flexAlignItemsCenter">
<input class="Toggle-state " type="checkbox" id="window-ac-unit">
<label class="Toggle-delegate u-flex u-flexAlignItemsCenter" for="window-ac-unit">
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text"> Window AC Unit
</span>
</label>
<div class="Toggle-expand u-flexExpandLeft u-size1of6 u-pullEnds01">
<label class="u-hiddenVisually" for="count-window-ac-unit">
Amount
</label>
<input class="Input" type="number" value="1" id="count-window-ac-unit">
</div>
</div>
Add a Toggle-expand--disclosure
modifier class to the Toggle-expand
element to show a disclosure indicator in the form of a gray line enclosing
the expanded content.
<div class="Toggle">
<input class="Toggle-state" type="checkbox" id="more-info-needed">
<label class="Toggle-delegate u-flex u-flexAlignItemsCenter" for="more-info-needed">
<span class="Toggle-indicator u-spaceRight06" aria-hidden="true"></span>
<span class="Toggle-text">A different retailer…</span>
</label>
<div class="Toggle-expand Toggle-expand--disclosure u-spaceTop1 u-spaceItems06">
<label for="purchase-retailer" class="u-textWeightBold">Retailer name</label>
<input class="Input" id="purchase-retailer">
</div>
</div>
The Input Results component allows you to display filtered results in a dropdown as the customer types in their search. Depending on your needs you can prepopulate the dropdown, or use AJAX Ajax to hit a search endpoint.
The component is composed of the following elements:
InputResults
- Containing elementInputResults--overlay
- Optional modifier that makes the dropdown overlay
surrounding content instead of increasing the container heightInputResults-item
- An individual result, assumed to be an <a>
elementInputResults-object
- Optional container for a visual element in an item,
for example an icon or thumbnailInputResults-label
- The actual text for the itemInputResults-muted
- An element that will appear lighter in color until
the item is interacted with via hover or focusDisabled Inputs: Adding is-disabled
to InputResults-item
will visually
render that item with a disabled appearance and cursor behavior.
There are a handful of configuration options that can be passed in via data attributes:
data-url
- the AJAX endpoint urldata-prepopulated
- Whether the dropdown is prepopulateddata-close-outside
- Whether to close the dropdown when a user clicks
outside of itdata-delay
- When using AJAX, how long to wait between AJAX callsdata-min-length
- When using AJAX, how many characters must be typed before
searchingdata-key
- When using AJAX this is the name of the search query string
parameterAdd a data-url
to enable the AJAX search option.
This example endpoint will always return the same data. When using this on a real site the endpoint would return filtered search data.
<div class="InputResults js-InputResults" data-url="/prototype-endpoints/input-results.json">
<input class="Input js-InputResults-input" type="search" placeholder="Type to see…">
<ul class="InputResults-dropdown js-InputResults-dropdown" aria-hidden="true"></ul>
</div>
The Input Results component is often used to allow searching a series of
links, but it can be used as an enhanced <select>
dropdown as well.
To get this to work make sure each InputResults-item
is a <button>
,
not a link. Then add a data-val
attribute to each button.
When a customer clicks a button the input will be populated with the
data-val
and the dropdown will close.
You can also add the Input--withDropdown
modifier to the Input
for a
visual cue.
<div class="InputResults js-InputResults" data-prepopulated="true" data-close-outside="true">
<input class="Input js-InputResults-input Input--withDropdown" type="text" placeholder="Type to see…">
<ul class="InputResults-dropdown js-InputResults-dropdown" aria-hidden="true">
<li>
<button type="button" class="InputResults-item js-InputResults-item" data-val="123456">
<div class="InputResults-object">
<img src="/images/prototypes/generators/42436_hero-8_26_13_hi-res.jpg" alt="">
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Model #123456</p>
<p class="u-textTruncate">Not Really a Product Name</p>
</div>
</button>
</li>
<li>
<button type="button" class="InputResults-item is-disabled js-InputResults-item" data-val="123456">
<div class="InputResults-object">
<img src="/images/prototypes/generators/42436_hero-8_26_13_hi-res.jpg" alt="">
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Model #123456</p>
<p class="u-textTruncate">Product Coming Soon</p>
</div>
</button>
</li>
<li>
<button type="button" class="InputResults-item js-InputResults-item" data-val="Fictional Category Name">
<div class="InputResults-label">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Product Category</p>
<p class="u-textTruncate js-InputResults-searchable">Fictional Category Name</p>
</div>
</button>
</li>
<li>
<button type="button" class="InputResults-item js-InputResults-item" data-val="Fake File">
<div class="InputResults-object">
<svg class="FileIcon FileIcon--pdf " viewBox="-4 0 42 48" width="42" height="48">
<polygon class="FileIcon-base" points="38 48 0 48 0 0 26 0 38 12 38 48" />
<polygon class="FileIcon-front" points="35 45 3 45 3 3 22 3 22 16 35 16 35 45" fill="#fff" />
<polygon class="FileIcon-fold" points="25 3 35 13 25 13 25 3" fill="#fff" />
<rect class="FileIcon-badge" x="-4" y="21" width="34" height="18" rx="3" />
<text class="FileIcon-label" text-anchor="middle" x="13" y="34" font-size="12" fill="#fff">PDF</text>
</svg>
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="u-textTruncate">Fake File</p>
</div>
</button>
</li>
<li>
<button disabled type="button" class="InputResults-item js-InputResults-item" data-val="Disabled Item">
<div class="InputResults-object">
<svg class="FileIcon FileIcon--pdf " viewBox="-4 0 42 48" width="42" height="48">
<polygon class="FileIcon-base" points="38 48 0 48 0 0 26 0 38 12 38 48" />
<polygon class="FileIcon-front" points="35 45 3 45 3 3 22 3 22 16 35 16 35 45" fill="#fff" />
<polygon class="FileIcon-fold" points="25 3 35 13 25 13 25 3" fill="#fff" />
<rect class="FileIcon-badge" x="-4" y="21" width="34" height="18" rx="3" />
<text class="FileIcon-label" text-anchor="middle" x="13" y="34" font-size="12" fill="#fff">PDF</text>
</svg>
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="u-textTruncate">Disabled Item</p>
</div>
</button>
</li>
</ul>
</div>
In some cases it's more performant to prepopulate the dropdown and perform
filtering and searching client-side. To enable this remove the data-url
and add data-prepopulated="true"
.When using the prepopulated option, the
following settings are ignored:
data-url
data-delay
data-min-length
The text to search for matches should be wrapped in the
js-InputResults-searchable
class. Anything outside of that class will be
ignored when searching.
<div class="InputResults js-InputResults" data-prepopulated="true" data-close-outside="true">
<input class="Input js-InputResults-input Input--withDropdown" type="search" placeholder="Type to see…">
<ul class="InputResults-dropdown js-InputResults-dropdown" aria-hidden="true">
<li>
<a href="#" type="button" class="InputResults-item js-InputResults-item">
<div class="InputResults-object">
<img src="/images/prototypes/generators/42436_hero-8_26_13_hi-res.jpg" alt="">
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Model #123456</p>
<p class="u-textTruncate">Not Really a Product Name</p>
</div>
</a>
</li>
<li>
<a href="#" type="button" class="InputResults-item is-disabled js-InputResults-item">
<div class="InputResults-object">
<img src="/images/prototypes/generators/42436_hero-8_26_13_hi-res.jpg" alt="">
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Model #123456</p>
<p class="u-textTruncate">Product Coming Soon</p>
</div>
</a>
</li>
<li>
<a href="#" type="button" class="InputResults-item js-InputResults-item">
<div class="InputResults-label">
<p class="InputResults-muted u-textShrink1 u-textTruncate">Product Category</p>
<p class="u-textTruncate js-InputResults-searchable">Fictional Category Name</p>
</div>
</a>
</li>
<li>
<a href="#" type="button" class="InputResults-item js-InputResults-item">
<div class="InputResults-object">
<svg class="FileIcon FileIcon--pdf " viewBox="-4 0 42 48" width="42" height="48">
<polygon class="FileIcon-base" points="38 48 0 48 0 0 26 0 38 12 38 48"/>
<polygon class="FileIcon-front" points="35 45 3 45 3 3 22 3 22 16 35 16 35 45" fill="#fff"/>
<polygon class="FileIcon-fold" points="25 3 35 13 25 13 25 3" fill="#fff"/>
<rect class="FileIcon-badge" x="-4" y="21" width="34" height="18" rx="3"/>
<text class="FileIcon-label" text-anchor="middle" x="13" y="34" font-size="12" fill="#fff">PDF</text>
</svg>
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="u-textTruncate">Fake File</p>
</div>
</a>
</li>
<li>
<button disabled type="button" class="InputResults-item js-InputResults-item">
<div class="InputResults-object">
<svg class="FileIcon FileIcon--pdf " viewBox="-4 0 42 48" width="42" height="48">
<polygon class="FileIcon-base" points="38 48 0 48 0 0 26 0 38 12 38 48" />
<polygon class="FileIcon-front" points="35 45 3 45 3 3 22 3 22 16 35 16 35 45" fill="#fff" />
<polygon class="FileIcon-fold" points="25 3 35 13 25 13 25 3" fill="#fff" />
<rect class="FileIcon-badge" x="-4" y="21" width="34" height="18" rx="3" />
<text class="FileIcon-label" text-anchor="middle" x="13" y="34" font-size="12" fill="#fff">PDF</text>
</svg>
</div>
<div class="InputResults-label js-InputResults-searchable">
<p class="u-textTruncate">Disabled Item</p>
</div>
</button>
</li>
</ul>
</div>
Add js-ElasticTextarea
to a <textarea>
element to have it expand as the
user types more than will fit.
rows
attribute is set, it will be used as the minimum height.<textarea class="Input js-ElasticTextarea" placeholder="Type stuff"></textarea>