Radio
Plain CSS on an ordinary <input type="radio">. The buttons in a group are tied together by name, and that is what lets only one be selected, and lets the arrow keys move between them.
If the user can choose several, use Checkbox. If there are many options, Select takes less room on the screen.
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/radio/radio.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/fieldset/fieldset.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/label/label.css"><!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css --><fieldset class="lt-fieldset"><legend class="lt-legend" data-required="symbol">How do you want to receive the answer?</legend>
<div class="lt-radio-row"> <input class="lt-radio" type="radio" id="reply-digital" name="reply" value="digital" checked /> <label class="lt-label" for="reply-digital">In your digital mailbox</label></div>
<div class="lt-radio-row"> <input class="lt-radio" type="radio" id="reply-post" name="reply" value="post" /> <label class="lt-label" for="reply-post">As a letter in the post</label></div>
<div class="lt-radio-row"> <input class="lt-radio" type="radio" id="reply-collect" name="reply" value="collect" disabled /> <label class="lt-label" for="reply-collect">Collect at the office</label></div></fieldset>import "@lo-tek/interfaces/tokens.css"import "@lo-tek/interfaces/radio.css"import "@lo-tek/interfaces/fieldset.css"import "@lo-tek/interfaces/label.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"
<div className={lt.radio.row}> <input {...lt.radio()} id="reply-digital" name="reply" value="digital" /> <label {...lt.label()} htmlFor="reply-digital">Digitally</label></div>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 buttons = document.querySelectorAll<HTMLInputElement>("[name='reply']")
function mark(invalid: boolean) { for (const button of buttons) { lt.setAttributes(button, lt.radio({ state: invalid ? "invalid" : "default" })) }}You set name yourself, since only you know what the group is called. lt.radio.row gives the class for the row around it. See Type-safe use.
The group always belongs in a Fieldset. Without it only the option is read out, not the question it answers.
States
Section titled “States”<div class="lt-radio-row"><input class="lt-radio" type="radio" id="invalid-choice" name="example" data-state="invalid" aria-invalid="true" /><label class="lt-label" for="invalid-choice">You have to choose one option</label></div>data-state | Used for |
|---|---|
| (omitted) | Normal state |
invalid | Validation has failed |
success | The choice is confirmed valid. Use sparingly. |
If validation fails, set the state on every button in the group. It is the group that is invalid, not one of the buttons.
Classes you can style
Section titled “Classes you can style”| Class | What it is |
|---|---|
.lt-radio | The button itself |
.lt-radio-row | The row that holds the button and the text side by side |
| Variable | Default |
|---|---|
--lt-radio-size | var(--lt-spacing-5) |
The dot is a gradient drawn in --lt-color-accent-content, so it follows the theme without a separate image. See Customising.
Accessibility
Section titled “Accessibility”- Every button in the group has to share
name. Without it each button becomes its own group, and the user can choose several. - The arrow keys move between the buttons and select at the same time. Tab leaves the whole group. That is the browser’s own behaviour, and it should not be overridden.
- Do not preselect an option when the choice has a consequence. The default then becomes an answer the user never considered.
- If you only have two options that are each other’s opposite, consider Checkbox or Switch instead.