Label
The right typography on <label>, and one consistent way to mark required and optional fields. If you are setting up a whole field, Field is usually simpler. It sets for, id and aria-describedby for you.
How to use it
Section titled “How to use it”<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/tokens/tokens.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/label/label.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/input/input.css"><!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css --><label class="lt-label" for="name">Full name</label><input class="lt-input" id="name" type="text" />
<label class="lt-label" data-required="symbol" for="email">Email address</label><input class="lt-input" id="email" type="email" required />
<label class="lt-label" data-required="text" for="phone">Phone number</label><input class="lt-input" id="phone" type="tel" required />
<label class="lt-label" data-optional="" for="address">Address</label><input class="lt-input" id="address" type="text" />
<label class="lt-label" aria-disabled="true" for="org-number">Organisation number</label><input class="lt-input" id="org-number" type="text" disabled />import "@lo-tek/interfaces/tokens.css"import "@lo-tek/interfaces/label.css"import "@lo-tek/interfaces/input.css"lt is used in two ways, and which one depends on whether you create the element or find it.
If you create the markup, spread the attributes in. That is the way in React, Astro and anything else that renders:
import { lt } from "@lo-tek/interfaces/react"
<label {...lt.label()} htmlFor="name">Full name</label><input {...lt.input({ type: "text" })} id="name" />The import is from /react here, since the block is JSX. From there the keys are className and htmlFor. In Astro and anything else without React, import @lo-tek/interfaces and you get class and for.
If the element is already there, set them on it. That is the way when you enhance HTML a server or a template has sent:
import { lt } from "@lo-tek/interfaces"
const label = document.querySelector<HTMLLabelElement>("#email-label")if (!label) throw new Error("element not found")
lt.setAttributes(label, lt.label({ required: "symbol" }))label.htmlFor = "email"You set for yourself. The function returns only LO-TEK’s own attributes.
If you are setting up a whole field, lt.field does both the marking and the wiring to the control:
const input = document.querySelector<HTMLInputElement>("#email")
const field = lt.field({ id: "email", required: "symbol" })
lt.setAttributes(label, field.label)lt.setAttributes(input, lt.input({ type: "email" }), field.control)if (input) input.required = truerequired: "symbol" gives only the asterisk. That the field has to be filled in is said by required on the field itself.
| Attribute | Effect |
|---|---|
| (omitted) | An ordinary label |
data-required="symbol" | * in the danger colour |
data-required="text" | (required) in the danger colour |
data-optional="" | (optional) in a muted colour |
aria-disabled="true" | Muted text colour |
Choose one of data-required and data-optional and stick to it throughout the form. If you set both, the system shows only one: they are the same ::after, and the builder function drops data-optional when the field is required.
Together with a field
Section titled “Together with a field”for has to match the id of the field. Without the wiring the label is not read out when the field gets focus, and a click on the text does not move focus there.
We use the address to send you a receipt.
<label class="lt-label" data-required="symbol" for="email">Email address</label><input class="lt-input" id="email" type="email" required aria-describedby="email-help" /><p class="lt-help-text" id="email-help">We use the address to send you a receipt.</p>Classes you can style
Section titled “Classes you can style”| Class | What it is |
|---|---|
.lt-label | The label. The markers are added with ::after. |
The marker behind data-required and data-optional is text in ::after, and the text is read from a variable. It can then be replaced, or translated, without changing the markup:
| Variable | Default |
|---|---|
--lt-label-required-symbol | " *" |
--lt-label-required-text | " (required)" |
--lt-label-optional-text | " (optional)" |
:root:lang(nb) { --lt-label-required-text: " (påkrevd)"; --lt-label-optional-text: " (valgfri)";}The variables also apply to .lt-legend in Fieldset. See Translation.
See Customising for how the layer works.
Accessibility
Section titled “Accessibility”data-requiredis only visual. Setrequiredon the field itself, or the screen reader will not know it has to be filled in.- The asterisk and “(required)” are added with
::after. Content in::aftercounts towards the field’s name, so a screen reader may read it after the label. It isrequiredon the field that says it has to be filled in. - Never hide the label completely. If you need it gone visually, use
.lt-sr-onlyfromsr-only.cssrather thanplaceholder, which disappears as soon as the user types.