Skip to content

Expandable blocks

A full file is sometimes the clearest example, but a reader who scans the page does not need every line in view at once. The expandable attribute caps the block at a line count, with a fade at the cut and a button that reveals the rest.

Readers see

report.py
import csv
import sys
from collections import Counter
from pathlib import Path
def read_rows(path: Path) -> list[dict]:
with path.open() as fh:
return list(csv.DictReader(fh))
def summarise(rows: list[dict]) -> Counter:
return Counter(row["status"] for row in rows)
def main() -> None:
rows = read_rows(Path(sys.argv[1]))
counts = summarise(rows)
for status, n in counts.most_common():
print(f"{status:<10} {n:>5}")
if __name__ == "__main__":
main()

You write

```py title="report.py" expandable={8}
import csv
import sys
from collections import Counter
from pathlib import Path
def read_rows(path: Path) -> list[dict]:
with path.open() as fh:
return list(csv.DictReader(fh))
def summarise(rows: list[dict]) -> Counter:
return Counter(row["status"] for row in rows)
def main() -> None:
rows = read_rows(Path(sys.argv[1]))
counts = summarise(rows)
for status, n in counts.most_common():
print(f"{status:<10} {n:>5}")
if __name__ == "__main__":
main()
```

The block shows its first eight lines, faded at the bottom, with “Show all 24 lines” underneath. Clicking the button reveals the rest, and the button then reads “Show fewer lines”.

Syntax Where Effect
expandable Code block fence line Caps the block at the site default, 12 lines
expandable={N} Code block fence line Caps the block at N lines
expandable=false Code block fence line Turns off the auto option for the block
expandable.lines=<N> Code block fence line The line count for the block when it expands through expandable or auto

expandable with no number uses the site default:

.github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm test
  • The collapsed block:
    • The block shows the first N lines, with a fade over the last one.
    • A bar under the code has a button, “Show all X lines”, where X is the total. When the block is open, it reads “Show fewer lines”.
  • Other ways to open the block:
    • The collapsed lines use hidden="until-found" in browsers that support it. A reader who searches the page with Find still finds text inside them, and the block expands to show the match.
    • A line permalink to a collapsed line opens the block.
  • Which blocks collapse:
    • A block collapses only if the collapse hides three lines or more. A block with eight lines and expandable={7} renders in full.
    • Lines that hidden lines remove do not count. In a block of 20 lines with hidden={1-8} expandable={5}, readers see 5 lines, and the button reads “Show all 12 lines”.
    • A block with Expressive Code’s collapse attribute does not collapse, even with expandable, because its collapsed sections already shorten it.
  • Without JavaScript:
    • The block renders in full, with no fade and no button.
  • Motion:
    • The block eases open and closed in 200 ms. The button stays under the mouse cursor while the block closes.
    • With reduced motion, the block opens and closes at once.

Shows the first lines of long blocks, with a button to show the rest. Set it to false to turn the feature off. expandable and expandable={N} then have no effect.

Type
false | object
Default
On

Lines to show before the block expands. A code block can set its own on its fence line.

Type
number
Default
12

Makes every block with more lines than this expandable, without the attribute. expandable=false turns it off for one block.

Type
number | false
Default
false

To show more lines in blocks with the bare expandable attribute, raise lines:

astro.config.mjs
codeblocks({
expandable: { lines: 20 },
});

The auto option makes every block with more lines than its value expandable, with no attribute. The block shows lines lines:

astro.config.mjs
codeblocks({
expandable: { lines: 12, auto: 30 },
});

With this configuration, a block of 31 lines or more shows its first 12 lines. Add expandable=false to the fence line (the first line of the code block, with the language) of a block that must show in full. An expandable={N} attribute wins over the option.

auto skips blocks that have their own layout or their own controls:

  • Expandable blocks print in full: the fade and the button do not appear on paper.
  • Hidden lines: remove specific lines from view, instead of capping the block at a line count.
  • Focus: keep every line in view, and blur the ones that do not matter.