Skip to content

HTML

Files ending in .html and .htm are formatted by the HTML pack (rainbow_fmt.languages.html, grammar tree-sitter-html).

<div class="card"><div class="card-body"><h2>Title</h2><p>Some <b>bold</b> text that goes on for a while, long enough to wrap.</p></div></div>

becomes

<div class="card">
    <div class="card-body">
        <h2>Title</h2>
        <p>
            Some <b>bold</b> text that goes on for a while, long enough to
            wrap.
        </p>
    </div>
</div>

What changes and what does not

The pack changes layout only. Tag and attribute names, attribute values and their quotes, entities, comments and the doctype are printed as written; nothing is lower-cased, no quotes are added. Void elements are written <br> (void_elements).

  • Block elements (div, p, ul, li, section, table, head, body … everything whose default CSS display is not inline) go one per line, indented inside their parent. A block element whose content fits on its line stays on one line (<li><a href="/">Home</a></li>), except structural elements (html, head, body, lists, tables, select), which always break, and an element with a child element that holds more than text, as in Prettier.
  • Inline elements and text are filled to the width: words are re-wrapped, and a line breaks only where the source had whitespace, so what the browser renders does not change. text<b>bold</b> stays joined; <span> a span </span> keeps its spaces. Where nothing can break, the line stays long. Unknown and custom elements are inline.
  • Attributes stay on the tag's line when they fit; otherwise they go one per line, indented, with the > on a line of its own:
<input
    type="text"
    name="very_long_name"
    placeholder="Something long here"
    required
>
  • <pre> and <textarea> keep their content exactly; their tags are formatted.
  • <style> content is formatted by the CSS pack; <script> content by the JavaScript pack (no type, module, text/javascript), the TypeScript pack (lang="ts") or the JSON pack (application/json, application/ld+json, importmap, speculationrules). Each follows its own [language.X] options, as a file of that language at the same path would. Content of any other type, or that does not parse, is kept as written.
  • Comments on a line of their own stay on their own line; comments inside text flow with it.
  • Blank lines between children are kept, at most core.max_blank_lines (default 1).

Inline directives (<!-- rainbow: off --> … <!-- rainbow: on -->, <!-- rainbow: skip-next -->, <!-- rainbow: set … -->, and Prettier's <!-- prettier-ignore -->) keep children of an element as written or change options for one of them (configuration.md).

Options

Key Values Default
language.html.whitespace_sensitivity "css": inline elements and text are whitespace-sensitive, block elements are not (Prettier's default); "strict": every element is; "ignore": none is, so a line may break anywhere, also where the source had no whitespace "css"
language.html.bracket_same_line true: the > of a tag broken over several lines stays on the last attribute's line false
language.html.void_elements "no_slash": <br>, <img …>; "slash": <br />, <img … />; "preserve": as written. Only the void elements (area, base, br, col, embed, hr, img, input, link, meta, param, source, track, wbr); the two spellings parse the same "no_slash"

Differences from Prettier

  • Indentation is core.indent_size (4), the width core.max_width.
  • Where Prettier breaks inside a tag (<b\n>) to break a line without adding whitespace, rainbow-fmt leaves the line long.
  • Attribute values, quotes, self-closing slashes and tag-name case are as written; Prettier normalizes them.
  • Comments are never re-indented inside.