OOOOPS. Your browser seems to be too old for this. Please update your browser.
Teutonic CSS
Use it

Styled HTML5 form elements

Forms are a corner stone of any interactive web application. Here is a consitent yet familar look across Operating Systems and browsers while respecting standards.

The aim here is not pixel-perfection. It’s about dealing with standard elements with as little intervention, extra markup and classes as possible. Teutonic CSS does not apply the form styles directly, instead all elements are styled with a class named like the element itself: select.select,textarea.textarea

On this page

Input

Here are all the different textish input elements. Browser support and styling varies, but that’s ok.

This example also shows how to align labels to the input fields using Flexbox with a breakpoint on tablet size.

Syntax: input.input
SCSS: _forms.scss
<div class="read_l">
  <div class="flex wrap-no gap-no collapse-t">
  <label for="e-text" class="span-third span-full-t text-clip box">Text</label>
  <input class="input" type="text" id="e-text" placeholder="Just text">
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-fav-fruit" class="span-third span-full-t text-clip box">Text with datalist</label>
    <input class="input" type="text" list="fruits" id="e-fav-fruit" placeholder="data-list example">
    <datalist id="fruits">
      <option value="Apple">
      <option value="Orange">
      <option value="Peach">
      <option value="Melon">
      <option value="Strawberry">
    </datalist>
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-text-readonly" class="span-third span-full-t text-clip box">Text:readonly</label>
  <input class="input" type="text" id="e-text-readonly" value="Only to read." readonly>
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-text-disabled" class="span-third span-full-t text-clip box">Text:disabled</label>
  <input class="input" type="text" id="e-text-disabled" value="Disabled." disabled>
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-password" class="span-third span-full-t text-clip box">Password</label>
  <input class="input" type="password" id="e-password" placeholder="•••••••••••">
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-email" class="required span-third span-full-t text-clip box">Email</label>
  <input class="input" type="email" id="e-email" name="email" required>
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-number" class="span-third span-full-t text-clip box">Number</label>
  <input class="input" type="number" name="number" id="e-number" value="42">
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-tel" class="span-third span-full-t text-clip box">Tel</label>
  <input class="input" type="tel" name="tel" id="e-tel">
</div>
<div class="flex wrap-no gap-no collapse-t">
  <label for="e-url" class="span-third span-full-t text-clip box">URL</label>
  <input class="input" type="url" name="url" id="e-url" placeholder="https://www.fortrabbit.com">
</div>
</div>

Invalid input

HTML form data validation is a simple and cheap way to validate user input on entering. An :invalid text is redish. Below, an e-mail address is expected.

SCSS: _forms.scss
<input class="input read_m" type="email" required value="invalid email">

Select

A simple select box.

Syntax: select.select
SCSS: _select.scss
<select class="select read_m">
  <option value="choclate">Chocolate</option>
  <option value="lollipop">Lollipop</option>
  <option value="bubble-gum">Bubble gum</option>
</select>

Radio

Streamlined radio elements in a familar but unified look.

Syntax: input[type=radio].radio
SCSS: _radio-checkbox.scss

Warrenty

<div class="read_m">
  <h4 class="bo-b_xs pa-b_xs">
    Warrenty
  </h4>
  <div class="grid-auto gap-no">
    <label class="box">
      <input class="radio" type="radio" name="insurance" checked>
      1 year
    </label>
    <label class="box">
      <input class="radio" type="radio" name="insurance">
      2 years
    </label>
    <label class="box">
      <input class="radio" type="radio" name="insurance">
      3 years
    </label>
  </div>
</div>

Checkbox

Streamlined checkboxes in a familar but unified look.

Syntax: checkbox.checkbox
SCSS: _radio-checkbox.scss

Equipment

<div class="read_m">
  <h4 class="pa-b_xs bo-b_xs">
    Equipment
  </h4>
  <div class="flex gap-no collapse-p">
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="bluetooth"> Bluetooth
    </label>
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="aircon" checked> Air con
    </label>
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="turbo-boost" checked> Turbo boost
    </label>
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="cd-player"> CD player
    </label>
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="ejection-seat"> Ejection seat
    </label>
    <label class="span-half box">
      <input class="checkbox" type="checkbox" name="afterburner"> Afterburner
    </label>
  </div>
  <div class="text_s ma-t_s">
    <input class="checkbox" type="checkbox" id="choice" name="choice">
    <label for="choice">Remember my choice</label>
  </div>
</div>

Date

This is just a date input. Your browser might or might not help you filling it out.

Height of this element does not align with other inputs in WebKit.

Syntax: input[type=date].input
SCSS: _forms.scss
<input class="input read_m" type="date">

Time

This is just a time input. Your browser might or might not help you filling it out.

Height of this element does not align with other inputs in WebKit.

Syntax: input[type=time].input
SCSS: _forms.scss
<input class="input read_m" type="time">

Here is some love for the search input. The basic search is resetted to match other text inputs, but still features the cancel button in WebKit. You can also wrap the search in a .search-box container. Have a look at the search form over here.

Syntax: input[type="search"].input
SCSS: _input-search.scss
<div class="read_l">
  <h4 class="text_m ma-b_xs">Plain search <span class="text-normal">is styled like text input mostly</span></h4>
  <input type="search" class="input" placeholder="Search">
  <h4 class="text_m ma-b_xs ma-t_l text-clip">
    Wrapped in a .search-box <span class="text-normal">comes with a magnifier icon</span>
  </h4>
  <div class="search-box">
    <input type="search" class="input" placeholder="Search">
  </div>
  <h4 class="text_m ma-b_xs ma-t_s text-normal">… and with bigger text</h4>
  <div class="search-box">
    <input type="search" class="input text_xl" placeholder="Search">
  </div>
  <h4 class="text_m ma-b_xs ma-t_s text-normal">… and with some more padding</h4>
  <div class="search-box">
    <input type="search" class="input pa_m" placeholder="Search">
  </div>
  <h4 class="text_m ma-b_xs ma-t_s text-normal">… and with less padding</h4>
  <div class="search-box">
    <input type="search" class="input pa_xs" placeholder="Search">
  </div>
  <h4 class="text_m ma-b_xs ma-t_s text-normal">… and with the magnifier icon on the right side</h4>
  <div class="search-box right">
    <input type="search" class="input" placeholder="Search">
  </div>
  <h4 class="text_m ma-b_xs ma-t_s text-normal">… and with rounded corners</h4>
  <div class="search-box">
    <input type="search" class="input ra-pill" placeholder="Search">
  </div>
</div>

Textarea

Note that you can resize the textarea only vertically.

Syntax: textarea.textarea
SCSS: _forms.scss
<textarea class="textarea read_m" rows="3" placeholder="To whom it may concern …"></textarea>

File

Here is some basic styling for a file upload field. Apply the two classes: .input and .file to the HTML element to achieve alignment with other form elements.

This looks best in WebKit/Blink but degrades gracefully under other browsers.

Syntax: input[type=file].input.file
SCSS: _input-file.scss _forms.scss

Only file class

With input and file class

<div class="read_l">
  <h4 class="ma-b_xs">
    Only file class
  </h4>
  <input type="file" name="file" id="file" class="file">
  <h4 class="ma-b_xs ma-t_m">
    With input and file class
  </h4>
  <input type="file" name="file" id="file" class="file input">
</div>

Range

A range input is a (horizontal) slider. It lets a user specify a value within a range.

Wrap the range input in a .range-box container to better deal with size in more complex forms. Datalists for are currently not supported. There are some issues in MS Edge with this.

Syntax: input[type=range].range
SCSS: _input-range.scss

Stand alone

Wrapped in a .range-box

A mini form

0
<div class="read_l">
  <h4 class="pa-b_xs ma-b_xs">
    Stand alone
  </h4>
  <input type="range" class="range">
  <h4 class="ma-b_xs ma-t_m">
    Wrapped in a .range-box
  </h4>
  <div class="range-box">
    <input type="range" name="range" id="range-example-2" class="range" min="0" max="10" value="4" step="2">
  </div>
  <h4 class="ma-b_xs ma-t_m">
    A mini form
  </h4>
  <form class="flex gap-no" onsubmit="return false" oninput="level.value = slevel.valueAsNumber">
    <label class="box pa_m" for="skill">Skill level</label>
    <div class="range-box pa_m">
      <input name="slevel" id="skill" type="range" class="range" min="0" max="100" value="0"> 
      <output for="skill" name="level" class="mini-info">0</output>
    </div>
  </form>
</div>

Progress

The progress element represents the completion progress of a task. Use this for loading bars, form completion states, order status indicators … Don’t confound it with it’s bigger brother, the meter.

The progress comes with two states. When indeterminate, it shows a spinning animation when it is waiting to receive a value. When determinate, it shows a completion bar when value and max parameters are set. This is looking a little different in MS Edge, but still OK.

Syntax: progress.progress
SCSS: _progress.scss

Standalone

Wrapped in a .progress-box with content

Waiting for signal
50% loaded

Wrapped with custom padding and font size

90% done

Wrapped custom colors, no content

<div class="read_l">
  <h4 class="text-clip">Standalone</h4>
  <progress class="progress ma-t_xs"></progress>
  <progress class="progress ma-t_xs" value="30" max="100"></progress>

  <h4 class="text-clip ma-t_m">
    Wrapped in a .progress-box with content
  </h4>
  <div class="progress-box ma-t_xs">
    <div>Waiting for signal</div>
    <progress class="progress"></progress>
  </div>
  <div class="progress-box ma-t_xs">
    <div><output class="text-bold">50%</output> loaded</div>
    <progress max="10" value="5" class="progress"></progress>
  </div>
  <h4 class="text-clip ma-t_m">
    Wrapped with custom padding and font size
  </h4>
  <div class="progress-box ma-t_xs text_xl pa_m">
    <div><output class="text-bold">90%</output> done</div>
    <progress max="10" value="9" class="progress"></progress>
  </div>
  <h4 class="text-clip ma-t_m">
    Wrapped custom colors, no content
  </h4>
  <div class="progress-box ma-t_xs">
    <progress class="progress custom"></progress>
  </div>
  <div class="progress-box ma-t_xs">
    <progress max="10" value="8" class="progress custom"></progress>
  </div>
</div>

Meter

The meter element - similar to it’s little brother progress - looks like horizontal graph element. But the meter has a colored bar chart, which indicates if the value is too low, too high or just right. Use this for disk usage, the relevance of a query result …

It doesn’t have an indeterminate state. The HTML element has a lot of attributes: min, max, low, high, optimum and value. Wrap it in box for best alignment with other form elements within Teutonic CSS. Browser support for a styled meter element is a bit sloppy. This looks kind of OK in MS Edge.

SCSS: _meter.scss

Standalone

Wrapped in a .meter-box

Wrapped in a .meter-box with content

5
50
91
110
<div class="read_l">
  <h4 class="ma-t_m">
    Standalone
  </h4>
  <meter class="meter ma-t_xs" value="5"   min="0" low="10" optimum="50" high="90" max="100"></meter>
  <meter class="meter ma-t_xs" value="50"  min="0" low="10" optimum="50" high="90" max="100"></meter>
  <meter class="meter ma-t_xs" value="95"  min="0" low="10" optimum="50" high="90" max="100"></meter>
  <meter class="meter ma-t_xs" low=".25" optimum=".2" high=".75" value=".8"></meter>
  <h4 class="ma-t_m">
    Wrapped in a .meter-box
  </h4>
  <div class="meter-box ma-t_xs">
    <meter class="meter" value="5" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <meter class="meter" value="50" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <meter class="meter" value="91" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <meter class="meter" value="110" min="0" low="10" optimum="5" high="90" max="100"></meter>
  </div>
  <h4 class="ma-t_m">
    Wrapped in a .meter-box with content
  </h4>
  <div class="meter-box ma-t_xs">
    <div>5</div>
    <meter class="meter" value="5" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <div>50</div>
    <meter class="meter" value="50" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <div>91</div>
    <meter class="meter" value="91" min="0" low="10" optimum="50" high="90" max="100"></meter>
  </div>
  <div class="meter-box ma-t_xs">
    <div>110</div>
    <meter class="meter" value="110" min="0" low="10" optimum="5" high="90" max="100"></meter>
  </div>
</div>

Color

Here is a color picker. Wrap in a box so that it aligns with other form elements.

Note that the label does not interfere with the underlying color picker. This is because the text is a label that points to the input below, additionally the label has the text-point-no class which omits the pointer events. The pseudo-placeholder text effect is done with mix-blend-mode in an inline style. This looks OKish in MS Edge.

Syntax: input[type=color].color
SCSS: _input-color.scss

Stand alone

Wrapped in a .color-box

Wrapped in a .color-box with label

<div class="read_l">
  <h4 class="ma-b_xs">
    Stand alone
  </h4>
  <input type="color" class="color" value="#ff9999">
  <h4 class="ma-b_xs ma-t_m">
    Wrapped in a .color-box
  </h4>
  <div class="color-box">
    <input id="docs-color-picker" type="color" class="color" value="#ffdddd">
  </div>
  <h4 class="ma-b_xs ma-t_m">
    Wrapped in a .color-box with label
  </h4>
  <div class="color-box">
    <label for="docs-color-picker" class="text-point-no docs-color-label">Click to choose a color</label>
    <input id="docs-color-picker" type="color" class="color" value="#ffdddd">
  </div>
</div>

<style>
  .docs-color-label { 
    color: #333;
    mix-blend-mode: difference;
  }
</style>

Form box

This wrapper element combines a “label” with some form element and possibly other helpers. Most commonly used with .input, .textarea or .select. By default, the padding is small. Add the .pa_m class for a some padding.

You can also combine it with a .search-box — pushing the magnifier glass will to the right — but it will not work in combonation with .range-box, .meter-box or .progress-box.

Syntax: .form-box
SCSS: _form-box.scss

Standard

Give sense here

With extra padding

Please provide some sense here
<div class="read_l">
  <div class="gap_xs">
    <h4>Standard</h4>
    <div class="form-box">
      <label class="mini-label required">Text input</label>
      <input type="text" class="input">
      <div class="mini-info">Give sense here</div>
    </div>
    <div class="form-box">
      <label class="mini-label">Select</label>
      <select class="select">
        <option value="">Please select</option>
        <optgroup label="Favorite CSS preprocessor">
          <option>SASS</option>
          <option>LESS</option>
          <option>Stylus</option>
          <option>Post CSS</option>
        </optgroup>
      </select>
    </div>
    <div class="form-box search-box">
      <label class="mini-label">Search</label>
      <input type="search" class="input">
    </div>
    <div class="form-box">
      <label class="mini-label">Textarea</label>
      <textarea class="textarea" name="form-box-message" id="form-box-message" rows="3"></textarea>
    </div>
  </div>
  <div class="gap_xs ma-t_m">
    <h4>With extra padding</h4>
    <div class="form-box pa_m">
      <label class="mini-label required">Text input</label>
      <input type="text" class="input pa-l_s">
      <div class="mini-info">Please provide some sense here</div>
    </div>
    <div class="form-box pa_m">
      <label class="mini-label">Select</label>
      <select class="select" name="" id="">
        <option value="">Please select</option>
        <optgroup label="Favorite CSS preprocessor">
          <option>SASS</option>
          <option>LESS</option>
          <option>Stylus</option>
          <option>Post CSS</option>
        </optgroup>
      </select>
    </div>
    <div class="form-box search-box pa_m">
      <label class="mini-label">Search</label>
      <input type="search" class="input">
    </div>
    <div class="form-box pa_m">
      <label class="mini-label">Textarea</label>
      <textarea class="textarea" name="form-box-message" id="form-box-message" rows="3"></textarea>
    </div>
  </div>
</div>

Disabled

When things are “OFF”. Some elemnts have a disabled attribute, on others you can add a .disabled class.

div.box.disabled
a.box.disabled
.box.disabled + .color:disabled
a.button.disabled a.button.prime.disabled
<div class="flex gap-no read_l">
  <div class="box disabled">div.box.disabled</div>
  <a href="#" class="box disabled">a.box.disabled</a>
</div>
<div class="gap-no read_l ma-t_s">
  <textarea class="textarea" disabled>textarea.textarea:disabled</textarea>
  <input class="input" type="text" disabled value="disabled input">
  <div class="range-box disabled">
    <input type="range" class="range" disabled>
  </div>
  <div class="color-box disabled">
    <div>.box.disabled + .color:disabled</div>
    <input type="color" class="color" disabled>
  </div>
  <input class="input" type="text" disabled value="input.input:disabled">
  <select class="select" disabled>
    <option value="disabled">select.select:disabled</option>
  </select>
  <label class="box disabled">
    <input class="radio m-r-s" type="radio" disabled>
    radio:disabled + label.box.disabled 
  </label>
  <label class="box disabled">
    <input class="checkbox m-r-s" type="checkbox" disabled>
    checkbox:disabled + label.box.disabled
  </label>
  <label class="form-box disabled">
    <div class="mini-label">.form-box.disabled</div>
    <input class="input" type="email" disabled>
    <div class="mini-info shown">mini-info</div>
  </label>
</div>
<div class="grid gap_xs read_l ma-t_s">
  <a href="#" class="span-6 button disabled">a.button.disabled</a>
  <button class="span-6 button disabled">button.button:disabled</button>
  <a href="#" class="span-6 button prime disabled">a.button.prime.disabled</a>
  <button class="span-6 button prime disabled">button.button.prime:disabled</button>
</div>