---
title: "Visible whitespace"
description: "Show spaces and tabs as faint glyphs, for the blocks where indentation changes the meaning of the code."
url: "https://ewels.github.io/starlight-codeblocks/features/visible-whitespace/"
markdown: "https://ewels.github.io/starlight-codeblocks/features/visible-whitespace.md"
section: "Make code easier to read"
site: "starlight-codeblocks documentation"
context: "This page is from the documentation of starlight-codeblocks. A Starlight plugin that adds focus, line states, annotations, API auto-linking and 22 more features to the code blocks of a site."
index: "https://ewels.github.io/starlight-codeblocks/llms.txt"
---

# Visible whitespace

> Show spaces and tabs as faint glyphs, for the blocks where indentation changes the meaning of the code.

A code block usually renders whitespace as empty space. That is fine for most languages, but some depend on the exact character. Make needs a tab at the start of a recipe, and Python needs consistent indentation. The `whitespace` attribute shows spaces and tabs as glyphs, so readers see which character is there.

````md
```make title="Makefile" whitespace
build:
	cargo build --release

test:
    cargo test  # Recipes must start with a tab
```
````

The first recipe starts with an arrow, for the tab that Make needs. The second starts with four dots, for the four spaces that Make rejects. Copying the block gives the real characters, not the glyphs.

## Syntax

| Syntax | Where | Effect |
|---|---|---|
| `whitespace` | Code block fence line | Shows the leading whitespace of every line |
| `whitespace="all"` | Code block fence line | Shows every space and tab in the block |

## Examples

### Every space and tab

`whitespace="all"` shows every space, which is useful when trailing whitespace is part of what you are explaining:

````md
```text title="diff.patch" whitespace="all"
-  const width = 10; 
+  const width = 12;
```
````

## Behaviour

- The glyphs:
  - A space renders as a middle dot. A tab renders as an arrow at the start of the tab. The tab keeps its width up to the next tab stop. The plugin sets the CSS `tab-size` property of code blocks to 2 columns.
  - By default, the plugin shows only the leading whitespace of each line, where indentation usually matters. `whitespace="all"` shows every space and tab, including the ones between words and at the end of a line.
  - The glyphs are faint, so that they do not compete with the code. They use the text colour of the theme at about a third of its strength.
- Screen readers:
  - Screen readers do not hear the glyphs. They read the same code as a block without the attribute.
- Copy:
  - The glyphs are drawn with CSS on top of the real character. A manual copy or the copy button gives the actual spaces and tabs.
- Without JavaScript:
  - Visible whitespace needs no JavaScript in the browser.

## Options

Visible whitespace has no options. Turn it off for the whole site with `whitespace: false`:

```js title="astro.config.mjs"
codeblocks({
  whitespace: false,
});
```

The style setting `codeblocksWhitespace.foreground` changes the colour of the glyphs.

- [Configuration](https://ewels.github.io/starlight-codeblocks/configuration/): Learn how to set options for the whole site, or for a single code block.

## Limitations

- The glyphs add visual noise on a block with a lot of whitespace. Use `whitespace="all"` only where the extra detail matters, and leave the default, leading-only view for everything else.
- Expressive Code removes the whitespace at the end of each line before any plugin sees the code. The plugin puts it back for fenced code blocks in Markdown and MDX. A block that the `<Code>` component renders does not show trailing whitespace.
- Expressive Code turns every tab into spaces before this feature can see it. `codeblocks()` sets `tabWidth: 0` for you unless you already chose your own value. A site without Starlight sets `tabWidth: 0` in `ec.config.mjs` itself. A tab then reaches the plugin unchanged, and a Makefile block copies its real tab rather than spaces. Set `expressiveCode.tabWidth` in the Starlight config, or `tabWidth` in `ec.config.mjs`, for Expressive Code's normal tab-to-space expansion instead.

## Related

- [Line states](https://ewels.github.io/starlight-codeblocks/features/line-states/): mark the line that has the indentation problem, with a message that explains it.
