Forms
Contents:
Missing.css aims to style HTML nicely without authors needing to concern themselves over anything other than using HTML tags with correct meanings, but this is not always feasible. Forms are a particularly complex part of HTML, with multiple ways to mark up the same semantics. For instance, you can label an element in multiple ways:
<form>
<label>Name <input></label>
<!-- or... -->
<label for=adr>Address</label> <input id=adr>
</form>
Because of this, it's not really possible to write a stylesheet that will work with any HTML form.
Missing.css will work best on forms that follow these markup conventions:
§ Inputs and labels
Inputs inside labels will be display:inline.
Inputs outside labels will be display:block.
Input placeholders are styled with text-align:end to better distinguish them from actual input.
<form class="flex-switch">
<div>
<label for=category>Category:</label>
<select id=category placeholder="Select a category...">
<option>Blues
<!-- ... -->
</select>
</div>
<div>
<label for=search>Search:</label>
<input id=search type=search placeholder="Search...">
</div>
<div>
<label for=text>Text:</label>
<input id=text type=text placeholder="Type...">
</div>
</div>
§ Buttons
Wrap a <button> in a <strong> tag to get a primary button.
Buttons support the aria-pressed and aria-expanded attributes.
Buttons, .<button> masquerades, and <input type=file> all support colorways as well.
<script>
const toggle = el => (el.ariaPressed = (el.ariaPressed !== 'true'))
</script>
<section tabindex=0 class="overflow:auto">
<table id=button-table class="table">
<caption>Button demonstration</caption>
<thead>
<tr><th><th><th><code>.info</code><th><code>.ok</code><th><code>.warn</code><th><code>.bad</code>
<tbody>
<tr><th scope=row><code><button></code>
<td><button>Plain</button>
<td><button class="ok">Open</button>
<!-- ... -->
<tr><th scope=row class="padding-inline-start"><code>:disabled</code>
<td><button disabled>Plain</button>
<td><button disabled class="ok">Open</button>
<!-- ... -->
<tr><th scope=row class="padding-inline-start"><code>[aria-pressed=true]</code>
<td><button aria-pressed=true onclick="toggle(this)">Plain</button>
<td><button aria-pressed=true class="ok" onclick="toggle(this)">Open</button>
<!-- ... -->
<tr><th scope=row><code><strong><button></code>
<td><strong><button>Plain</button></strong>
<td><strong><button class="ok">Open</button></strong>
<!-- ... -->
<tr><th scope=row class="padding-inline-start"><code>:disabled</code>
<td><strong><button disabled>Plain</button></strong>
<td><strong><button disabled class="ok">Open</button></strong>
<!-- ... -->
<tr><th scope=row class="padding-inline-start"><code>[aria-pressed=true]</code>
<td><strong><button aria-pressed=true onclick="toggle(this)">Plain</button></strong>
<td><strong><button aria-pressed=true class="ok" onclick="toggle(this)">Open</button></strong>
<!-- ... -->
<tr><th scope=row><code><a class="<button>"></code>
<td><a href=#button-table class="<button>">Plain</button>
<td><a href=#button-table class="ok <button>">Open</button>
<!-- ... -->
</table>
</section>
.info | .ok | .warn | .bad
| ||
|---|---|---|---|---|---|
<button>
| |||||
:disabled
| |||||
[aria-pressed=true]
| |||||
<strong><button>
| |||||
:disabled
| |||||
[aria-pressed=true]
| |||||
<a class="<button>">
| Plain | Info | Open | Reset | Close |
§ Tabular forms
You can use the .table and .rows classes to create a form with inputs lined up like cells of a table.
Tabular forms default to wide inputs, but can be overridden with the .narrow-inputs utility class.
<form class="table rows">
<p><label for=inp>Label</label> <input id=inp></p>
...
§ Labeling radio buttons
The accepted way to label a group of radio buttons is to use <fieldset> and <legend>:
<fieldset>
<legend>Color</legend>
<ul>
<li><label><input type=radio name=color value="ff0000">Red</label>
<li><label><input type=radio name=color value="00ff00">Green</label>
<li><label><input type=radio name=color value="0000ff">Blue</label>
</ul>
</fieldset>
This works in missing.css, but these two elements are [notorious] for being hard to style.
You can use the following pattern instead, which will work with tabular forms.
Notice that the wrapper has role=radiogroup and its aria-labelledby value refers to the id of the label for the whole radiogroup.
<form class="table rows narrow-inputs">
<div>
<label for=item>Item</label>
<select id=item>
<option>Wallet
...
</select>
</div>
<div role=radiogroup aria-labelledby=color-lbl>
<span id=color-lbl>Color</span>
<div>
<div><label><input type=radio name=color value="ff0000"> Red</label></div>
<div><label><input type=radio name=color value="00ff00"> Green</label></div>
<div><label><input type=radio name=color value="0000ff"> Blue</label></div>
</div>
</div>
</form>