# Heading

> Headings in six sizes, independent of level. A CSS component with one class and no JavaScript.

Size and level are two different things. The level is `<h1>` to `<h6>` and decides the structure screen readers navigate by. `data-size` only decides how large the text looks.

## 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/heading/heading.css">
<!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css -->
```

```html
<h1 class="lt-heading" data-size="mega">Housing benefit application</h1>
<h2 class="lt-heading" data-size="xl">About the applicant</h2>
<h2 class="lt-heading">Living situation</h2>
<h3 class="lt-heading" data-size="m">Attachments</h3>
<h4 class="lt-heading" data-size="s">Birth certificate</h4>
<h5 class="lt-heading" data-size="xs">Last changed</h5>
```

**TypeScript**

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


<h1 {...lt.heading({ size: "mega" })}>Housing benefit application</h1>
```

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:

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


const title = document.querySelector<HTMLHeadingElement>("#section")


lt.setAttributes(title, lt.heading({ size: "m" }))
```

If the size comes from outside content, validate it with `lt.heading.isSize(x)`. See [Type-safe use](/type-safe-use.md).

| `data-size` | Font |
| - | - |
| `mega` | `--lt-font-size-mega` |
| `xl` | `--lt-font-size-xxl` |
| *(omitted)* | `--lt-font-size-xl` |
| `m` | `--lt-font-size-l` |
| `s` | `--lt-font-size-m` |
| `xs` | `--lt-font-size-s`, in capitals |

## Level follows the structure, not the look

An `<h2>` that should look small is correct. An `<h4>` chosen because it was small enough skips a level, and the table of contents the screen reader builds is then wrong:

```html
<h2 class="lt-heading" data-size="s">Attachments</h2>
```

The page should have one `<h1>`, and the levels below should follow each other without skipping.

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-heading` | The heading. The size comes from `data-size`. |

The sizes are the `--lt-font-size` tokens directly, so a change to the scale applies everywhere at once. Weight and line height are separate variables, because an organisation adopting the system often has its own typography:

| Variable | Default |
| - | - |
| `--lt-heading-font-weight` | `var(--lt-font-weight-bold)` |
| `--lt-heading-line-height` | `var(--lt-line-height-heading)` |

The headings use `text-wrap: balance`, so a heading over two lines does not end with a single word on the last one.

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

## Accessibility

- Screen readers can list every heading and jump between them. That is the most common way to find your way around a long page.
- Do not use a heading to make text large. Use [Paragraph](/components/paragraph.md) with `data-size="large"`.
- A heading with no content below it is not a heading.
