Forms

Form inputs have been considered from an accessibility and user experience point of view. These inputs deliver the best solution for inputting and focusing on elements. They also provide clear, visual user feedback as a form is traversed or submitted. Each input has a transparent background and we recommend form inputs are used only on a solid background of ‘Brand3’ or ‘Brand4’. Standard inputs include an inline label in the text field but can also be used with the label above the input field where needed e.g. above a radio list. The focus state of each label would remain in each case for consistent visual feedback. Labels can be shown or hidden as required. All forms contain space for entering information, labels, in form icons and feedback messages below. Form inputs can appear on their own row (stacked) or they can be put side by side with other relevant fields, when space is available. 16px of margin between both field input/label blocks is required.

Utility classes

  • rc-input--full-width - Disables the fixed max width and allows the input to fill its parent.
  • rc-select-group - Adds flexbox layout to sibling selects to improve how selects sit next to each other.
  • rc-input--label - Adds a top margin when a transition label is needed.
  • rc-margin-*--* - Our spacing utility classes can also be used to fine tune margins to suit your needs.

Text

Initially an input will have placeholder copy with a colour of ‘Text’ at 50% opacity and a 2px bottom border of ‘Interface’ with a colour of ‘Interface’. On clicking into the input, placeholder copy will become 100% opacity and the bottom border will transition from left to right in colour to a colour of ‘Text’, darkening the border and placeholder copy giving the element more emphasis. The transition will use our global transition property. On entering information into the input, the font-weight will transition from Medium to Regular and the placeholder copy will seamlessly transition to be above the input with a weight of Medium, this gives contrasting weights between our consistently visible placeholder copy and our users entered information.'

html
            <span class="rc-input rc-input--inline rc-input--label">
 	<input class="rc-input__control" id="id-text1" type="text" name="text">
 	<label class="rc-input__label" for="id-text1"><span class="rc-input__label-text">Text input</span></label>
</span>
        

Inline inputs

Inputs can be inlined using rc-input--inline, and aligned horizontally using rc-input--label depending on whether the input has a label or not. Note: if option is really long, add data-title custom attribute to it. This will create native title/tooltip option on hover state.

html
            <div class="rc-layout-container rc-one-column rc-content-h-bottom">
  <div class="rc-column">
    <span class="rc-input rc-input--inline rc-input--label">
      <input class="rc-input__control" id="id-text1" type="text" name="text">
      <label class="rc-input__label" for="id-text1"><span class="rc-input__label-text">Text input</span></label>
    </span>
    <span class="rc-select rc-input--inline rc-input--label">
      <label class="rc-select__label" for="id-single-select">I am interested in</label>
      <select data-js-select id="id-single-select">
        <option selected disabled value="" placeholder>Select an option</option>
        <option disabled>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
        <option data-custom="Some data">Option 4</option>
        <option data-title="Option 5 - that is example of really long option to select">Option 5 - that is example of really long option to select</option>
        <option data-other-custom="Other custom data">Option 6</option>
        <option>Option 7</option>
        <option>Option 8</option>
        <option>Option 9</option>
      </select>
    </span>
    <span class="rc-input rc-input--inline rc-input--label">
      <input class="rc-input__date" type="date" id="id-date" name="example-date-input" data-js-dateformat="DD/MM/YYYY" />
      <label class="rc-input__label" for="id-date"><span class="rc-input__label-text">Date</span></label>
    </span>
  </div>
</div>
        

Success

This states gives users important feedback that certain criteria must be met but that an error has not yet occured. It uses the ‘Warning’ colour. This is particularly useful for form elements such as email and passwords where validation criteria may be required. It is recommended that warning states include a short descriptor to assist and give users clarity. This should be used to display that criteria have not yet been met, but where the user has not yet completed the input fields, clicked out of the field or attempted to submit the form information.

Success Message
html
            <span class="rc-input rc-input--success" data-js-validate data-js-success-message="Success message">
	<input class="rc-input__control" id="id-text3" type="text" name="text" />
	<label class="rc-input__label" for="id-text3"><span class="rc-input__label-text">Success input</span></label>
</span>
        

Warning

This states give users important feedback that certain criteria must be met but that an error has not yet occured. It uses the ‘Warning’ colour. This is particularly useful for form elements such as email and passwords where validation criteria may be required. It is recommended that warning states include a short descriptor to assist and give users clarity. This should be used to display that criteria have not yet been met, but where the user has not yet completed the input fields, clicked out of the field or attempted to submit the form information.

Warning message
html
            <span class="rc-input rc-input--warning" data-js-validate data-js-warning-message="Warning message">
	<input class="rc-input__control" id="id-text5" type="text" name="text" />
	<label class="rc-input__label" for="id-text5"><span class="rc-input__label-text">Warning input</span></label>
</span>
        

Error

Incorrectly completed fields are indicated by our border transitioning to the ‘Error’ colour and also use a right-aligned 16px icon of warning which is also shaded in the ‘Error’ colour. Error states can be used on all mandatory form elements when a form is submitted and information has not been provided in a mandatory field.

Error message
html
            <span class="rc-input rc-input--error" data-js-validate data-js-error-message="Error message">
	<input class="rc-input__control" id="id-text6" type="text" name="text" />
	<label class="rc-input__label" for="id-text6"><span class="rc-input__label-text">Error input</span></label>
</span>
        

Optional

Form fields by their nature should be used where information is required. Ideally no indication of a field being mandatory will ever need to be required. Forms should only provide fields that a user needs to complete to progress. If other inputs are offered to a user as part of a larger form we would prefer to indicate which inputs are optional fields rather than indicate that everything else is mandatory on the form.

html
            <span class="rc-input">
	<input class="rc-input__control" id="id-text7" type="text" name="text" optional/>
	<label class="rc-input__label" for="id-text7"><span class="rc-input__label-text">Input (optional)</span></label>
</span>
        

Disabled

Disabled inputs may be required for fields that cannot have their information changed or are locked until another action is completed, before they become editable. Disabled inputs follow the same style as a standard input apart from they have ‘Interface’ as a background colour and have an attribute of disabled="" on their markup.

html
            <span class="rc-input">
	<input class="rc-input__control" id="id-text8" type="text" name="text" disabled>
	<label class="rc-input__label" for="id-text8"><span class="rc-input__label-text">Input text</span></label>
</span>
        

Email

An email field demonstrates well the various errors that may be used for form validation.

html
            <span class="rc-input" data-js-validate data-js-warning-message="Please enter a valid email">
	<input class="rc-input__control" id="id-email" type="email" name="email" />
	<label class="rc-input__label" for="id-email"><span class="rc-input__label-text">Email input</span></label>
</span>
        

Search

Search fields use the same Dimensions properties as a normal text field for icon position but at the start of an input rather than at the end (such as a Success input). This is because traditionally a search bar uses a search icon to the left of the entered information. All other rules around a search field are the same as a default text field.

html
            <span class="rc-input">
    <button class="rc-input__submit rc-input__submit--search" type="submit"><span class="rc-screen-reader-text">Submit</span></button>
    <input class="rc-input__control" id="id-submit" type="text" name="search" />
    <label class="rc-input__label" for="id-submit"><span class="rc-input__label-text">Search</span></label>
</span>
        

Micro form

For single field inputs they can be combined with an Action Button to create a Micro Form. Micro Forms are for when there is simply one main task to complete on a page or application, such as searching for a supplier or entering a discount code. When Micro forms are used all rules around standard inputs still apply.

html
            <span class="rc-input">
    <input class="rc-input__control" id="id-submit2" type="text" name="email" />
    <label class="rc-input__label" for="id-submit2"><span class="rc-input__label-text">Submit</span></label>
    <button class="rc-input__submit rc-input__submit--micro" type="submit"><span class="rc-screen-reader-text">Submit</span></button>
</span>
        

Password

Password fields have two distinct states, one for hiding the password (default) and a toggle option for a user to easily see their password once they have entered it. This password field follows the same rules as Success and Failure inputs for the positioning of their iconography with the distinct difference of the View icon sitting outside of the input due it needing its own clickable hit area due to being a toggle between the two states. Icon toggles switch from a colour of ‘Iconography’ to ‘Brand1’ on click/touch.

html
            <span class="rc-input rc-input--inline" data-js-validate data-js-warning-message="Must be at least X characters">
  <input class="rc-input__password" id="id-password" type="password" name="password" data-js-match="id-password-2" />
  <label class="rc-input__label" for="id-password">
    <span class="rc-input__label-text">Your password</span>
  </label>
</span>

<span class="rc-input rc-input--inline" data-js-validate data-js-error-message="Passwords don't match" data-js-success-message="Passwords match">
  <input class="rc-input__password" id="id-password-2" type="password" name="password" />
  <label class="rc-input__label" for="id-password-2">
    <span class="rc-input__label-text">Confirm password</span>
  </label>
</span>
        

Textarea

Textareas follow all of the same rules and transitions surrounding focus and text entry from Text Fields but with a difference in how the borders are styled. We change from a bottom only border to an entirely surrounded border which helps to emphasise how large the textarea is for a user to enter information in.

html
            <span class="rc-input">
	<textarea class="rc-input__textarea" id="id-textarea"></textarea>
	<label class="rc-input__label" for="id-textarea"><span class="rc-input__label-text">Textarea</span></label>
</span>
        

Radio

Radio button lists are used when a user is required to pick one option from a small list. Radio buttons are custom styled with a ‘Brand1’ colour selected state. Where possible the options should be listed in a logical order, such as most likely to be selected to least likely to be selected. Alphabetical ordering is not recommended because it is language dependent and therefore not localisable. Options should be listed vertically, with one option per line whenever possible. Horizontal layouts can also be used to save space if only two to three options are required under the label. Users should be able to select an option by clicking or tapping the radio button, the text label or associated words.

html
            <div class="rc-input rc-input--inline">
	<input class="rc-input__radio" id="id-radio-cat" type="radio" name="radio" value="input-label" />
	<label class="rc-input__label--inline" for="id-radio-cat">Cat</label>
</div>

<div class="rc-input rc-input--inline">
	<input class="rc-input__radio" id="id-radio-dog" type="radio" name="radio" value="input-label" checked="" />
	<label class="rc-input__label--inline" for="id-radio-dog">Dog</label>
</div>
        
html
            <div class="rc-input rc-input--stacked">
	<input class="rc-input__radio" id="id-radio-cat2" type="radio" name="radio" value="input-label" />
	<label class="rc-input__label--inline" for="id-radio-cat2">Cat</label>
</div>

<div class="rc-input rc-input--stacked">
	<input class="rc-input__radio" id="id-radio-dog2" type="radio" name="radio" value="input-label" checked="" />
	<label class="rc-input__label--inline" for="id-radio-dog2">Dog</label>
</div>
        

Checkboxes

Checkboxes are used when the user may select any number of choices from a list, including zero, one, or several options. Checkboxes are custom styled with ‘icon--tick’ Iconography and are coloured in ‘Brand1’ in place of the browser default ticks. The rules around checkbox forms are the same as radio forms:

html
            <div class="rc-input rc-input--inline">
	<input class="rc-input__checkbox" id="id-checkbox-cat" type="checkbox" name="checkbox" value="input-label" />
	<label class="rc-input__label--inline" for="id-checkbox-cat">Cat</label>
</div>

<div class="rc-input rc-input--inline">
	<input class="rc-input__checkbox" id="id-checkbox-dog" type="checkbox" name="checkbox" value="input-label" checked="" />
	<label class="rc-input__label--inline" for="id-checkbox-dog">Dog</label>
</div>
        
html
            <div class="rc-input rc-input--stacked">
	<input class="rc-input__checkbox" id="id-checkbox-cat2" type="checkbox" name="checkbox" value="input-label" />
	<label class="rc-input__label--inline" for="id-checkbox-cat2">Cat</label>
</div>

<div class="rc-input rc-input--stacked">
	<input class="rc-input__checkbox" id="id-checkbox-dog2" type="checkbox" name="checkbox" value="input-label" checked="" />
	<label class="rc-input__label--inline" for="id-checkbox-dog2">Dog</label>
</div>
        

Standard Select

Selects are styled using the same rules defined for text fields regarding border and focus properties. Differences are that they have a right aligned Chevron-Down / Chevron-Up state when clicked which indicates the dropdown is open or closed. Icon Chevron-Down is used here to indicate the element is clickable. On click of the select, the custom dropdown is revealed with our available options. The icon switches to Chevron-Up and uses a toggle state of ‘Brand1’. In the above example, we showcase a hover state which is a background colour of ‘Brand4’ ’and the option selected by the user becomes apparent within the select area itself.

html
            <span class="rc-select">
  <label class="rc-select__label" for="id-single-select">I am interested in</label>
  <select data-js-select id="id-single-select">
    <option selected disabled value="" placeholder>Select an option</option>
    <option disabled>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
    <option data-custom="Some data">Option 4</option>
    <option>Option 5</option>
    <option>Option 6</option>
    <option>Option 7</option>
    <option>Option 8</option>
    <option>Option 9</option>
  </select>
</span>
        

Custom Standard Select

Selects can be initialised with a custom selector and options object using the JavaScript below. This is useful for tailoring the selects to your specific use case. For example: dynamically generating items, applying a custom sort filter, choosing alternative select text etc. Design Language selects utilise the Choices.js library and a full list of options and more in-depth documentation can be seen on their Github repository.


   let options = {
     shouldSort: true,
     searchEnabled: true,
     itemSelectText: 'Custom',
     classNames: {
       item: 'choices__item choices__item--custom-data'
     }
   };

   RCDL.ready('Selects', ['[data-js-custom-select]', null, options]);
 

html
            <span class="rc-select">
  <label class="rc-select__label" for="id-single-select">I am interested in</label>
  <select data-js-custom-select id="id-single-select">
    <option selected disabled value="" placeholder>Select an option</option>
    <option disabled>Option 1</option>
    <option>Option 2</option>
    <option data-custom="Some data">Option 3</option>
    <option>Option 4</option>
    <option>Option 5</option>
    <option>Option 6</option>
    <option>Option 7</option>
    <option>Option 8</option>
    <option>Option 9</option>
  </select>
</span>
        

Multi Select

Multi-select dropdowns can be used when a user can select multiple options from a list of many. Icon Chevron-Down is used here to indicate the element is clickable. On click of the select, the custom dropdown is revealed with our available options. Available options become greyed out at 50% opacity the more options are selected (Boxer in the above example). Selected options are indicated by a band in colour of ‘Text’ with a copy colour of ‘Brand3’; they are also indicated by a tick icon indicated to a user they have selected this option and as many more as are available to them.

html
            <span class="rc-select">
  <label class="rc-select__label" for="id-multi-select">I am interested in</label>
  <select multiple data-js-select data-custom-attr="Custom" data-js-select-placeholder="Please select..." id="id-multi-select">
    <optgroup label="Option Group">
      <option disabled>Option 1</option>
      <option data-custom-one="Some data" data-custom-two="Some more data">Option 2</option>
      <option>Option 3</option>
    </optgroup>
    <optgroup label="Option Group">
      <option>Option 4</option>
      <option>Option 5</option>
      <option data-custom="Some data">Option 6</option>
      <option>Option 7</option>
      <option>Option 8</option>
      <option>Option 9</option>
    </optgroup>
  </select>
</span>
        

Custom Multi Select

Multi selects can be initialised with a custom selector and options object using the JavaScript below. This is useful for tailoring the selects to your specific use case. For example: dynamically generating items, applying a custom sort filter, choosing alternative select text etc. Design Language selects utilise the Choices.js library and a full list of options and more in-depth documentation can be seen on their Github repository. To insert a value from a data attribute, simply refer to that attribute in your options.


   let multiOptions = {
     placeholderValue: 'data-js-custom-placeholder',
     shouldSort: false,
     searchEnabled: true,
     itemSelectText: 'Custom'
     classNames: {
       item: 'choices__item choices__item--custom-data'
     }
   };

   RCDL.ready('Selects', ['[data-js-custom-select]', null, multiOptions]);
 

html
            <span class="rc-select">
  <label class="rc-select__label" for="id-multi-select">I am interested in</label>
  <select multiple data-js-custom-multi data-js-custom-multi-placeholder="Custom..." id="id-multi-select">
    <optgroup label="Option Group">
      <option>Option 3</option>
      <option disabled>Option 1</option>
      <option>Option 2</option>
    </optgroup>
    <optgroup label="Option Group">
      <option>Option 8</option>
      <option data-custom="Some data">Option 6</option>
      <option>Option 5</option>
      <option>Option 7</option>
      <option>Option 4</option>
      <option>Option 9</option>
    </optgroup>
  </select>
</span>
        

Date

A date picker is used to easily traverse days, years and months. For the scenario when a pet owner may not know the exact date of birth of their pet a checkbox should be used which swaps the date picker to an inactive state and presents the user with a select year field. The assumption here is that if the user knows the month and year they can use the standard date picker, choosing any specific day of the month. Where the date is not a mandatory the input label should read (optional).

html
            <span class="rc-input">
	<input class="rc-input__date" type="date" id="id-date" name="example-date-input" data-js-dateformat="DD/MM/YYYY" />
  <label class="rc-input__label" for="id-date"><span class="rc-input__label-text">Date</span></label>
</span>
        

Number

Number picker is not supported in IE. Fallback will be text input only. Number picker Inline label active state not working in IE on v8.1.1

html
            <span class="rc-input">
 	<input class="rc-input__control" id="id-number" type="number" name="number">
 	<label class="rc-input__label" for="id-number"><span class="rc-input__label-text">Number</span></label>
</span>
        

Telephone

html
            <span class="rc-input">
 	<input class="rc-input__control" id="id-tel" type="tel" name="tel">
 	<label class="rc-input__label" for="id-tel"><span class="rc-input__label-text">Telephone</span></label>
</span>
        

URL

html
            <span class="rc-input">
 	<input class="rc-input__control" id="id-url" type="url" name="url">
 	<label class="rc-input__label" for="id-url"><span class="rc-input__label-text">URL</span></label>
</span>
        

Issues

If you are having problems implementing this code, please submit an issue on our Github page.

Github Octocat

Feedback

If you would like to offer feedback on the design of this component, please send an email requesting access to the Design Language Slack channel.

Slack logo

Changelog

  • 26th October 2018 [ui_assets/elements/forms.yml]
    Update inline icons wrapper to make sure it's aligned correctly.
  • 26th October 2018 [ui_assets/elements/forms.yml]
    Change type text to type data
  • 25th October 2018 [ui_assets/elements/forms.yml]
    Updated examples that contain date input
  • 4th October 2018 [ui_assets/elements/forms.yml]
    Add options to example for custom select.
  • 2nd October 2018 [ui_assets/elements/forms.yml]
    Add more options with custom data, and explanation in docs.
  • 26th September 2018 [ui_assets/elements/forms.yml]
    Add example of long select option
  • 21st September 2018 [ui_assets/elements/forms.yml]
    Undo auto-format
  • 21st September 2018 [ui_assets/elements/forms.yml]
    Added docs on how to use new input classes
  • 13th September 2018 [ui_assets/elements/forms.yml]
    Spelling/ grammar
  • 13th September 2018 [ui_assets/elements/forms.yml]
    spelling & grammar corrections
  • 7th September 2018 [ui_assets/elements/forms.yml]
    Tweak portal only logo layout.
  • 2nd August 2018 [ui_assets/elements/forms.yml]
    Update form docs
  • 1st August 2018 [ui_assets/elements/forms.yml]
    Added some test data-attributes to select options
  • 31st July 2018 [ui_assets/elements/forms.yml]
    Added docs for choices js
  • 25th July 2018 [ui_assets/elements/forms.yml]
    prefix input__label-text
  • 12th July 2018 [ui_assets/elements/forms.yml]
    Update forms classes.
  • 12th July 2018 [ui_assets/elements/forms.yml]
    Prefixed classes throughout the portal with rc-.
  • 11th June 2018 [ui_assets/elements/forms.yml]
    Add element dump page for testing.
  • 1st June 2018 [ui_assets/elements/forms.yml]
    add disclaimer to forms
  • 31st May 2018 [ui_assets/elements/forms.yml]
    add numberpicker IE disclaimer
  • 8th March 2018 [ui_assets/elements/forms.yml]
    Updated keywords, removed old HTML files
  • 8th March 2018 [ui_assets/elements/forms.yml]
    Renamed header-nav to bar, page copy improvements
  • 19th February 2018 [ui_assets/elements/forms.yml]
    Convert all multi line text to use
  • 8th February 2018 [ui_assets/elements/forms.yml]
    Added placeholder data-attribute for multi-select
  • 7th February 2018 [ui_assets/elements/forms.yml]
    Added validation to form page and updated register form
  • 5th February 2018 [ui_assets/elements/forms.yml]
    Fixed register modal validation
  • 5th February 2018 [ui_assets/elements/forms.yml]
    Removed extra full stops
  • 5th February 2018 [ui_assets/elements/forms.yml]
    Added link to icons page to buttons, minor copy updates
  • 5th February 2018 [ui_assets/elements/forms.yml]
    Added success input
  • 5th February 2018 [ui_assets/elements/forms.yml]
    Updated form page docs
  • 4th February 2018 [ui_assets/elements/forms.yml]
    Updated form on register modal
  • 3rd February 2018 [ui_assets/elements/forms.yml]
    Updated form classes on doc page
  • 31st January 2018 [ui_assets/elements/forms.yml]
    Update form page & form elems on register modal
  • 29th January 2018 [ui_assets/elements/forms.yml]
    Update button classnames
  • 4th December 2017 [ui_assets/elements/forms.yml]
    Added missing for attribute to select labels
  • 4th December 2017 [ui_assets/elements/forms.yml]
    Fixed register page, tweaked select box label to be consistent with other inputs
  • 1st December 2017 [ui_assets/elements/forms.yml]
    Reorganised elements navigation
  • 1st December 2017 [ui_assets/elements/forms.yml]
    Restructured folder order.
  • 13th November 2017 [ui_assets/elements/forms.yml]
    Added paragraph twig filter and removed p tags from YAML
  • 26th October 2017 [ui_assets/elements/forms.yml]
    Removed rc- from form classes
  • 26th October 2017 [ui_assets/elements/forms.yml]
    Tidied forms page and fixed missing headers
  • 29th August 2017 [ui_assets/elements/forms.yml]
    Refactored naming convention used for levels of abstraction. https://trello.com/c/H5kTHTkZ/259-copy-change-update-naming-convention-on-sidebar
  • 25th August 2017 [ui_assets/elements/forms.yml]
    Added search input page. Improved inputs to conform to xhtml. Added shade page. Added footer sub-navigation page. Moved footer into navigation
  • 19th July 2017 [ui_assets/elements/forms.yml]
    Added associated files to page config for use with git info collection.
  • 15th July 2017 [ui_assets/elements/forms.yml]
    Git commit message sync improvements. Folder restructure.
  • 15th July 2017 [ui_assets/elements/forms.yml]
    Copy and markup improvements.
  • 11th July 2017 [ui_assets/elements/forms.yml]
    Added remaining content.