๐Ÿ› ๏ธ Chapter 93: HTML Tooling, Linting & Quality Assurance

Code Formatting with Prettier

Deterministic HTML code formatting, CSS whitespace collapsing mechanics, inline vs block tag wrapping, `.prettierrc` configurations, and format-ignore pragmas.

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 .prettierrc for HTML with htmlWhitespaceSensitivity, bracketSameLine, and singleAttributePerLine.
  • Prevent unwanted whitespace reflows using <!-- prettier-ignore --> and <!-- prettier-ignore-attribute -->.
  • Integrate Prettier into command-line scripts and CI checks (prettier --check).
๐ŸŽฌ INTERACTIVE VISUAL PIPELINE Core Architecture Simulation
๐ŸŒ
1. Input
Directives & Tags
โš™๏ธ
2. Parse
Tokenizer & AST
๐ŸŒณ
3. Layout
Box Model & Flow
๐ŸŽจ
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.

๐Ÿ“– 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>

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL example.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...

๐Ÿ’ป 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


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL playground.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...
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:

  1. 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 USD instead of $49.95 USD.
  2. Reconstruct the markup so that:
    • Currency symbol $, dollar integer 49, and cent decimals .95 touch 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.

๐Ÿ Starter Code Sandbox

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
STARTER CODE SANDBOX exercise.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...

โš ๏ธ Common Pitfalls

  1. 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".
  2. Mixing Tabs and Spaces in Editor Config: Ensure .editorconfig matches .prettierrc (indent_size = 2, indent_style = space) to prevent fighting between your editor's auto-indent and Prettier.
  3. Formatting Minified Output Directories: Always add dist/, build/, and node_modules/ to your .prettierignore file so Prettier does not re-expand production bundles.

๐Ÿ’ก Pro Tips

  1. Enable Format-on-Save in VS Code: Configure "editor.formatOnSave": true and "editor.defaultFormatter": "esbenp.prettier-vscode" in .vscode/settings.json for zero-friction formatting during development.
  2. Run prettier --check in CI Quality Gates: Run npx prettier --check "src/**/*.html" in continuous integration. It exits with code 1 if 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 .prettierrc or .prettierrc.json.
  • Use <!-- prettier-ignore --> to exempt specific pre-formatted HTML elements from modification.
  • --
โญ LEARN: HTML ๐ŸŒŸ โš”๏ธ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

Why does Prettier sometimes place the closing bracket > of an inline element on the next line touching the inner text (e.g. >Click</a)?

Question 1 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 2 / 3

What happens when "htmlWhitespaceSensitivity" is set to "ignore" in .prettierrc?

Question 2 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 3 / 3

Which command should be executed in a Continuous Integration (CI) pipeline to verify that all HTML files are properly formatted without modifying them?

Question 3 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP