# Post list

Lays out a list of posts as a grid, with the latest one larger, or as a compact list of rows. Each post is a card.

### Known issues
None known.

### Copy the markup
A list, one card in each item. The first item of the lead list has its text in a `<div>` beside the picture:

Post list markup
```html
<ul class="luz-post-list luz-post-list--lead" role="list">
  <li>
    <article class="luz-card">
      <div class="luz-image luz-image--3x2"><img src="/media/tide.jpg" width="600" height="400" alt="" loading="lazy"></div>
      <div>
        <p class="luz-tag luz-tag--gray u-mb-sm">Coast</p>
        <h2 class="luz-card__title"><a href="/2026/10/tide-records/">What ten years of tide records say about the bay</a></h2>
        <p class="luz-card__body">Volunteers have read the gauge in the port twice a day since 2016.</p>
        <p class="luz-meta"><time datetime="2026-10-12">12 October 2026</time> <span>6 min read</span></p>
      </div>
    </article>
  </li>
  <!-- one li for each post; the others have no div around their text -->
</ul>
```

A template for the results page of a search: a `<search>` with its form, a heading that says how many results there are, and the compact list. Your site's search fills in the results; the text here is a placeholder.

Search results markup
```html
<search>
  <form action="/search/">
    <label for="q">Search the blog</label>
    <input type="search" id="q" name="q" value="tide">
    <button type="submit">Search</button>
  </form>
</search>
<h2 id="results-title">3 results for "tide"</h2>
<ul class="luz-post-list luz-post-list--compact" role="list" aria-labelledby="results-title">
  <li>
    <article class="luz-card">
      <h3 class="luz-card__title"><a href="/2026/10/tide-records/">What ten years of tide records say about the bay</a></h3>
      <p class="luz-meta"><time datetime="2026-10-12">12 October 2026</time> <span>Coast</span></p>
    </article>
  </li>
  <!-- one li for each result -->
</ul>
```

### Variants and options
- `.luz-post-list`: On a `<ul>`: as many equal columns as fit, none under `--luz-post-list-min` (16rem), no bullets. Each card is as tall as the tallest in its row
- `.luz-post-list--lead`: From 40rem of list width, the first item spans two columns and its card puts the picture beside the text, with a larger title
- `.luz-post-list--compact`: One column, a row for each post: the title, and the facts at its end when there is room. Leave out the picture and the summary
- `--luz-post-list-min`: The narrowest a column may be. Set it on the list or an ancestor

### How it works
CSS from `components/post-list.css` of `@luz-ds/catalog`. It sets the layout; the post is core's card, with the picture, tag, title, summary and [meta line](https://nandovejer.github.io/luz/docs/components/meta/) you choose.

- The list is its own size container, so the lead follows the room it has and not the window. Give it a parent that sets its width: a flex or grid item sized by its content leaves it no width.
- Under 40rem the lead is a card like the rest, with its picture above.
- The link on the title makes the whole card one link, as in any card.

### Without JavaScript
Nothing changes. It is a list of cards, and the package has no script.

### Keyboard and ARIA
- **Order:** the source order, which is the reading order. In the lead the picture comes before the text; each card is one tab stop, on its title link.
- **List:** the `<ul>` is announced with its count ("list, 12 items"). Keep `role="list"`: some browsers drop the list from a `<ul>` without bullets.
- **Names:** each link is named by its post title. A picture that only decorates the post has `alt=""`. Give the list a heading, or an `aria-label`, when the page has more than one.
- **Search results:** `<search>` is the search landmark, so the form inside it needs no `role="search"`: adding one would nest a second landmark. Put the results outside `<search>`, in the `<main>`. If the page has more than one `<search>`, name each with `aria-label`. Name the list with the heading that counts the results, with `aria-labelledby`.
- **Announcing the results:** a results page that loads whole needs no live region: put the count and the query in the `<title>` and in the `<h1>`. If your site filters the list in place, put the count in a separate element with `role="status"`: a heading is not live, so a screen reader does not say it changed.

### When to use
Use it whenever a page shows several posts, so every list on the site is laid out alike.

- Base: the posts of a category or a tag.
- Lead: the home, when one post should be read first.
- Compact: an archive by date, or the results of a search.

### When not to use
Do not use it for a single card, or for items that are not posts.

- One post is a [card](https://nandovejer.github.io/luz/docs/components/card/). Products, people and plans are cards in a `.o-grid--auto`.
- For the pages of a long list, add [pagination](https://nandovejer.github.io/luz/docs/components/pagination/) after it.
