<label>

Form Family Master Tag Blueprint

The HTML <label> element represents a caption for a form control. In json-to-dom, it is a focused, semantic element strictly bound to text captions and attribute association via for.

allowsTextContent: true
allowedAttributes: ["for", "class", "id"]
Best Practice: Pure Text Caption

1. The Schema Contract (tags.json)

Single Source of Truth

Every <label> compiled by json-to-dom v7 is checked against this contract before touching the DOM:

"label": {
    "allowsTextContent": true,
    "allowsChildren": true,
    "allowedAttributes": [
        "for",
        "class",
        "id"
    ]
}
allowsTextContent

true: Text strings represent the visual caption.

allowedAttributes

Strictly for, class, id. All other attributes are purged.

UI Role

Dedicated to captioning. Does not contain input controls.

2. What is RIGHT (Valid Patterns)

4 Valid Types

In json-to-dom, these patterns represent correct, optimal declarations for the <label> element:

Right #1 Semantic Form Caption (Standard) Most Common

A clean text caption linked to an input control via the for attribute matching the input's id.

{
  "tagName": "label",
  "textContent": "Customer Email Address",
  "attributes": {
    "for": "user-email"
  }
}
Compiled DOM Output:
Right #2 Styled Form Label (Bootstrap Utilities) UI Styling

Applying styling classes (e.g. form-label, fw-semibold, text-primary) via attributes.class.

{
  "tagName": "label",
  "textContent": "Mobile Phone Number",
  "attributes": {
    "for": "cust-mobile",
    "class": "form-label fw-semibold text-primary"
  }
}
Compiled DOM Output:
Right #3 Fieldset or Subtitle Label Grouping

A standalone uppercase or muted caption used as a group header or fieldset descriptor.

{
  "tagName": "label",
  "textContent": "BILLING AND SHIPPING ADDRESS",
  "attributes": {
    "class": "text-uppercase text-muted small fw-bold tracking-wide"
  }
}
Compiled DOM Output:
Right #4 Label with Unique Element ID Testing & Hooks

Providing an explicit id for automated testing (Playwright, Cypress) or aria-labelledby bindings.

{
  "tagName": "label",
  "textContent": "Tax Identification (GSTIN)",
  "attributes": {
    "id": "lbl-tax-id",
    "for": "input-tax-id",
    "class": "form-label fw-medium text-dark"
  }
}
Compiled DOM Output:

3. What is WRONG (Anti-Patterns & Violations)

4 Common Violations

These anti-patterns violate HTML grammar or the tags.json schema contract. In v7, the compiler will actively filter these attributes or flag validation errors:

Wrong #1 Leaking Input Attributes onto Label Attribute Violation

Attempting to pass placeholder, type, or value to a <label>. Labels are captions, not inputs.

{
  "tagName": "label",
  "textContent": "Full Name",
  "attributes": {
    "for": "user-fullname",
    "placeholder": "Enter full name", // ❌ WRONG: Belongs to <input>
    "type": "text",                    // ❌ WRONG: Belongs to <input>
    "value": "John Doe"                // ❌ WRONG: Belongs to <input>
  }
}
Compiler Action: filterAttributes.js purges placeholder, type, and value. The real DOM node only receives <label for="user-fullname">Full Name</label>.
Wrong #2 Table Geometry Attributes on Label Grid Violation

Passing colspan, rowspan, or border on a label.

{
  "tagName": "label",
  "textContent": "Voucher Total",
  "attributes": {
    "colspan": 2, // ❌ WRONG: Belongs to <td> or <th>
    "rowspan": 1  // ❌ WRONG: Belongs to <td> or <th>
  }
}
Compiler Action: Rejected by tags.json schema validation. Stripped completely from DOM.
Wrong #3 State Attributes (disabled, checked, readonly) State Violation

Labels do not have interactive state. State belongs to the input element.

{
  "tagName": "label",
  "textContent": "Agree to Terms",
  "attributes": {
    "for": "agree-chk",
    "disabled": "true", // ❌ WRONG: Label cannot be disabled
    "checked": "true"   // ❌ WRONG: Label cannot be checked
  }
}
Compiler Action: State attributes are stripped. If the form control is disabled, apply disabled styling via CSS classes on the label (e.g. text-muted opacity-50).
Wrong #4 Embedding Inputs as Children of Label Architecture Anti-Pattern

Wrapping <input> inside <label> children creates deeply coupled, non-reusable trees.

// ❌ ANTI-PATTERN in json-to-dom:
{
  "tagName": "label",
  "children": [
    { "tagName": "span", "textContent": "Name: " },
    { "tagName": "input", "attributes": { "type": "text" } } // ❌ Non-composable
  ]
}
Best Practice: Keep <label> and <input> as separate siblings in a composite group, bound via for="id". This allows independent styling, validation, and layout flexibility.

4. Attribute Reference Matrix

Allowed Attributes (tags.json)
Attribute Type Purpose Example
for string References the id of the associated form input. Critical for accessibility. for: "user-name"
class string CSS styling classes (Bootstrap, Tailwind, custom utility classes). class: "form-label fw-bold"
id string Unique DOM identifier for test hooks and ARIA labelling. id: "lbl-username"
Common Forbidden Attributes
Forbidden Belongs To Why It Is Disallowed on <label>
placeholder <input>, <textarea> Labels are permanent visual titles, not ghost input prompts.
type <input>, <button> Labels have no data type; they render text content.
value <input>, <option> Labels do not carry form submission state.
disabled <input>, <button> Labels cannot be disabled. Use CSS (e.g. opacity-50) instead.
colspan, rowspan <td>, <th> Table layout attributes cannot be applied to labels.

5. Classes & Visual Styling (Pure Labels)

Inspect how different CSS utility classes shape the appearance of the <label> alone:

Standard Form Label
class: "form-label fw-semibold text-dark"
Dense Uppercase Subtitle
class: "text-uppercase text-muted small fw-bold"
Badge / Status Label
class: "badge bg-primary px-2.5 py-1.5"
Dark Mode Label
class: "text-light fw-medium small"
Live v7 Compiler
dist/v7/min.js
Rendered DOM Element Live Target
#render-output