Font Face
Teva Sans Latin

Drafts & Templates
PBS Templates

Primitives & components context

Primitives & components: Teva SCS

Form

v0.0.0

Form elements styled according to Teva VIsion design.

Three variations are available:

  • The default, in primary color. (.vi-form without any modifiers)
  • Modifier .vi-form--accent displays fields in accent color.
  • Modifier .vi-form--outline displays select fields in outlined accent color.

On required fields the use of (required) is preferred over an asterisk *. When using an asterisk, always add a note like 'Required fields are marked *'

Detailed documentation about form validation can be found here.


Textual input elements #

<!-- Form  -->
<form action="#form-5521bc" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-77e220">Your Name
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-77e220" name="name-015bdc" placeholder="Your Name" required type="text">
  </div>
  <div class="form-group">
    <label for="control-22b0b6">Your Email Address
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-22b0b6" name="name-64c6d3" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Your Email Address" required type="email">
  </div>
  <div class="form-group">
    <label for="control-eb3d92">Your Website
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-describedby="help-4d14ed" aria-required="true" class="form-control" disabled id="control-eb3d92" name="name-05ced0" placeholder="Your Website" required type="url">
    <div id="help-4d14ed" class="vi-form__feedback vi-form__feedback--hint">This field is disabled</div>
  </div>
  <div class="form-group">
    <label for="control-ce052b">Your Message
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <textarea aria-required="true" class="form-control" id="control-ce052b" name="name-e318d4" placeholder="Your Message" required></textarea>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Send Message</button>
</form>

Using modifier .vi-form--accent.

<!-- Form (mods: --accent) -->
<form action="#form-20b72c" autocomplete="off" class="vi-form vi-form--accent vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-dc0a38">Your Name
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-dc0a38" name="name-280477" placeholder="Your Name" required type="text">
  </div>
  <div class="form-group">
    <label for="control-5c71b4">Your Email Address
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-5c71b4" name="name-6eb469" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Your Email Address" required type="email">
  </div>
  <div class="form-group">
    <label for="control-4d4ec1">Your Website
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-describedby="help-26c4a0" aria-required="true" class="form-control" disabled id="control-4d4ec1" name="name-b087d1" placeholder="Your Website" required type="url">
    <div id="help-26c4a0" class="vi-form__feedback vi-form__feedback--hint">This field is disabled</div>
  </div>
  <div class="form-group">
    <label for="control-5d3634">Your Message
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <textarea aria-required="true" class="form-control" id="control-5d3634" name="name-0a5c95" placeholder="Your Message" required></textarea>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-1 vi-btn">Send Message</button>
</form>

Using modifier .vi-form--inversed in combination with .vi-typesystem--inversed.

<!-- Form (mods: --inversed) -->
<form action="#form-364905" autocomplete="off" class="vi-form vi-form--inversed vi-typesystem vi-typesystem--inversed" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-c8a72c">Your Name
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-c8a72c" name="name-6669c6" placeholder="Your Name" required type="text">
  </div>
  <div class="form-group">
    <label for="control-26ac46">Your Email Address
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="control-26ac46" name="name-8204b2" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Your Email Address" required type="email">
  </div>
  <div class="form-group">
    <label for="control-a0e5b0">Your Website
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-describedby="help-54e1d9" aria-required="true" class="form-control" disabled id="control-a0e5b0" name="name-673405" placeholder="Your Website" required type="url">
    <div id="help-54e1d9" class="vi-form__feedback vi-form__feedback--hint">This field is disabled</div>
  </div>
  <div class="form-group">
    <label for="control-4729ee">Your Message
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <textarea aria-required="true" class="form-control" id="control-4729ee" name="name-3abec4" placeholder="Your Message" required></textarea>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-2 vi-btn">Send Message</button>
</form>

Sizing #

As per bootstrap documentation use .form-control-sm for small sized text input.

<!-- Form  -->
<form action="#form-b24775" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-ee4214">Your Name
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control-sm form-control" id="control-ee4214" name="name-bd5e25" placeholder="Your Name" required type="text">
  </div>
  <div class="form-group">
    <label for="control-e10462">Your Email Address
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control-sm form-control" id="control-e10462" name="name-95d955" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Your Email Address" required type="email">
  </div>
  <div class="form-group">
    <label for="control-1c5a41">Your Website
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control-sm form-control" id="control-1c5a41" name="name-86d607" placeholder="Your Website" required type="url">
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Send Message</button>
</form>

Checkboxes and radios #

<!-- Form  -->
<form action="#form-267e5c" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-bd9abb" name="name-c31a2a" required type="checkbox">
      <label class="custom-control-label" for="control-bd9abb">
        Cardigan wolf truffaut.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-5e854c" name="name-65bd04" required type="checkbox">
      <label class="custom-control-label" for="control-5e854c">
        Portland blog plaid.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-407ed8" name="name-ee4be0" required type="checkbox">
      <label class="custom-control-label" for="control-407ed8">
        Vice typewriter offal.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-29975e" name="name-2bd671" required type="checkbox">
      <label class="custom-control-label" for="control-29975e">
        Meggings disrupt letterpress.
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-switch custom-control">
      <input aria-required="true" class="custom-control-input" id="control-03d7b9" name="name-b797d0" required type="checkbox">
      <label class="custom-control-label" for="control-03d7b9">
        Chartreuse readymade mixtape.
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-66404d" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-66404d">
        Tofu cliche hella.
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-91c64c" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-91c64c">
        Tacos gluten-free iphone.
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-9e08d5" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-9e08d5">
        Gentrify kinfolk brooklyn.
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Knausgaard locavore</button>
</form>

Using modifier .vi-form--accent.

<!-- Form (mods: --accent) -->
<form action="#form-a7e71c" autocomplete="off" class="vi-form vi-form--accent vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-71e340" name="name-8adc1d" required type="checkbox">
      <label class="custom-control-label" for="control-71e340">
        Viral wolf quinoa.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-ca593c" name="name-7e6127" required type="checkbox">
      <label class="custom-control-label" for="control-ca593c">
        Lumbersexual ennui leggings.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-d024c3" name="name-a8cc9e" required type="checkbox">
      <label class="custom-control-label" for="control-d024c3">
        Asymmetrical tumblr cliche.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-80c9e6" name="name-4a7a4b" required type="checkbox">
      <label class="custom-control-label" for="control-80c9e6">
        Pour-over xoxo synth.
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-switch custom-control">
      <input aria-required="true" class="custom-control-input" id="control-97cbd9" name="name-483431" required type="checkbox">
      <label class="custom-control-label" for="control-97cbd9">
        Goth cornhole ethical.
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-93db08" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-93db08">
        Letterpress vice vhs.
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-234d99" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-234d99">
        Wolf freegan intelligentsia.
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-ea1226" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-ea1226">
        Loko everyday gastropub.
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-1 vi-btn">Occupy tilde</button>
</form>

Select fields #

<!-- Form  -->
<form action="#form-499414" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-302452">Sort order
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <select aria-required="true" class="custom-select" id="control-302452" name="name-ae15ab" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <label for="control-8dbac9">Results per page</label>
    <select class="custom-select" disabled id="control-8dbac9" name="name-603b31">
      <option disabled hidden="hidden" selected value="">20 results per page
      </option>
      <option value="10-results-per-page">10 results per page</option>
      <option value="20-results-per-page">20 results per page</option>
      <option value="30-results-per-page">30 results per page</option>
      <option value="40-results-per-page">40 results per page</option>
      <option value="50-results-per-page">50 results per page</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-sm custom-select" id="control-5e6535" name="name-7de3cd" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-lg custom-select" id="control-12b243" name="name-1b2340" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Submit your choices</button>
</form>

Using modifier .vi-form--accent.

<!-- Form (mods: --accent) -->
<form action="#form-193932" autocomplete="off" class="vi-form vi-form--accent vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-888e8c">Sort order
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <select aria-required="true" class="custom-select" id="control-888e8c" name="name-585117" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <label for="control-9b74cc">Results per page</label>
    <select class="custom-select" disabled id="control-9b74cc" name="name-e52a6e">
      <option disabled hidden="hidden" selected value="">20 results per page
      </option>
      <option value="10-results-per-page">10 results per page</option>
      <option value="20-results-per-page">20 results per page</option>
      <option value="30-results-per-page">30 results per page</option>
      <option value="40-results-per-page">40 results per page</option>
      <option value="50-results-per-page">50 results per page</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-sm custom-select" id="control-71dc5b" name="name-4da80d" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-lg custom-select" id="control-5b730d" name="name-e9cea0" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-1 vi-btn">Submit your choices</button>
</form>

Using modifier .vi-form--outline.

<!-- Form (mods: --outline) -->
<form action="#form-36548e" autocomplete="off" class="vi-form vi-form--outline vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-368c1e">Sort order
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <select aria-required="true" class="custom-select" id="control-368c1e" name="name-84ae4c" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <label for="control-8b0413">Results per page</label>
    <select class="custom-select" disabled id="control-8b0413" name="name-3468ac">
      <option disabled hidden="hidden" selected value="">20 results per page
      </option>
      <option value="10-results-per-page">10 results per page</option>
      <option value="20-results-per-page">20 results per page</option>
      <option value="30-results-per-page">30 results per page</option>
      <option value="40-results-per-page">40 results per page</option>
      <option value="50-results-per-page">50 results per page</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-sm custom-select" id="control-7a111a" name="name-b716ac" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <div class="form-group">
    <select aria-required="true" class="custom-select-lg custom-select" id="control-73b357" name="name-0c5d51" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-1 vi-btn">Submit your choices</button>
</form>

File browser #

To change the button text, use data-browse on the element with class .custom-file-label.

This file field also has attribute multiple for testing purposes.

<!-- Form  -->
<form action="#form-92b0a7" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <div class="custom-file">
      <input class="custom-file-input" id="control-216347" name="name-79c57d" type="file">
      <label class="custom-file-label" data-browse="Find files" for="control-216347">
        Please select a file
      </label>
    </div>
  </div>
  <p class="text-muted small mb-10">This file field also has attribute <code>multiple</code> for testing purposes.</p>
  <div class="form-group">
    <div class="custom-file">
      <input class="custom-file-input" id="control-87a8c8" multiple name="name-253e75" type="file">
      <label class="custom-file-label" for="control-87a8c8">
        Please select multiple files
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Schlitz humblebrag</button>
</form>

Using modifier .vi-form--accent.

Note the data-msg-success message to set the success message.

This file field also has attribute multiple for testing purposes.

<!-- Form (mods: --accent) -->
<form action="#form-43007d" autocomplete="off" class="vi-form vi-form--accent vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <div class="custom-file">
      <input class="custom-file-input" data-msg-success="%files% choosen" id="control-494ab9" name="name-27e6e6" type="file">
      <label class="custom-file-label" data-browse="Find files" for="control-494ab9">
        Please select a file
      </label>
    </div>
  </div>
  <p class="text-muted small mb-10">This file field also has attribute <code>multiple</code> for testing purposes.</p>
  <div class="form-group">
    <div class="custom-file">
      <input class="custom-file-input" data-msg-success="%files% choosen" id="control-7c2b22" multiple name="name-38c3c5" type="file">
      <label class="custom-file-label" for="control-7c2b22">
        Please select multiple files
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Actually chambray</button>
</form>

Miscellaneous #

Example of checkbox with really long label text.

To align the control to the top use modifier ...--top on .custom-control

<!-- Form  -->
<form action="#to-the-server" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" id="sg-d44028" novalidate>
  <div class="form-group" id="sg-461900">
    <div class="custom-checkbox custom-control custom-control--top">
      <input class="custom-control-input" id="control-b7dc2b" name="name-035560" type="checkbox">
      <label class="custom-control-label" for="control-b7dc2b">
        You probably haven't heard of them ramps portland. Roof kale chips pitchfork. Chambray five dollar toast ramps williamsburg shabby chic fashion axe. Williamsburg meggings lo-fi try-hard distillery portland thundercats. Gastropub marfa kombucha blue bottle crucifix freegan yr godard. Celiac bushwick typewriter godard brooklyn salvia. Letterpress park lomo cold-pressed crucifix normcore. Ramps asymmetrical you probably haven't heard of them. Park plaid shoreditch selfies craft beer phlogiston. Narwhal mixtape tote bag. Letterpress next level vhs. Pbr&amp;b umami pitchfork schlitz put a bird on it.
        Don't you agree?
      </label>
    </div>
  </div>
  <div class="form-group" id="sg-461900">
    <div class="custom-switch custom-control custom-control--top">
      <input class="custom-control-input" id="control-8ead67" name="name-40581a" type="checkbox">
      <label class="custom-control-label" for="control-8ead67">
        Health 90's meh readymade. Farm-to-table xoxo try-hard sriracha craft beer dreamcatcher pour-over vhs. Freegan thundercats helvetica tilde park. Loko irony iphone paleo chia park retro. Gastropub cronut polaroid artisan. Phlogiston ennui typewriter gluten-free meditation health disrupt 90's. Squid artisan hashtag freegan lumbersexual cronut. Small batch pop-up 90's fingerstache yr. Cardigan master wayfarers marfa cornhole. Tote bag slow-carb letterpress waistcoat venmo. Typewriter 90's mlkshk everyday pug echo forage migas. Wes anderson locavore iphone.
        Don't you agree?
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Flexitarian phlogiston</button>
</form>

The example shows:

  • rich text in description for checkbox and radiobuttons.
  • links in labels (although an UX anti-pattern)

Are you sure? Tilde kombucha vegan actually tote bag. Portland fingerstache fashion axe cardigan. Small batch twee mustache.

Do you agree? Cornhole you probably haven't heard of them chillwave waistcoat +1 loko cardigan. Post-ironic sustainable drinking messenger bag health. Flexitarian literally pickled roof. Ennui microdosing crucifix scenester green juice. Semiotics brooklyn hashtag disrupt +1 everyday.

<!-- Form  -->
<form action="#form-7ed1b4" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group" role="group" aria-labelledby="label-56ba60">
    <div class="mb-10 vi-form__text vi-form__text--label vi-typesystem vi-typesystem--collapse-last" id="label-56ba60">
      <p>Are you sure? Tilde kombucha vegan actually tote bag. Portland fingerstache fashion axe cardigan. Small batch twee mustache.</p>
      <span aria-hidden="true" class="vi-form__required">(required)</span>
    </div>
    <div class="custom-checkbox custom-control">
      <input aria-describedby="help-3a6101" aria-required="true" class="custom-control-input" id="control-269e3d" name="name-1e8d48" required type="checkbox">
      <label class="custom-control-label" for="control-269e3d">
        I agree with the
        <a href="#sample">terms</a>
      </label>
    </div>
    <div id="help-3a6101" class="vi-form__feedback vi-form__feedback--hint">This is optional help text for the field above.</div>
    <div class="custom-switch custom-control">
      <input aria-describedby="help-37deeb" aria-required="true" class="custom-control-input" id="control-a84197" name="name-c06209" required type="checkbox">
      <label class="custom-control-label" for="control-a84197">
        I agree with the
        <a href="#sample">terms</a>
      </label>
    </div>
    <div id="help-37deeb" class="vi-form__feedback vi-form__feedback--hint">This is optional help text for the field above.</div>
  </div>
  <div class="form-group" role="group" aria-labelledby="label-c42818" aria-describedby="help-1c16d1">
    <div class="mb-10 vi-form__text vi-form__text--label vi-typesystem vi-typesystem--collapse-last" id="label-c42818">
      <p>Do you agree? Cornhole you probably haven't heard of them chillwave waistcoat +1 loko cardigan. Post-ironic sustainable drinking messenger bag health. Flexitarian literally pickled roof. Ennui microdosing crucifix scenester green juice. Semiotics brooklyn hashtag disrupt +1 everyday.</p>
      <span aria-hidden="true" class="vi-form__required">(required)</span>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-e19daa" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-e19daa">
        I agree with the
        <a href="#sample">terms</a>
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-aa86b5" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-aa86b5">
        I agree with the
        <a href="#sample">terms</a>
      </label>
    </div>
    <div class="custom-radio custom-control">
      <input aria-required="true" class="custom-control-input" id="control-40c0e3" name="name-b3e502" required type="radio">
      <label class="custom-control-label" for="control-40c0e3">
        I agree with the
        <a href="#sample">terms</a>
      </label>
    </div>
    <div id="help-1c16d1" class="vi-form__feedback vi-form__feedback--hint">You have to agree with something.</div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Thundercats tacos</button>
</form>

The example shows:

  • A checkbox with label, followed by a paragraph that contains a link.

This is the paragraph near the checkbox. The paragraph contains a Hyperlink, as you can see.

<!-- Form  -->
<form action="#form-ed795d" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group" role="group" aria-labelledby="label-1ca4e3">
    <div class="custom-checkbox custom-control">
      <input aria-required="true" class="custom-control-input" id="control-d4ee53" name="name-17bd4a" required type="checkbox">
      <label class="custom-control-label" for="control-d4ee53">
        This is the label of the checkbox
      </label>
    </div>
    <div class="mb-10 vi-form__text vi-form__text--label vi-typesystem vi-typesystem--collapse-last" id="label-1ca4e3">
      <p>
        This is the paragraph near the checkbox. The paragraph contains a
        <a href="#">Hyperlink</a>,
        as you can see.
      </p>
      <span aria-hidden="true" class="vi-form__required">(required)</span>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Letterpress banjo</button>
</form>

Example of checkboxes with one error message at the bottom of all checkboxes.

<!-- Form  -->
<form action="#to-the-server" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" id="sg-143452" novalidate>
  <div class="form-group" id="sg-b8196a">
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-ae0253" name="name-23791d" type="checkbox">
      <label class="custom-control-label" for="control-ae0253">
        Loko freegan drinking.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-54a53e" name="name-c1983d" type="checkbox">
      <label class="custom-control-label" for="control-54a53e">
        Bushwick asymmetrical salvia.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-1cdbb0" name="name-1eb40b" type="checkbox">
      <label class="custom-control-label" for="control-1cdbb0">
        Farm-to-table kitsch asymmetrical.
      </label>
    </div>
    <div class="custom-checkbox custom-control" id="sg-e60e89">
      <input class="custom-control-input" id="control-91002e" name="name-9e3562" type="checkbox">
      <label class="custom-control-label" for="control-91002e">
        Normcore semiotics tacos.
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Lumbersexual cleanse</button>
</form>

Example of search filter checkboxes.

<!-- Form (mods: --accent) -->
<form action="#form-31886e" autocomplete="off" class="vi-form vi-form--accent vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-87b15b" name="name-7051e7" type="checkbox">
      <label class="custom-control-label" for="control-87b15b">
        Disrupt cleanse yr.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-33984c" name="name-77a1bd" type="checkbox">
      <label class="custom-control-label" for="control-33984c">
        Tilde vinyl farm-to-table.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-178b7a" name="name-11ebb4" type="checkbox">
      <label class="custom-control-label" for="control-178b7a">
        Twee gastropub 90's.
      </label>
    </div>
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" id="control-00a715" name="name-1e62c1" type="checkbox">
      <label class="custom-control-label" for="control-00a715">
        Semiotics slow-carb aesthetic.
      </label>
    </div>
  </div>
</form>

Example of newsletter subscription form.

<!-- Form  -->
<form action="#form-be52d5" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="mb-30 form-group">
    <label class="sr-only" for="control-82e88e">Your Email Address</label>
    <input aria-required="true" class="form-control" data-msg-success="Looks like an email address." data-msg="Please provide a valid email address." id="control-82e88e" name="name-e8ae30" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Your Email Address" required type="email">
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-2 vi-btn">Subscribe</button>
</form>

Example of HCP Filter.

<!-- Form (mods: --outline) -->
<form action="#form-b95b04" autocomplete="off" class="vi-form vi-form--outline vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label class="vi-type vi-type--text-big" for="control-6ee663">I am a</label>
    <div class="form-row">
      <div class="col-auto col-md-7 col-lg-5">
        <select aria-required="true" class="custom-select" id="control-6ee663" name="name-e8e43e" required>
          <option disabled hidden="hidden" selected value="">Select
          </option>
          <option value="pharmacist">pharmacist</option>
          <option value="pharmacy-technician">pharmacy technician</option>
          <option value="physician">physician</option>
        </select>
      </div>
    </div>
  </div>
  <div class="form-group">
    <label class="vi-type vi-type--text-big" for="control-5dc348">looking for</label>
    <div class="form-row">
      <div class="col-auto col-md-7 col-lg-5">
        <select aria-required="true" class="custom-select" id="control-5dc348" name="name-63d6ce" required>
          <option disabled hidden="hidden" selected value="">Select
          </option>
          <option value="professional-support">professional support</option>
          <option value="pharmacy-tools-and-resources">pharmacy tools and resources</option>
          <option value="continuing-education">continuing education</option>
          <option value="resources-for-patients-and-caregivers">resources for patients and caregivers</option>
          <option value="information-about-generic-medicines">information about generic medicines</option>
        </select>
      </div>
    </div>
  </div>
  <div class="mt-20">
    <!-- Button type: solid  -->
    <button type="submit" class="vi-btn-solid vi-btn-solid--accent-2 vi-btn-solid--lg vi-btn">Go</button>
  </div>
</form>

Select Field with Label and Required text.

<!-- Form  -->
<form action="#form-492291" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-43e2c5">Sort order
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <select aria-required="true" class="custom-select" id="control-43e2c5" name="name-415901" required>
      <option disabled hidden="hidden" selected value="">Sort order
      </option>
      <option value="asc">Asc</option>
      <option value="desc">Desc</option>
    </select>
  </div>
</form>

Example login form. This form uses the grid.

I forgot my password

<!-- Form  -->
<form action="#form-c2ac96" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="mb-30">
    <div class="form-group">
      <label for="control-14d1d0">Email</label>
      <input aria-required="true" class="form-control" data-msg="Please provide a valid email address." id="control-14d1d0" name="name-715cdd" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" placeholder="Email" required type="email">
    </div>
    <div class="form-group">
      <label for="control-6e5c8b">Password</label>
      <input aria-required="true" class="form-control" id="control-6e5c8b" name="name-768ad6" placeholder="Password" required type="password">
    </div>
    <p class="mt-10">
      <a href="#sg-e3cbd9">I forgot my password</a>
    </p>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn-solid--accent-1 vi-btn">Log in</button>
</form>

Disabled #

Example login form. This form uses the grid.

<!-- Form  -->
<form action="#form-90c7d5" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="control-95aa69">Disabled text field</label>
    <input class="form-control" disabled id="control-95aa69" name="name-728ce2" placeholder="Disabled text field" type="text">
  </div>
  <div class="form-group">
    <label for="control-304325">Disabled text area</label>
    <textarea class="form-control" disabled id="control-304325" name="name-4db5a5" placeholder="Disabled text area"></textarea>
  </div>
  <div class="form-group">
    <div class="custom-checkbox custom-control">
      <input class="custom-control-input" disabled id="control-455d99" name="name-729b91" type="checkbox">
      <label class="custom-control-label" for="control-455d99">
        Disabled checkbox
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-switch custom-control">
      <input class="custom-control-input" disabled id="control-a666d4" name="name-39c06b" type="checkbox">
      <label class="custom-control-label" for="control-a666d4">
        Disabled checkbox (switch)
      </label>
    </div>
  </div>
  <div class="form-group">
    <div class="custom-radio custom-control">
      <input class="custom-control-input" disabled id="control-8687e5" name="name-35e3be" type="radio">
      <label class="custom-control-label" for="control-8687e5">
        Disabled radio button
      </label>
    </div>
  </div>
  <div class="form-group">
    <select class="custom-select" disabled id="control-a21381" name="name-d83833">
      <option disabled hidden="hidden" selected value="">Disabled select field
      </option>
      <option value="nope">nope</option>
    </select>
  </div>
  <div class="form-group">
    <div class="custom-file">
      <input class="custom-file-input" disabled id="control-5cc919" name="name-9e4111" type="file">
      <label class="custom-file-label" for="control-5cc919">
        Please select a file
      </label>
    </div>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" disabled class="vi-btn-solid vi-btn">Disabled button</button>
</form>

Data List #

Native autocomplete with datalist element. The list attribute of the input element points to the id of the datalist.

To only allow entries from the datalist, custom validations can be used.

<!-- Form  -->
<form action="#form-c0c261" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
  <div class="form-group">
    <label for="sg-02dbaa">Country
      <span aria-hidden="true" class="vi-form__required">(required)</span></label>
    <input aria-required="true" class="form-control" id="sg-02dbaa" list="countries" name="name-0693ea" placeholder="Country" required type="text">
    <datalist id="countries">
      <option>Russia</option>
      <option>Germany</option>
      <option>United Kingdom</option>
      <option>France</option>
      <option>Italy</option>
      <option>Spain</option>
      <option>Ukraine</option>
      <option>Poland</option>
      <option>Romania</option>
      <option>Netherlands</option>
      <option>Belgium</option>
      <option>Czech Republic</option>
      <option>Greece</option>
      <option>Portugal</option>
      <option>Sweden</option>
      <option>Hungary</option>
      <option>Belarus</option>
      <option>Austria</option>
      <option>Serbia</option>
      <option>Switzerland</option>
      <option>Bulgaria</option>
      <option>Denmark</option>
      <option>Finland</option>
      <option>Slovakia</option>
      <option>Norway</option>
      <option>Ireland</option>
      <option>Croatia</option>
      <option>Moldova</option>
      <option>Bosnia and Herzegovina</option>
      <option>Albania</option>
      <option>Lithuania</option>
      <option>North Macedonia</option>
      <option>Slovenia</option>
      <option>Latvia</option>
      <option>Estonia</option>
      <option>Montenegro</option>
      <option>Luxembourg</option>
      <option>Malta</option>
      <option>Iceland</option>
      <option>Andorra</option>
      <option>Monaco</option>
      <option>Liechtenstein</option>
      <option>San Marino</option>
      <option>Holy See</option>
    </datalist>
  </div>
  <!-- Button type: solid  -->
  <button type="submit" class="vi-btn-solid vi-btn">Scenester biodiesel</button>
</form>

Stylesheets #

The following stylesheets are required to display this component.

The following additional stylesheet is used to display the example(s).


JavaScript #

The following javascript is required to display this component.


Usage documentation #

Usage documentation can be found here.


Changelog #

Changelog

Fix

  • 19 Feb 2025 - fix(form): resolve mutation observer recursion issue in Safari
  • 13 Feb 2025 - feat(form): fix form reset validation messages
  • 11 Sep 2024 - Fix broken label issue (webkit only!)
  • 01 Jun 2023 - Fix read-only styling to input, select and textarea. Fixes placeholder combobox.
  • 23 May 2023 - Removed a11y default success message; Business requirement.
  • 28 Apr 2023 - Fix safaris hard disable color override.
  • 15 Feb 2023 - Combobox validation
  • 18 Jan 2023 - Fix background-clip setting.
  • 28 June 2022 - Fix scrollparent detector
  • Make Safari (the new IE6) understand how parenthesis work when direction is rtl.
  • Remove previous work around.
  • Try to work around chrome mobile bug (1197882) where long datalists overlap keyboard.
  • Fix chrome bug (674447, 849616) where datalist gets detached by scrolling.
  • Wrapping of lang filenames in file field.
  • PBS support: fix box-shadow on custom-control
  • Regression: accent colors not picked up by sass.
  • Allow re-enabled fields to validate.
  • Remove file field blur validation.
  • A11y: …show hidden span tag with this value”name of the file + “selected” add role=”alert”
  • A11y: Redundantly add attribute aria-required=true to elements with attribute required
  • A11y: …add a hidden span tag with this value”name of the file + “uploaded” add role=”alert”
  • Form Validation message not showing, when element hidden.
  • IE11 premature error throwing.
  • Better align custom indicators regardless font / line-height used.
  • Remove background color IE11 from focused select.

Changed

  • 09 Jan 2025 - feat(multiple-select): Show options with empty value.
  • 30 Jun 2023 - Disabled state of checkbox/radio and switch.

Added

  • 28 Aug 2024 - Add dynamic form fields example + added $.fn.viFormDynamicFieldsContainer() to assign to a dynamic fields container and keep validation in sync.
  • 17 May 2023 - Form reset removes validation messages.
  • 15 Mar 2023 - Allow browse button text to be changed.
  • 15 Feb 2023 - Combobox reset
  • 2 Dec 2022 - Add size sm size to text-fields.
  • 14 Nov 2022 - Add data attribute data-keyup to allow for keyup validation on a field. (required by wizard#contextual-fields)
  • Add an example of a paragraph
  • An example of labels on select fields.
  • PBS support
  • Examples of contextual form fields.
  • Add --top modifier to .custom-control for long labels.
  • A11y: File field focus outline same as links.
  • On submit focus on first invalid element
  • Missing File Browser field
  • RTL support
  • Documentation
  • Changed checkbox outline according new design input.
  • Initial draft