LEARNING OBJECTIVES โต
- Understand how Prettier's AST printer formats HTML deterministically to eliminate code review formatting disputes.
- Master CSS whitespace sensitivity rules and how accidental newlines alter inline element rendering.
- Configure
.prettierrcfor HTML withhtmlWhitespaceSensitivity,bracketSameLine, andsingleAttributePerLine. - Prevent unwanted whitespace reflows using
<!-- prettier-ignore -->and<!-- prettier-ignore-attribute -->. - Integrate Prettier into command-line scripts and CI checks (
prettier --check).
๐ The Mental Model & Story (Intuitive Foundation)
In programming languages like JavaScript or Python, adding extra whitespace, tabs, or newlines between tokens does not change the execution output of your code. You can format code however you want without altering logic.
HTML is fundamentally different because in standard CSS layout, whitespace is part of the rendered content.
Under default CSS rules (white-space: normal), a sequence of spaces, tabs, or newlines between inline elements (like <span> or <a>) collapses into a single rendered space character. If a formatter carelessly inserts a line break between two inline tags, it can accidentally inject unwanted visual spaces into your user interface:
Source Code A (No space):
<span>$</span><span>99</span> ===> Browser renders: "$99"
Source Code B (Newline inserted by naive formatter):
<span>$</span>
<span>99</span> ===> Browser renders: "$ 99" (Unwanted gap!)
+-------------------------------------------------------------------------------+
| PRETTIER HTML ENGINE |
+-------------------------------------------------------------------------------+
| 1. HTML AST Parser -> Understands tag boundaries & attributes. |
| 2. CSS Display Classifier -> Knows if an element is BLOCK or INLINE. |
| 3. Whitespace Hugger -> Tightly wraps inline tags (> at start of line) |
| to preserve exact visual pixel rendering. |
+-------------------------------------------------------------------------------+
Prettier is an opinionated, spec-aware formatter that understands the exact CSS display characteristics of every standard HTML tag, ensuring your markup looks beautiful in the editor without introducing visual rendering bugs.
Technical Deep Dive & Specifications
The .prettierrc.json Configuration for HTML
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"bracketSameLine": false,
"singleAttributePerLine": false,
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}
Deep Dive: htmlWhitespaceSensitivity Options
Prettier provides three modes for handling whitespace in HTML:
| Setting Value | Behavior & Formatting Mechanics | When to Use |
|---|---|---|
"css" (Default) |
Follows default CSS display values. Block elements (<div>, <p>) get clean line breaks. Inline elements (<span>, <a>, <b>) are formatted with "hugging" brackets (> on next line) if wrapping is needed to prevent phantom spaces. |
Recommended for 99% of web projects. |
"strict" |
Treats all whitespace across all elements as significant. Produces very safe but visually jagged markup with strict bracket placement. | Use when working with custom CSS white-space overrides. |
"ignore" |
Treats all whitespace as insignificant and formats all tags with standard block indentation. | โ ๏ธ Dangerous: Can introduce unintended spaces between inline spans and text. |
Understanding "Bracket Hugging" in Inline Formatting
When an inline element has multiple attributes and exceeds printWidth, Prettier wraps the opening tag's closing bracket (>) directly against the child text:
<!-- Formatted by Prettier with htmlWhitespaceSensitivity: "css" -->
<a
href="https://example.com/checkout"
class="btn-primary"
target="_blank"
rel="noopener noreferrer"
>Click Here</a
>
Notice that >Click Here</a has no leading or trailing whitespace. This guarantees that no extra space character is injected before or after the anchor tag.
Configuration Options Breakdown
1. singleAttributePerLine
Forces every HTML attribute onto its own line when set to true:
<!-- singleAttributePerLine: true -->
<button
type="submit"
id="checkout-button"
class="btn btn-primary"
disabled>
Submit Order
</button>
2. bracketSameLine
Controls whether the closing > of a multiline HTML element is placed at the end of the last attribute line instead of on a new line:
<!-- bracketSameLine: true -->
<input
type="text"
name="username"
id="user-field"
class="form-control" />
Prettier Ignore Pragmas
To exempt specific markup blocks (e.g. ASCII art, preformatted code, or sensitive inline micro-layouts) from being reflowed:
<!-- prettier-ignore -->
<div class="do-not-touch" id="custom-layout" >
<span>Custom</span><span>Alignment</span>
</div>
<!-- prettier-ignore-attribute (ignores specific attribute formatting) -->
<!-- prettier-ignore-attribute (data-tracking) -->
<div data-tracking='{"event": "click", "id": 102}'>Content</div>
๐ป Interactive Code Playground
Starter Code (Before Prettier Formatting)
Line-by-Line Code Breakdown
- Lines 1โ3: Dense, unformatted one-liner tags.
- Lines 5โ7:
<span class="currency-symbol">$</span><span class="amount">199</span><span class="decimal">.99</span>are inline elements placed directly adjacent without spaces so that "$199.99" renders without gaps. - Lines 9โ10: An
<input>with 6 attributes that exceeds standard 80-character line lengths.
Formatted Output (After Prettier Execution)
Expected Browser Render Output
Store Checkout
$199.99 <-- Rendered seamlessly without gaps between $, 199, and .99!
Email: [ [email protected] ]
[ Complete Purchase ]๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Resolve Whitespace Collapsing Bugs
Instructions:
- You have inherited an e-commerce price tag component where a naive code formatter introduced unwanted spaces, causing the price to render as
$ 49 . 95 USDinstead of$49.95 USD. - Reconstruct the markup so that:
- Currency symbol
$, dollar integer49, and cent decimals.95touch with zero whitespace. - A single standard space appears before
USD. - Long attributes on the buy button wrap cleanly across multiple lines.
- Use
<!-- prettier-ignore -->on a specialized pre-formatted breadcrumb trail.
- Currency symbol
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Setting
"htmlWhitespaceSensitivity": "ignore"Globally: While it makes formatted HTML look like clean nested blocks in the code editor, it introduces phantom whitespace bugs in inline text, badges, and pricing tags. Keep it set to"css". - Mixing Tabs and Spaces in Editor Config: Ensure
.editorconfigmatches.prettierrc(indent_size = 2,indent_style = space) to prevent fighting between your editor's auto-indent and Prettier. - Formatting Minified Output Directories: Always add
dist/,build/, andnode_modules/to your.prettierignorefile so Prettier does not re-expand production bundles.
๐ก Pro Tips
- Enable Format-on-Save in VS Code: Configure
"editor.formatOnSave": trueand"editor.defaultFormatter": "esbenp.prettier-vscode"in.vscode/settings.jsonfor zero-friction formatting during development. - Run
prettier --checkin CI Quality Gates: Runnpx prettier --check "src/**/*.html"in continuous integration. It exits with code1if any file is unformatted, guaranteeing 100% repository consistency.
๐ Key Takeaways
- Prettier is an opinionated AST-based code formatter that enforces deterministic layout across HTML, CSS, and JS.
- In CSS
white-space: normal, newlines between inline elements collapse into visible space characters. - Prettier's
htmlWhitespaceSensitivity: "css"prevents visual UI bugs by using bracket-hugging formatting on inline elements. - Project formatting rules are declared centrally in a root
.prettierrcor.prettierrc.json. - Use
<!-- prettier-ignore -->to exempt specific pre-formatted HTML elements from modification. - --