# Icon

> An icon from the app's own set, as large as the text around it. A CSS component with one class and no JavaScript.

The class goes on an `<svg>`. LO-TEK ships no icons, so the svg comes from the set the app already uses. The class makes the icon as large as the surrounding text and centres it on the line, and `lt.icon()` hides it from screen readers when it is only decoration.

## How to use it

**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/button/button.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/icon/icon.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" type="button">
<svg class="lt-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="2">
  <path d="M12 5v14M5 12h14" />
</svg>
New application
</button>


<button class="lt-button" data-variant="ghost" type="button" aria-label="Delete the application">
<svg class="lt-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="2">
  <path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" />
</svg>
</button>
```

**TypeScript**

```ts
import "@lo-tek/interfaces/tokens.css"
import "@lo-tek/interfaces/button.css"
import "@lo-tek/interfaces/icon.css"
```

**If you create the markup,** spread the attributes in:

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


<button {...lt.button({ variant: "ghost" })} type="button" aria-label="Delete the application">
  <svg {...lt.icon()} viewBox="0 0 24 24">…</svg>
</button>
```

**If the element is already there,** set them on it:

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


const icon = document.querySelector<SVGSVGElement>("#warning-icon")


lt.setAttributes(icon, lt.icon({ label: "Warning" }))
```

Without `label`, `lt.icon()` gives `aria-hidden="true"`. With `label` it gives `role="img"` and `aria-label` instead. See [Type-safe use](/type-safe-use.md).

The first button has text, and the icon is decoration next to it. The second has only the icon, and gets its name from `aria-label` on the button.

## Size and colour

The icon is `1em` wide and high, so it follows the font size where it stands. If you want it larger or smaller than the text, set `font-size` on the icon.

The colour comes from the svg. Write `currentColor` in `fill` or `stroke`, as icon sets do, and the icon gets the colour of the surrounding text. It also follows the text in forced colours mode. The stylesheet does not set `fill` itself: an icon drawn with strokes has `fill="none"`, and a rule in the stylesheet would fill it.

## An icon that means something

If the icon stands alone and says something the reader needs, such as a warning sign with no text next to it, it gets a name:

```html
<svg class="lt-icon" role="img" aria-label="Warning" viewBox="0 0 24 24"
     fill="none" stroke="currentColor" stroke-width="2">
  <path d="M12 3l9 16H3zM12 10v4M12 17v.01" />
</svg>
```

If text next to it says the same thing, the icon is decoration and should have `aria-hidden="true"`. Otherwise the same thing is read out twice.

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-icon` | The icon, on an `<svg>`. |

See [Customising](/customising.md) for how the layer works.

## Accessibility

- A button or link with only an icon in it needs a name: `aria-label` on the button, or a text in an element with the class `lt-sr-only`. `lotek check` and the editors report `icon-without-name` when it is missing.
- Write what the button does, not what the icon depicts. “Delete the application” is better than “Rubbish bin”.
- An icon alone is hard for many people to understand, including those who can see it. If you have room, text next to it is better than only a name for the screen reader.
