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

```html
<button class="lt-button" data-variant="danger">
Delete<span class="lt-sr-only"> the report 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: "danger" })} type="button">
  Delete{" "}
  <span {...lt.srOnly()}>the report from 4 March</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 “Deletethe report from 4 March”.

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 report from 4 March"


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

**kotlinx.html**

```kotlin
// Once for the whole app, in the page template: every stylesheet, from the WebJar.
head { link(rel = "stylesheet", href = LotekWebJar.CSS) }
```

On a Kotlin or Java server, the same with kotlinx.html and `lo-tek-kotlinx-html`. The builder functions are in `Lt`, with an enum for each list of values:

```kotlin
import kotlinx.html.*
import no.lotek.*
import no.lotek.html.lt


fun FlowContent.delete() {
    button {
        lt(Lt.button(variant = ButtonVariant.DANGER))
        +"Delete"
        span { lt(Lt.srOnly()); +" the report from 4 March" }
    }
}
```

The button is read out as “Delete the report 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 the site</label>
<input class="lt-input" id="search" type="search" placeholder="Search the site" />
```

`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`.
