# Sr Only

> Text only screen readers get. A CSS component with one class and no JavaScript.

Content that should be read out, but not shown. The class shrinks the element away visually and leaves it in the document, so screen readers still find it.

## How to use it

A row of “Delete” buttons makes sense to someone looking at the table. Someone listening to it gets four identical buttons. The addition in `.lt-sr-only` says which row the button belongs to, without repeating it for the eye.

**Plain HTML**

```html
<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/sr-only/sr-only.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/button/button.css">
<!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css -->
```

```html
<button class="lt-button" data-variant="danger">
Delete<span class="lt-sr-only"> the application from 4 March</span>
</button>
```

**TypeScript**

```ts
import "@lo-tek/interfaces/tokens.css"
import "@lo-tek/interfaces/sr-only.css"
import "@lo-tek/interfaces/button.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:

```tsx
import { lt } from "@lo-tek/interfaces/react"


<button {...lt.button({ variant: "ghost" })} type="button">
  Delete{" "}
  <span {...lt.srOnly()}>application 2024/1187</span>
</button>
```

`{" "}` is the space between the two words. JSX strips a line break between text and an element, and without it the button is read as “Deleteapplication”.

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 you have the element in a variable,** set them on it with `setAttributes`. That is the way without JSX, whether you just created the element or found it in a page the server sent:

```ts
import { lt } from "@lo-tek/interfaces"


const addition = document.createElement("span")
addition.textContent = " the application from 4 March"


lt.setAttributes(addition, lt.srOnly())
```

The button is read out as “Delete the application from 4 March”, while it shows “Delete” on screen.

## Hidden label

If the label is obvious from the layout, it can be hidden visually. It should not be removed.

**Plain HTML**

```html
<label class="lt-label lt-sr-only" for="search">Search cases</label>
<input class="lt-input" id="search" type="search" placeholder="Search cases" />
```

`placeholder` is no replacement for a label: it disappears as soon as the user types, and several screen readers do not read it out at all.

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-sr-only` | The element that should be heard, but not seen |

The class has no variables. It has one job, and the values in it are the ones that actually work across browsers.

## Accessibility

- Use it only on text that makes sense read on its own. An explanation that only fits with something you can see becomes confusing when it is read out in a list of links.
- If the content should go for everyone, use `hidden`. `display: none` and `visibility: hidden` remove the element for screen readers too, and that is exactly what this class avoids.
- An element with the class can still get focus. If you put a link there, focus jumps to something the user cannot see. If it should be shown when it gets focus, you have to restore the styles in `:focus`.
