# List

> Bulleted lists, numbered lists and lists without bullets. A CSS component with one class and no JavaScript.

The class goes on `<ul>` or `<ol>` and gives the list the right spacing and indentation. The variants remove the bullets visually without removing the list itself. The exception is Safari, where VoiceOver may not read a `<ul>` without visible bullets as a list. An `<ol>` and a list inside `<nav>` keep it. If the count matters to someone listening to the page, set `role="list"` on the `<ul>`.

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

```html
<ul class="lt-list">
<li>Birth certificate</li>
<li>Confirmation from your employer</li>
<li>Copy of the tenancy agreement</li>
</ul>


<ol class="lt-list">
<li>Fill in the form</li>
<li>Upload attachments</li>
<li>Send the application</li>
</ol>


<ul class="lt-list" data-variant="divided">
<li>Invoice 2026-0481, due 4 March</li>
<li>Invoice 2026-0482, due 4 April</li>
</ul>
```

**TypeScript**

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


<ul {...lt.list({ variant: "divided" })}>
  <li>Housing benefit application</li>
  <li>Home loan application</li>
</ul>
```

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 list = document.querySelector<HTMLUListElement>("#attachments")


lt.setAttributes(list, lt.list({ variant: "divided" }))
```

| `data-variant` | Used for |
| - | - |
| *(omitted)* | Bullets or numbers, with indentation |
| `plain` | No bullets, for lists that carry their own structure |
| `divided` | No bullets, with a line between the rows |

## Why the variant exists

Without `plain`, people would write `<div>` to get rid of the bullets, and the information that this is a list of four items is lost. The variant removes the look, not the meaning, with the Safari exception above.

**Plain HTML**

```html
<ul class="lt-list" data-variant="plain">
<li>
  <div class="lt-card">
    <h3 class="lt-card__title">Housing benefit application</h3>
    <p>Sent 4 March.</p>
  </div>
</li>
<li>
  <div class="lt-card">
    <h3 class="lt-card__title">Nursery place application</h3>
    <p>In progress.</p>
  </div>
</li>
</ul>
```

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-list` | The list. The variant comes from `data-variant`. |

| Variable | Default |
| - | - |
| `--lt-list-gap` | `var(--lt-spacing-1)`, and `var(--lt-spacing-2)` in `divided` |

`--lt-list-gap` is the space between the items, and becomes the space above and below each row in `divided`. The two have different defaults, so if you set the variable, your value applies in both places. See [Customising](/customising.md).

## Accessibility

- Use `<ol>` when the order matters, as in a recipe or a sequence of steps in a case. Use `<ul>` otherwise.
- Put nothing but `<li>` directly inside the list. A `<div>` in between breaks the link between the list and its items.
- Lists of links should be in a list even when they look like a menu. The screen reader then says how many choices there are.
