Skip to main content

Content

Reboot

Reboot, a small set of element-specific CSS changes at the top of felt.css, provides a simple, consistent baseline to build upon.

View page source on GitHub

Approach#

Like Bootstrap's Reboot, felt-css gives many HTML elements somewhat opinionated styles using only element selectors. Additional styling is done only with classes. For example, <table>s get a simpler baseline, and .table, .table-bordered, and more come on top.

felt-css's Reboot is smaller than Bootstrap's and doesn't build on Normalize. It lives in two cascade layers at the top of felt.css: reset (a handful of resets) and base (page defaults and prose). Because every later layer and all un-layered CSS win over them, your own styles override Reboot without any specificity fights.

Guidelines it follows:

  • Avoid margin-top. Vertical margins can collapse, yielding unexpected results.
  • Block elements use rems for their margins, for easier scaling.
  • Keep declarations of font-related properties to a minimum, using inherit whenever possible.
  • Colours come from custom properties on :root (--text, --body-bg, --link…), so everything follows the look and the color mode.

Page defaults#

The <html> and <body> elements are updated to provide better page-wide defaults. More specifically:

  • The box-sizing is globally set on every element—including *::before and *::after, to border-box.
  • The <body> loses its default margin.
  • No base font-size is declared on the <html> or the <body>; the browser's default (typically 16px) applies, so visitors can change it.
  • The <body> sets a global font-family (--font), line-height: 1.5, color (--text) and font smoothing.
  • The <body> also has a declared background: --body-bg, a very light grey in the clean look and cream felt in the felt look (charcoal in dark mode). Cards and other surfaces sit on it in --surface.
  • <img> and <svg> get max-width: 100% and vertical-align: middle, so images never overflow their container, even without .img-fluid.
  • Every focusable element gets a visible focus ring on :focus-visible: a 3px outline in --focus (a translucent primary), 2px away from the element.

Native font stack#

felt-css uses a "native font stack" or "system font stack" for optimum text rendering on every device and OS:

--font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-heading: var(--font);
--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

Override these custom properties on :root to change the typeface of the body, the headings or the code, everywhere at once.

Headings#

All heading elements—<h1>—<h6> have their margin-top removed, margin-bottom: .5rem set, line-height tightened to 1.2 and a bold weight. They use --font-heading and inherit their color. See Typography for the sizes.

Paragraphs#

All <p> elements have their margin-top removed and margin-bottom: 1rem set for easy spacing.

This is an example paragraph.

<p>This is an example paragraph.</p>

Links have a default color (--link) and the browser's underline. They don't change based on whether someone :visited the link. On keyboard focus they show the global focus ring.

<a href="#">This is an example link</a>

Link color is mixed with transparency through the --link-opacity custom property (Bootstrap's --bs-link-opacity), so you can change the opacity of a link's colour:

<a href="#" style="--link-opacity: .5">This is an example link</a>

Placeholder links—those without an href—keep the link colour but, as in every browser, lose the underline and the pointer cursor. felt-css doesn't reset their colour.

<a>This is a placeholder link</a>

Horizontal rules#

The <hr> element has been simplified. Similar to browser defaults, <hr>s are styled via border-top, have a default opacity: .25, and automatically inherit their border-color via color, including when color is set via the parent.





<hr>

<div class="text-success">
  <hr>
</div>

<hr class="border border-danger border-2 opacity-50">
<hr class="border border-primary border-3 opacity-75">

In the felt look, an <hr> is a row of running stitches instead of a line, in a darker tone of the felt underneath, so a color set on it or its parent doesn't tint it. With border utilities you get a plain coloured line, as in the clean look.

Lists#

All lists—<ul>, <ol>, and <dl>—have their margin-top removed and a margin-bottom: 1rem. Nested lists have no margin-bottom. The padding-left on <ul> and <ol> is set to 2rem.

  • All lists have their top margin removed
  • And their bottom margin normalized
  • Nested lists have no bottom margin
    • This way they have a more even appearance
    • Particularly when followed by more list items
  • The left padding has also been reset
  1. Here's an ordered list
  2. With a few list items
  3. It has the same overall look
  4. As the previous unordered list
<ul>
  <li>All lists have their top margin removed</li>
  <li>And their bottom margin normalized</li>
  <li>Nested lists have no bottom margin
    <ul>
      <li>This way they have a more even appearance</li>
      <li>Particularly when followed by more list items</li>
    </ul>
  </li>
  <li>The left padding has also been reset</li>
</ul>

<ol>
  <li>Here's an ordered list</li>
  <li>With a few list items</li>
  <li>It has the same overall look</li>
  <li>As the previous unordered list</li>
</ol>

For simpler styling, clear hierarchy, and better spacing, description lists have updated margins. <dd>s reset margin-left to 0 and add margin-bottom: .5rem. <dt>s are bolded.

Description lists
A description list is perfect for defining terms.
Term
Definition for the term.
A second definition for the same term.
Another term
Definition for this other term.
<dl>
  <dt>Description lists</dt>
  <dd>A description list is perfect for defining terms.</dd>
  <dt>Term</dt>
  <dd>Definition for the term.</dd>
  <dd>A second definition for the same term.</dd>
  <dt>Another term</dt>
  <dd>Definition for this other term.</dd>
</dl>

Inline code#

Wrap inline snippets of code with <code>. Be sure to escape HTML angle brackets. Inline code is set in --font-mono at .875em and coloured with --danger-emphasis.

For example, <section> should be wrapped as inline.
For example, <code>&lt;section&gt;</code> should be wrapped as inline.

Code blocks#

Use <pre>s for multiple lines of code. Once again, be sure to escape any angle brackets in the code for proper rendering. The <pre> element is reset to remove its margin-top and use rem units for its margin-bottom. Unlike Bootstrap's, it is a padded, scrollable box with a sunken background, a border and rounded corners.

<p>Sample text here...</p>
<p>And another line of sample text here...</p>
<pre><code>&lt;p&gt;Sample text here...&lt;/p&gt;
&lt;p&gt;And another line of sample text here...&lt;/p&gt;
</code></pre>

Variables#

For indicating variables use the <var> tag.

y = mx + b
<var>y</var> = <var>m</var><var>x</var> + <var>b</var>

User input#

Use the <kbd> to indicate input that is typically entered via keyboard. It's a small dark key cap; nested <kbd>s are bold.

To switch directories, type cd followed by the name of the directory.
To edit settings, press Ctrl + ,
To switch directories, type <kbd>cd</kbd> followed by the name of the directory.<br>
To edit settings, press <kbd><kbd>Ctrl</kbd> + <kbd>,</kbd></kbd>

Sample output#

For indicating sample output from a program use the <samp> tag.

This text is meant to be treated as sample output from a computer program.
<samp>This text is meant to be treated as sample output from a computer program.</samp>

Tables#

Tables are slightly adjusted to style <caption>s (below the table, muted, left-aligned), collapse borders, and ensure consistent text-align throughout. Additional changes for borders, padding, and more come with the .table class.

This is an example table, and this is its caption to describe the contents.
Table heading Table heading Table heading Table heading
Table cell Table cell Table cell Table cell
Table cell Table cell Table cell Table cell
Table cell Table cell Table cell Table cell
<table>
  <caption>
    This is an example table, and this is its caption to describe the contents.
  </caption>
  <thead>
    <tr>
      <th>Table heading</th>
      <th>Table heading</th>
      <th>Table heading</th>
      <th>Table heading</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
  </tbody>
</table>

Forms#

Various form elements have been rebooted for simpler base styles. Here are some of the most notable changes:

  • <fieldset>s have no borders, padding, or margin so they can be easily used as wrappers for individual inputs or groups of inputs.
  • <legend>s, like fieldsets, have also been restyled to be displayed as a heading of sorts.
  • <label>s are set to display: inline-block to allow margin to be applied.
  • <input>s, <select>s, <textarea>s, and <button>s have their margin removed and inherit font and color.
  • <textarea>s are modified to only be resizable vertically as horizontal resizing often "breaks" page layout.
  • <button>s have cursor: pointer.

These changes, and more, are demonstrated below.

Example legend


<form>
  <fieldset>
    <legend>Example legend</legend>
    <p>
      <label for="rebootInput">Example input</label>
      <input type="text" id="rebootInput" placeholder="Example input">
    </p>
    <p>
      <label for="rebootEmail">Example email</label>
      <input type="email" id="rebootEmail" placeholder="test@example.com">
    </p>
    <p>
      <label for="rebootSelect">Example select</label>
      <select id="rebootSelect">
        <option value="">Choose...</option>
        <optgroup label="Option group 1">
          <option value="">Option 1</option>
          <option value="">Option 2</option>
          <option value="">Option 3</option>
        </optgroup>
        <optgroup label="Option group 2">
          <option value="">Option 4</option>
          <option value="">Option 5</option>
          <option value="">Option 6</option>
        </optgroup>
      </select>
    </p>
    <p>
      <label>
        <input type="checkbox" value="">
        Check this checkbox
      </label>
    </p>
    <p>
      <label>
        <input type="radio" name="rebootRadios" value="option1" checked>
        Option one is this and that
      </label>
      <br>
      <label>
        <input type="radio" name="rebootRadios" value="option2">
        Option two is something else that's also super long to demonstrate the wrapping of these fancy form controls.
      </label>
    </p>
    <p>
      <label for="rebootTextarea">Example textarea</label>
      <textarea id="rebootTextarea" rows="3"></textarea>
    </p>
    <p>
      <label for="rebootDate">Example date</label>
      <input type="date" id="rebootDate">
    </p>
    <p>
      <label for="rebootRange">Example range</label>
      <input type="range" id="rebootRange" min="0" max="10">
    </p>
    <p>
      <button type="submit">Button submit</button>
      <input type="submit" value="Input submit button">
      <input type="button" value="Input button">
    </p>
  </fieldset>
</form>

Address#

The <address> element is updated to reset the browser default font-style from italic to normal, and margin-bottom: 1rem has been added. <address>s are for presenting contact information.

ACME Corporation
1123 Fictional St,
San Francisco, CA 94103
P: (123) 456-7890
Full Name
first.last@example.com
<address>
  <strong>ACME Corporation</strong><br>
  1123 Fictional St,<br>
  San Francisco, CA 94103<br>
  <abbr title="Phone">P:</abbr> (123) 456-7890
</address>

<address class="mb-0">
  <strong>Full Name</strong><br>
  <a href="mailto:first.last@example.com">first.last@example.com</a>
</address>

Blockquote#

The default margin on blockquotes is 1em 40px, so we reset that to 0 0 1rem for something more consistent with other elements.

A well-known quote, contained in a blockquote element.
<blockquote>A well-known quote, contained in a blockquote element.</blockquote>

Inline elements#

The <abbr> element receives basic styling to make it stand out amongst paragraph text: a dotted underline and a help cursor. <mark> gets a soft mustard highlight, <small> is .875em, and <sub>/<sup> no longer change the line height.

The HTML abbreviation element, some marked text, H2O and E = mc2.
The <abbr title="HyperText Markup Language">HTML</abbr> abbreviation element, some <mark>marked text</mark>, H<sub>2</sub>O and E = mc<sup>2</sup>.

Summary#

felt-css doesn't restyle a bare <summary>; it keeps the browser's default cursor and marker. For a styled disclosure, use <details class="accordion-item"> (see the accordion).

HTML5 [hidden] attribute#

HTML5 adds a new global attribute named [hidden], which is styled as display: none by default. felt-css improves upon this default by making [hidden] { display: none !important; } to help prevent its display from getting accidentally overridden.

<input type="text" hidden>

To merely toggle the visibility of an element, meaning its display is not modified and the element can still affect the flow of the document, use the .invisible class instead.