# Bikeshed Documentation

## Living Standard, 19 December 2025

The processor automatically generates nearly all of a spec’s boilerplate, the text that is repeated nearly identically across all specs.

Generally, you won’t need to understand what’s going on here in order to use the processor—​it’ll just automatically do the right thing as long as your doctype (the Org, Group, and Status metadatas) is set correctly.

For help in creating new boilerplate files for your organization, see § 13.6 Creating New Boilerplate Files For Your Organization.

### 13.1. Rearranging and Excluding "Spec Metadata"

An important part of the boilerplate is the "spec-metadata" section. This will likely be at the top of your header boilerplate, as it contains a bunch of useful information about your spec.

Bikeshed generates a lot of these automatically for you, based on the metadata you provide and other things detected from your document, and you can supply "custom" items as specified near the end of § 4 Metadata. There’s a predefined ordering of these, but if you’d like a slightly different order, or to omit some of the automatically-generated items, you can use Metadata Include and Metadata Order to control this.

Metadata Include takes a comma-separated list of names and boolish values, where the names are the strings that show up in the `dt` in the spec metadata. Everything defaults to "on" currently, but you can explicitly turn them "off" to omit them from the spec metadata section.

Metadata Order instead controls the ordering of the spec metadata section. It’s a comma-separated list of names, where the names are the strings that show up in the `dt` in the spec metadata (same as Metadata Include). Two special "names" are recognized as well: the `*` name stands in for "all the standard keys that aren’t otherwise explicitly specified", while `!*` stands in for "all the custom keys that aren’t otherwise explicitly specified". (The default value is thus `Metadata Order: *, !*`, listing all the standard keys in the default order, followed by all the custom keys in the default order.)

If a name is specially pluralized when there are multiple entries (such as "Editor" vs "Editors"), use the singular version in either of these metadatas.

For example, `Metadata Include: This version off` will make Bikeshed omit the "This version" entry from the spec-metadata section, which is otherwise auto-generated by the ED metadata.

If you wanted to make sure that editors were listed before anything else, you could set `Metadata Order: Editor, *, !*`.

### 13.2. Conditional Inclusion

If you have multiple boilerplate files for publishing with different document statuses (like WD vs CR), but the only difference is that some sections are added/omitted between them, you can greatly simplify things by instead making a generic boilerplate for everything, and then adding/removing the variant bits with a conditional inclusion.

To mark an element as "conditionally included", put an `include-if` and/or `exclude-if` attribute on it, each of which takes a comma-separated list of inclusion conditions.

- If an element has `include-if`, it will included only if it matches at least one of the conditions.

- If an element has `exclude-if`, it will be included only if it matches none of the conditions.

- If an element has both, it will be included only if it passes the inclusion criteria for both.

An element that fails will be removed from the output entirely, along with its contents.

Inclusion conditions can be:

- A Status value, like `w3c/ED` or `LS`, so you can include/exclude text for certain publication statuses only.

- The existence of a custom text macro (defined by the Text Macro metadata), keyed by the text macro name, like `text macro: FOO` to match a `Text Macro: FOO here’s a custom text macro` metadata, so you can include text that uses a custom text macro only if that macro is defined.

  Note: For technical reasons, text macros are substituted before conditionals can be evaluated. If you’re conditioning an element on the existence of a text macro so you can use that macro only when it is defined, make sure the text macro is marked as optional when you use it (written as `[FOO?]` rather than just `[FOO]`), so it doesn’t trigger an "unknown text macro" error before throwing away the element anyway.

- The existence of a custom boilerplate element in the document, keyed by the boilerplate name, like `boilerplate: FOO` to match a `<div boilerplate=FOO>...</div>` element, so you can include text that pulls in a custom boilerplate only if that boilerplate is present.

Normally the conditional attributes go on an existing element in your page, which’ll show up in the output assuming it passes the tests. If there’s not a natural wrapper element, or adding such an element would mess with the semantics or styling of the page, you can instead wrap the conditional content in an `if-wrapper` element.

The `if-wrapper` element is a standard block-level element that can contain any flow markup. It must have one of the conditional attributes. If it fails the conditions, it and its contents are removed from the document, as normal; if it passes the conditions, it is still removed from the document, but its children are left behind in its place.

`if-wrapper` is still parsed as a standard unknown "custom" element by the HTML parser, and so can only appear in places where such elements are allowed; it cannot, for example, be used in the `head` of a document, or as a child of `table`.

It’s also considered "block level" by the Markdown parser. It can be used inline in text (tho you probably want to instead make the entire block conditional, for readability/editability), but it won’t parse as intended if it’s the very first content in a paragraph.

### 13.3. Boilerplate Sections

The location of the boilerplate sections are indicated by elements with `data-fill-with=''` attributes. If the elements contain anything, they’re emptied before being filled with the appropriate boilerplate. The valid `data-fill-with=''` values are:

- "table-of-contents" for the ToC

- "spec-metadata" for the `dl` of spec data that’s in the header of all of our specs

- "abstract" for the spec’s abstract

- "status" for the status section

- "logo" for the W3C logo

- "copyright" for the W3C copyright statement

- "warning" for the relevant spec warning, if one was indicated in the metadata.

- "references" for the bibliography refs

- "index" for the index of terms (all the `dfn` elements in the spec)

- "property-index" for the table summarizing all properties defined in the spec

- "idl-index"

- "cddl-index"

- "issues-index"

Additionally, "header" and "footer" boilerplate files are used to put content at the start and end of your document. Most or all of the above boilerplate sections should actually show up here, in the header and footer, rather than being manually specified in your source file.

#### 13.3.1. Default Boilerplate

Some sections listed above are generated by default; if you don’t put an explicitly `data-fill-with` container in your document, they’ll generate anyway (if they have anything to fill themselves with), appending themselves to the end of the `body`. These sections are:

- all of the indexes: "index", "property-index", "idl-index", "cddl-index" and "issues-index"

- "references"

Again, these will only auto-generate if there is something for them to do; if your spec doesn’t define any CSS properties, for example, the "property-index" boilerplate won’t generate. If you want to suppress their generation even when they do have something to do, use the Boilerplate metadata, like:

    <pre class="metadata">
    Boilerplate: idl-index no, property-index no
    </pre>

#### 13.3.2. Custom/Overriding Boilerplate

Sometimes a file-based boilerplate (see below) that is appropriate for most of the specs in your group isn’t quite right for your specific spec. Any boilerplate, file-based or Bikeshed-generated, can be overridden by custom text of your choosing. Just add an element to your source document with the content you’d like to show up in place of the offending boilerplate, and add a `boilerplate="foo"` attribute to the container, specifying which boilerplate section is being replaced.

Bikeshed will automatically remove that element from your document, and instead inject its contents in place of the boilerplate that it would normally provide.

The `boilerplate` attribute isn’t limited to just the predefined boilerplate section names; you can supply whatever section name you want, and if there’s a `data-fill-with` attribute somewhere in the document with the same name, the element’s contents will be moved there.

### 13.4. Table of Contents

The headings in the spec are automatically numbered, and a table of contents automatically generated.

Any heading `h2` to `h6` (that is, skipping only the document-titling `h1`) is automatically numbered by having a `<span class='secno'>...</span>` prepended to its contents. You can avoid this behavior for a heading and all of its subsequent subheadings by adding `class="no-num"` to the heading.

Similarly, a ToC is generated to match. Headings and their subheadings can be omitted from the ToC by adding `class="no-toc"` to them.

Headings also automatically gain a self-link pointing to themselves, to enable people to easily link to sections without having to return to the ToC.

### 13.5. File-based Includes

Several of the data-fill-with values (those that are static, rather than generated from in-document data) actually come from sets of .include files in the `bikeshed-data` project.

The base files are simply named "foo.include", where "foo" is the name of the data-fill-with value. They can be specialized, however, to particular working groups, and to particular document statuses.

Putting the boilerplate in a folder named after the group, like `csswg/header.include`, specializes it for that Group. Adding a "-STATUS" to the filename specializes it for the Status. These can be used together, like "csswg/status-CR.include". Orgs can also have default boilerplates, which are stored in the same way, and will be used if the Group doesn’t have a specific boilerplate.

The processor will first look for the "GROUP/foo-STATUS.include" file, failing over to "GROUP/foo.include", then "ORG/foo-STATUS.include", then "ORG/foo.include", then "foo-STATUS.include", and finally "foo.include".

### 13.6. Creating New Boilerplate Files For Your Organization

Bikeshed’s default boilerplate generates a functional and reasonably attractive spec, but if your group has specific style requirements, you can produce your own boilerplate files. This section is a basic guide to developing these files.

The most important part of the boilerplate is the `header.include` and `footer.include` file. These define the parts of the spec HTML that precede and follow your actual spec content, so the source file can contain only the actual spec text, and all specs in the same organization can look similar.

Here is a basic example `header.include` file:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>[TITLE]</title>
      <style>
      ...
      </style>
    </head>
    <body class="h-entry">
    <div class="head">
      <p data-fill-with="logo"></p>
      <h1 id="title" class="p-name no-ref">[TITLE]</h1>
      <h2 id="subtitle" class="no-num no-toc no-ref">[LONGSTATUS],
        <span class="dt-updated"><span class="value-title" title="[CDATE]">[DATE]</span>
      </h2>
      <div data-fill-with="spec-metadata"></div>
      <div data-fill-with="warning"></div>
      <p class='copyright' data-fill-with='copyright'></p>
      <hr title="Separator for header">
    </div>

    <div class="p-summary" data-fill-with="abstract"></div>
    <div data-fill-with="at-risk"></div>

    <nav data-fill-with="table-of-contents" id="toc"></nav>
    <main>

This uses several of Bikeshed’s boilerplating features:

- Text replacement, via the `[FOO]` macros. These macros are prepopulated by Bikeshed, either from metadata in the spec (like `[TITLE]`) or from environment data (like `[DATE]`). The full list of text macros can be found at § 5.3 Text Macros.

- Boilerplate pieces, via empty container elements with `data-fill-with` attributes. The list of Bikeshed-provided `data-fill-with` values can be found at § 13.3 Boilerplate Sections. At minimum, you want to include the `abstract`, `table-of-contents`, and `spec-metadata` sections here; they’re all most useful at the top of the document.

## Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.