UNPKG

@ou-imdt/css

Version:

The IMDT CSS library styles native elements with light, extendable CSS. It is developed for Interactive Media Developers at the Open University.

759 lines (561 loc) 22.9 kB
# form __A Note on Disabled Inputs__ In most cases assistive technology doesn't recognize disabled controls. So it can be argued they shouldn't be present at all when disabled for consistency. There are some techniques for disabling in an accessible way but the behaviour across elements cannot be handled with css alone. ## Aria In most cases the use of aria-tags can complicate things, so unless youa re sure it's necessary stick to using semantic tags. __A Note on Aria Pressed__ Most often used on buttons to denote an active or inactive state. Aria-pressed text content does not change, for example a 'Play' button should not change to 'Paused' when it is pressed. Icons can change but te actual label (e.g. aria-label) should not. It should be noted that input `type=button` supports global aria attributes but does not support the use of 'aria-pressed' which seems to be more specific to the button tag or explicit button role; though it does appear to work, we are not recommending that usage. __A Note on Aria Switch__ <blockquote> The ARIA switch role is functionally identical to the checkbox role, except that instead of representing "checked" and "unchecked" states, which are fairly generic in meaning, the switch role represents the states "on" and "off." <cite> <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/switch_role">MDN </a> </cite> </blockquote> ## Inputs There are a few rules that should be followed with inputs: - Inputs MUST have an associated label (with the exception of type image which MUST have an alt attribute that serves as a label and type button which uses value as it's label and name). - Exception: use of aria-label - Related inputs SHOULD be grouped using fieldsets (e.g. radio groups, checkbox groups, fields for related information). Optional attributes: - required: adding this makes it so a field must be populated for a form to submit. - minlength: minimum character length. - maxlength: maximum character length. - list: link field to a datalist allowing users to type or select from a list. - pattern: a regex pattern used for client-side validation (see js RegEx object); you can add a title attribute for a tooltip or instruction for assistive technology, though it is better practice to have explanatory text nearby. - placeholder: can be used to add a 'hint' text to a field. This is not recommended as it has no semantic value and often can't be detected by assistive technology. - readonly: prevents users from editing a field. Useful in edge cases but please consider assistive technology if using. - size: set the length of a text input in characters, using CSS is preferred over this method. - spellcheck: (true/false or blank) Enables user agent spellchecking on field. ## Examples ### Text Input The most commonly used input field. <div class="card"> <label for="name">Name: </label> <input id="name" name="name" type="text" /> <label for="name-disabled">Name Disabled: </label> <input id="name-disabled" name="name-disabled" type="text" disabled /> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="name">Name: </label> <input id="name" name="name" type="text" /> <label for="name-disabled">Name Disabled: </label> <input id="name-disabled" name="name-disabled" type="text" disabled /> ``` </details> ### Colour Input Not often used. <div class="card"> <label for="color2">Simple</label> <input id="color2" name="color2" type="color" /> <label for="color3">With Datalist</label> <input id="color3" name="color3" type="color" list="color-list" value="#ff0000" /> <datalist id="color-list"> <option>#ff0000</option> <option>#00ff00</option> <option>#0000ff</option> <option>purple</option> <!--ignored as invalid --> <option>#F00</option> <!--ignored as invalid --> </datalist> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="name">Name: </label> <input id="name" name="name" type="text" /> <label for="name-disabled">Name Disabled: </label> <input id="name-disabled" name="name-disabled" type="text" disabled /> ``` </details> ### Date Input <div class="card"> <label for="date1">Simple: </label> <input id="date1" name="date1" type="date" /> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="date1">Date: </label> <input id="date1" name="date1" type="date" /> ``` </details> ### DateTime Input <div class="card"> <label for="datetime1">Datetime: </label> <input id="datetime1" name="datetime1" type="datetime-local" /> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="datetime1">Datetime: </label> <input id="datetime1" name="datetime1" type="datetime-local" /> ``` </details> ### Email Input <div class="card"> <label for="email1">Simple Email: </label> <input id="email1" name="email1" type="email" /> <hr> <p>Email with custom pattern for validation.</p> <form onsubmit="((e) => {e.preventDefault(); alert('submit'); return false})()"> <div> <label for="email">User email (required)</label> <input type="text" name="email" id="email" required pattern=".+@open\.ac.uk" title="*@open.ac.uk"> </div> <button type="submit">Submit</button> </form> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="email1">Simple Email: </label> <input id="email1" name="email1" type="email" /> <hr> <p>Email with custom pattern for validation -> the use of 'onsubmit' is for demo purposes only and is not recomended usage.</p> <form onsubmit="((e) => {e.preventDefault(); alert('submit'); return false})()"> <div> <label for="email">User email (required)</label> <input type="text" name="email" id="email" required pattern=".+@open\.ac.uk" title="*@open.ac.uk"> </div> <button type="submit">Submit</button> </form> ``` </details> ### File Input <div class="card"> <label for="file1">File: </label> <input id="file1" name="file1" type="file" /> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="file1">File: </label> <input id="file1" name="file1" type="file" /> ``` </details> ### Image Input The Image input is used to create graphical submit buttons. Similar to an 'img' tag the 'image' type input requires an alt tag for cases where the image wont load. <div class="card"> <form onsubmit="((e) => {e.preventDefault();alert('submit'); return false})()"> <input type="image" alt="Image input" SameSite="Strict" src="https://picsum.photos/200" /> </form> </div> <details class="compact"> <summary>HTML</summary> ```html <form onsubmit="((e) => {e.preventDefault();alert('submit'); return false})()"> <input type="image" alt="Image input" SameSite="Strict" src="https://picsum.photos/200" /> </form> ``` </details> ### Number Input <div class="card"> <label for="num">Number</label> <input id="num" name="num" type="number" max="10" min="0" step="1" value="1" /> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="num">Number</label> <input id="num" name="num" type="number" max="10" min="0" step="1" value="1" /> ``` </details> ### Password Input <div class="card"> <label for="pwd1">Password</label> <input type="password" name="pwd1" id="pwd1"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="pwd1">Password</label> <input type="password" name="pwd1" id="pwd1"> ``` </details> ### Radio and Checkbox Input Radio and checkbox inputs in the core css are sized using 'em' which is to say they will re-size to match the current text size dynamically (the large example below is just an input nested in a h3 tag). #### Radios <div class="card"> <h3><label>Large <input type="radio"></label></h3> <fieldset> <legend>Drink?</legend> <label>Coffee <input type="radio" name="drink"></label> <label>Tea <input type="radio" name="drink"></label> <label>Water <input type="radio" name="drink"></label> <label>Disabled <input type="radio" name="drink" disabled></label> </fieldset> </div> <details class="compact"> <summary>HTML</summary> ```html <h3><label>Large <input type="radio"></label></h3> <fieldset> <legend>Drink?</legend> <label>Coffee <input type="radio" name="drink"></label> <label>Tea <input type="radio" name="drink"></label> <label>Water <input type="radio" name="drink"></label> <label>Disabled <input type="radio" name="drink" disabled></label> </fieldset> ``` </details> #### Checkboxes <div class="card"> <h3><label>Large <input type="checkbox"></label></h3> <fieldset> <legend>Drink?</legend> <label>Coffee <input type="checkbox"></label> <label>Tea <input type="checkbox"></label> <label>Water <input type="checkbox"></label> <label>Disabled <input type="checkbox" disabled></label> </fieldset> </div> <details class="compact"> <summary>HTML</summary> ```html <h3><label>Large <input type="checkbox"></label></h3> <fieldset> <legend>Drink?</legend> <label>Coffee <input type="checkbox"></label> <label>Tea <input type="checkbox"></label> <label>Water <input type="checkbox"></label> <label>Disabled <input type="checkbox" disabled></label> </fieldset> ``` </details> ### Range Input Native range inputs are notoriously varied in appearance across browser. There is a simple utility class '.range' that can be applied to make the styling more consistent cross-browser but using it prevents the use of ticks (we have decided not to completely override native ranges to allow the use of data lists and ticks). <div class="card"> <label for="range1">Range: </label> <input type="range" name="range1" id="range1"> <label for="rangeWticks">Range with ticks</label> <input id="rangeWticks" name="rangeWticks" type="range" list="tickmarks" min="0" max="100" step="10"> <datalist id="tickmarks"> <option value="0" label="0%">0</option> <option value="10"></option> <option value="20"></option> <option value="30"></option> <option value="40"></option> <option value="50" label="50%"></option> <option value="60"></option> <option value="70"></option> <option value="80"></option> <option value="90"></option> <option value="100" label="100%"></option> </datalist> <label for="ranger1">Class 'range' applied: </label> <input type="range" name="ranger1" id="ranger1" class="range"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="pwd1">Password</label> <input type="password" name="pwd1" id="pwd1"> ``` </details> ### Search Input <div class="card"> <label for="search1">Search </label> <input type="search" name="search1" id="search1"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="search2">Search </label> <input type="search" name="search1" id="search2"> ``` </details> ### Submit Input __A 'button' tag with a 'submit' type shoudl be used over a input with type submit.__ Submit inputs are buttons so name and label attributes are not needed. The value attribute is used in place of a label; if no value is specified the user agent will revert to it's default label for submit elements. <div class="card"> <input value="Custom label" type="submit" /> <input type="submit" /> </div> <details class="compact"> <summary>HTML</summary> ```html <input value="Custom label" type="submit" /> <input type="submit" /> ``` </details> ### Tel Input The tel input is functionally the same as the text field, unlike field types like email or url there is no custom validation or processing. In general using a tel input for phone numbers is beneficial for mobile browsers as they will generally have custom keypad interactions for phone numbers. <div class="card"> <label for="tel1">Explicit label:</label> <input type="tel" name="tel1" id="tel1"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="tel2">Explicit label:</label> <input type="tel" name="tel2" id="tel2"> ``` </details> ### Time Input <div class="card"> <label for="time1">Explicit label:</label> <input type="time" name="time1" id="time1"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="time2">Explicit label:</label> <input type="time" name="time2" id="time2"> ``` </details> ### URL Input <div class="card"> <label for="url1">Explicit label:</label> <input type="url" name="url1" id="url1"> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="url1">Explicit label:</label> <input type="url" name="url1" id="url1"> ``` </details> ### Textarea <div class="card"> <label for="t1">Textarea</label> <textarea name="t1" id="t1"></textarea> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="t1">Textarea</label> <textarea name="t1" id="t1"></textarea> ``` </details> ### Progress Progress bar indicates the 'progress' of a task, it's more likly to move in only one direction. Examples: Loading assets, a count down or sount up indicator. <dl> <dd>max</dd> <dt>This attribute describes how much work the task indicated by the progress element requires</dt> <dd>value</dd> <dt>This attribute specifies how much of the task that has been completed. If no value is specified the progress bar is 'indeterminate' which means it is loading until complete rather than knowing a specific progress value.</dt> </dl> __Note__: _Text placed between the element's tags is not an accessible label, it is only recommended as a fallback for old browsers that do not support this element._ <div class="card"> <label for="progress-bar">Progress</label> <progress id="progress-bar" value="70" max="100">70 %</progress> <label for="progress-bar-indeterminate">Indeterminate progress bar (no value specified)</label> <progress id="progress-bar-indeterminate" max="100"></progress> <br><br> <div aria-busy="true" aria-describedby="progress-bar"> <em> Imagine a lot of data being loaded from a csv file incrementally is going to appear here... </em> </div> <label for="progress-bar3">CSV Content Loading...</label> <progress id="progress-bar3" max="100"></progress> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="progress-bar">Progress</label> <progress id="progress-bar" value="70" max="100">70 %</progress> <label for="progress-bar-indeterminate">Indeterminate progress bar (no value specified)</label> <progress id="progress-bar-indeterminate" max="100"></progress> <br><br> <div aria-busy="true" aria-describedby="progress-bar"> <em> Imagine a lot of data being loaded from a csv file incrementally is going to appear here... </em> </div> <label for="progress-bar3">CSV Content Loading...</label> <progress id="progress-bar3" max="100"></progress> ``` </details> ### Meter A meter can be thought of as a gauge and is used to display value within a range. The meter element should not be used to indicate progress (as in a progress bar). Examples: Health bar in a game, fuel left in an engine. The meter element also does not represent a scalar value of arbitrary range — for example, it would be wrong to use this to report a weight, or height, unless there is a known maximum value. <dl> <dd>value</dd> <dt></dt> <dd>min</dd> <dd>max</dd> <dd>low</dd> <dd>high</dd> <dd>optimum</dd> <dt>Used with the low and high attributes to determine the where along the range is preferred. Browsers may color this element differently depending on on if the value is greater or less than the optimum.</dt> <dd>form</dd> <dt>ID of the form element the meter is associated with, if this is not set it will refer to it's ancestor form. This is only usable in this case if the meter is being used as an indicator for a form input.</dt> </dl> <div class="card"> <label for="meter-1">Low Coffee</label> <meter id="meter-1" min="0" max="100" value="5" low="25" high="75" optimum="76"></meter> <label for="meter-2">Medium Coffee</label> <meter id="meter-2" min="0" max="100" value="50" low="25" high="75" optimum="76"></meter> <label for="meter-3">High Coffee</label> <meter min="0" max="100" value="95" low="25" high="75" optimum="76" id="meter-3"></meter> <strong>sometimes less is more (colors are reversed)</strong> <label for="meter-4">Low Stress</label> <meter id="meter-4" min="0" max="100" value="5" low="25" high="75" optimum="24"></meter> <label for="meter-5">Medium Stress</label> <meter id="meter-5" min="0" max="100" value="50" low="25" high="75" optimum="24"></meter> <label for="meter-6">High Stress</label> <meter id="meter-6" min="0" max="100" value="95" low="25" high="75" optimum="24"></meter> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="meter-1">Low Coffee</label> <meter id="meter-1" min="0" max="100" value="5" low="25" high="75" optimum="76"></meter> <label for="meter-2">Medium Coffee</label> <meter id="meter-2" min="0" max="100" value="50" low="25" high="75" optimum="76"></meter> <label for="meter-3">High Coffee</label> <meter min="0" max="100" value="95" low="25" high="75" optimum="76"></meter> <strong>sometimes less is more (colors are reversed)</strong> <label for="meter-4">Low Stress</label> <meter id="meter-4" min="0" max="100" value="5" low="25" high="75" optimum="24"></meter> <label for="meter-5">Medium Stress</label> <meter id="meter-5" min="0" max="100" value="50" low="25" high="75" optimum="24"></meter> <label for="meter-6">High Stress</label> <meter id="meter-6" min="0" max="100" value="95" low="25" high="75" optimum="24"></meter> ``` </details> ### Select, Option and Optgroup Please be aware select box elements appear differently in different browsers (and are difficult to style out of the box). Core is intended to create a consisted baseline for native elements with minimal css/js/markup intervention so only minimal styles are applied. We will create a select component at a later date for more advanced styling/functionality. <div class="card"> <label for="s1">Select</label> <select name="s1" id="s1"> <option value="">--Please choose an option--</option> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <label for="s1.2">Select Disabled</label> <select name="s1.2" id="s1.2" disabled> <option value="">--Please choose an option--</option> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <label for="s3">Select (Multiple)</label> <select name="s3" id="s3" multiple> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <small>Keyboard: Hold down <code>ctrl</code> or <code>shift</code> and select.</small> <label for="s4">Select with option groups</label> <select name="s4" id="s4"> <optgroup label="Front End"> <option value="css">CSS</option> <option value="js">Javascript</option> <option value="html">HTML</option> </optgroup> <optgroup label="Backend"> <option value="none">Node</option> <option value="full">PHP</option> <option value="cream">MSSQL</option> <option value="skimmed">MYSQL</option> <option value="plant">SQLlite</option> </optgroup> </select> <label for="s5">Select with option groups and multiple</label> <select name="s5" id="s5" multiple> <optgroup label="Sugar"> <option value="oneSugar">One Sugar</option> <option value="twoSugar">Two Sugar</option> <option value="sweetner">Sweetner</option> </optgroup> <optgroup label="Milk"> <option value="none">None</option> <option value="full">Full fat milk</option> <option value="cream">Cream</option> <option value="skimmed">Skimmed Milk</option> <option value="plant">Plant-based alternative</option> </optgroup> <optgroup label="Hot drink"> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="chai">Chai</option> <option value="cocoa">Cocoa</option> </optgroup> </select> </div> <details class="compact"> <summary>HTML</summary> ```html <label for="s1">Select</label> <select name="s1" id="s1"> <option value="">--Please choose an option--</option> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <label for="s1.2">Select Disabled</label> <select name="s1.2" id="s1.2" disabled> <option value="">--Please choose an option--</option> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <label for="s3">Select (Multiple)</label> <select name="s3" id="s3" multiple> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="water">Water</option> </select> <small>Keyboard: Hold down <code>ctrl</code> or <code>shift</code> and select.</small> <label for="s4">Select with option groups</label> <select name="s4" id="s4"> <optgroup label="Front End"> <option value="css">CSS</option> <option value="js">Javascript</option> <option value="html">HTML</option> </optgroup> <optgroup label="Backend"> <option value="none">Node</option> <option value="full">PHP</option> <option value="cream">MSSQL</option> <option value="skimmed">MYSQL</option> <option value="plant">SQLlite</option> </optgroup> </select> <label for="s5">Select with option groups and multiple</label> <select name="s5" id="s5" multiple> <optgroup label="Sugar"> <option value="oneSugar">One Sugar</option> <option value="twoSugar">Two Sugar</option> <option value="sweetner">Sweetner</option> </optgroup> <optgroup label="Milk"> <option value="none">None</option> <option value="full">Full fat milk</option> <option value="cream">Cream</option> <option value="skimmed">Skimmed Milk</option> <option value="plant">Plant-based alternative</option> </optgroup> <optgroup label="Hot drink"> <option value="coffee">Coffee</option> <option value="tea">Tea</option> <option value="chai">Chai</option> <option value="cocoa">Cocoa</option> </optgroup> </select> ``` </details>