Skip to main content

Codebase 6 Typography


Font stacks

A few native font stacks are set in the root-vars.css file.

:root {
  --t-sans: ui-sans-serif, sans-serif;
  --t-serif: ui-serif, serif;
  --t-mono: ui-monospace, monospace;

  --t-base-ff: var(--t-sans);
  --hd-ff: inherit; /* headings */
  --t-form-ff: inherit;
}

Everything here is an example, a place to start. Your own --base and --prose don’t need to be both sans-serif and serif.

Font stack usage in Codebase:

  • The --t-sans font stack is set in the <body> tag (via --t-base-ff) and is inherited on forms (via --t-form-ff) and headings (via --hd-ff), so that you can override and set a different typefaces if you prefer.
  • The --t-serif font stack is only available via the t-prose utility class. But you can employ it directly on your <article> tag, or wherever you need.
  • The --t-mono font stack is available via the <code>, <kbd>, and <samp> HTML tags, and in the t-mono utility class.

Base font size

The default font size in Codebase is 100% for small viewports. This sets the value of 1rem—that is 16px on most browsers (in 2025).

:root {
  --t-base-fs: 100%;
}

Typographic block elements

All typographic block elements have zero top margin, and a bottom margin of var(--t-mb) (which is 1rem by default). This includes paragraphs, headings, blockquotes, lists, and definition lists.

Headings

Heading sizes are set using the classic typographic scale (but set in em, not pt or px). The font size for h6 and utility class .h6 is not increased by this scale (remains the same as the base font size).

Example headings (using heading-size utility classes):

Heading h1

Heading h2

Heading h3

Heading h4

Heading h5

Heading h6

:root {
  --h1: 2.5em;
  --h2: 1.875em;
  --h3: 1.5em;
  --h4: 1.25em;
  --h5: 1.125em;
  --h6: 1em;
}

All headings <h1> to <h6> and matching heading size utility classes h1 to h6 have:

  • Headings font sizes set in the variables file (see above).
  • Heading-size utility classes h1 to h6 are available for use on any element, e.g. <div class="h1">. These utilities only affect font-size. They do not include margin or font-weight styling.
  • Headings font family set using --h-ff: inherit. This has been done so that you can use the variable to override it — your headings don’t need to be the same typeface as your paragraphs.
  • Headings font weight is set using --h-fw: var(--t-semibold) — which you can also override.
  • Headings line heights set using the formula 1em + 0.5rem.
  • Headings have their bottom margin set the same as for paragraphs, var(t--mb).
:root {
  --h-ff: inherit; /* headings font-family */
  --h-fw: var(--t-semibold);
  --h-lh: calc(1em + 0.5rem);
  --h-mb: var(--t-mb);
}

Tip: In some contexts (e.g. in card components) you may not want any built-in spacing for typographic block elements. Then, you can remove margins by using the mb-0 utility class.

Block quotes

Codebase styles <blockquote> tags with some inline (x-axis) padding, to give the effect of indentation. This inline padding is set using the responsive spacing variable --s-4 so that it increases if there is more available width.

Otherwise, blockquotes have the same as paragraph styling.

Lorem ipsum dolor sit amet, adipiscing honestatis ius ut, nisl consulatu pro in. Imperdiet evertitur no usu, his te suavitate salutatus. Nullam ridens deterruisset an duo. Cum harum insolens ei, cum probo placerat praesent et.

Lists

In Codebase ordered <ol> and unordered <ul> have a small amount of left padding. But Codebase separates list items <li> to make them more obvious by setting a small top margin between list items (smaller than the top margin between paragraphs), and the same amount above nested <ol> and <ul>. This makes ordered and unordered lists have an even spacing like this:

  1. Ordered item one
  2. Ordered item two
    1. Ordered item two child one
    2. Ordered item two child two
  3. Ordered item three
<ol>
  <li>Ordered item one</li>
  <li>Ordered item two
    <ol>
      <li>Ordered item two child one</li>
      <li>Ordered item two child two</li>
    </ol>
  </li>
  <li>Ordered item three</li>
</ol>
  • Unordered item
  • Unordered item
    • Unordered item child
    • Unordered item child
  • Unordered item
<ul>
  <li>Unordered item</li>
  <li>Unordered item
    <ul>
      <li>Unordered item child</li>
      <li>Unordered item child</li>
    </ul>
  </li>
  <li>Unordered item</li>
</ul>

For definition lists, the title is bold and the definition data item is indented with the same left padding as for the lists (see above).

Definition list title
Definition list data
Definition list title
Definition list data
<dl>
  <dt>Definition list title</dt>
  <dd>Definition list data</dd>
  <dt>Definition list title</dt>
  <dd>Definition list data</dd>
</dl>

Links and menus

In Codebase, links are styled with a color and an underline. The underline is set using the text-decoration property, and the color is set using the color property. The color of links is set to the --tc-link variable, which is defined in the root-vars.css file. On :hover, the link text color changes to the --tc-link-hover variable, which is set darker than --tc-link.

Example:

Link utilities

Then there are the following two classes that apply to links, that may be handy in some situations:

The browser default, and the best practice for accessability, is to have links indicated by an underline (and the browser default color of links is blue). But in the context of menus it is permissible to deviate from the best practice, provided there are other visual and non-visual indicators. This is the reason why we should use semantic HTML tags on menus, and and why we should place navigation menus in their expected locations (in sitewide menu-bars, sidebars, and footers).

Panel links

There may be situations where you have a link that contains some accompanying text that you don’t want to receive the <a href=""> (link) underline. Examples where this may be used: media object, card or hero component, where you want the whole thing to behave like a “big button”. for these, you need the panel-link and panel-link-title combo classes.

You will also want to style the outer <a href=""> e.g. with the block utility (for display:block), and add more styles to this inner element text, so that it is not the same color as the link label.

Y0u will also want to style the other element(s) text that’s not the panel-link-title with a different color, e.g. t-gray t-900.

Lorem ipsum dolor sit amet ...

<a class="panel-link" href="">
    <p class="panel-link-title">Link label (title)</p>
    <p class="mb-0 t-gray t-900">Lorem ipsum dolor sit amet ...</p>
</a>

Another example: here t-underline-hover-only has also been added to the <a href="">:

Lorem ipsum dolor sit amet ...

<a class="panel-link t-underline-hover-only" href="">
    <p class="panel-link-title">Link label (title)</p>
    <p class="mb-0 t-gray t-900">Lorem ipsum dolor sit amet ...</p>
</a>

Semantic menu tags

  • nav / <menu> / <menuitem>

The semantic <nav> tag has no styling of its own, other than its being a block element (similar to a div). Use it to organize your major navigation blocks of links (whether to other pages in your website, or “on this page”).

Semantic <menu> tags are treated by the browser as no different to an <ul>, but they are announced as a menu by screen readers. Codebase gives <menu>, <ul>, and <ol> the same styling: some left padding and bottom margin (and you can remove these you don't require them, using spacing utility classes: margins and/or paddings).

Using an <li> within a <menu> will give you bulletpoint block items. This will be OK for sidebars and dropdown menus, for example, but there’s also the semantic <menuitem> tag. This is an inline tag (like a <span>), and it doesn’t come with a bulletpoint.

This is what you get if you add no styling, other than the Codebase defaults (but of course you will want to add more styling):

<nav>
  <menu>
    <menuitem><a href="">Menu item 1</a></menuitem>
    <menuitem><a href="">Menu item 2</a></menuitem>
    <menuitem><a href="">Menu item 3</a></menuitem>
  </menu>
</nav>

Notes:

  1. Use <nav> to encapsulate your main navigation and “on this page” navigation. Navs can contain more than one menu, e.g. in dropdowns. The website or brand logo (with a link to the homepage) can be situated within the top <nav> but outside of the menu.
  2. The <menu> tag can be used in other contexts, e.g. for a list of related links to other websites, or for a set of user interface controls in a web application.
  3. Inside a <menuitem> can be a link, a button, or other interactive element.

If you want a group of links (in a menu) to not have underlines, or to have underlines only when hovered, the following wrapper classes are available in Codebase:

  • links-underline-none
  • links-underline-hover-only

And now, with a few other Codebase utilities, you have a menubar:

<nav>
  <menu class="p-cell flex flex-wrap gap-3 bg-gray bg-100 links-underline-hover-only">
    <menuitem><a class="t-semibold t-gray t-700" href="">Menu item 1</a></menuitem>
    <menuitem><a class="t-semibold t-gray t-700" href="">Menu item 2</a></menuitem>
    <menuitem><a class="t-semibold t-gray t-700" href="">Menu item 3</a></menuitem>
  </menu>
</nav>

Or a menu for a sidebar or footer buffet:

<nav>
  <menu class="pl-0 flex flex-column gap-2 links-underline-hover-only">
    <menuitem><a href="">Menu item 1</a></menuitem>
    <menuitem><a href="">Menu item 2</a></menuitem>
    <menuitem><a href="">Menu item 3</a></menuitem>
  </menu>
</nav>

Text alignment

  • t-right, t-center, and t-left

In addition to the three simple text alignment classes above, Codebase also has several container-query responsive variants, for xs:, sm:, md: and lg: container breakpoints widths.

Example: The hearing in the card below is left aligned by default, but becomes center aligned when its container is xs (320px) wide and above, using xs:t-center:

A title

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magni rem animi quaerat accusantium illum architecto, nemo, ex harum voluptatum adipisci eum blanditiis dolorum. Natus debitis quisquam, expedita accusantium quos cumque?

Tables

Codebase tables are set using the .table class.

  • Table headers <th> are bold.
  • Table cells <th> and <td> have a border set by var(--b-1) – the same detail as <hr> and border utility classes.
  • Table cell paddings are set by --p-cell
  • All cell content is left-aligned. You can change that on the whole <table> or on a per-cell basis using the text alignment classes.
  • Codebase tables ordinarily are grid-lined, with cell content left-aligned, and cell widths dependant on the amoint of content in cells. Optional modifiers:
    • table-fixed will force cells to have the same (fixed) width.
    • table-borderless removes border lines (but keeps padding).
    • table-lines removes vertical lines but keeps horizontal lines.
    • table-compact reduced padding, good for large tables.
    • table-striped alternate rows have backgrounds semi-transparent white and pale gray
  • Cell or whole table alignments can be handled by t-center etc. and vertical-align-middle etc.
This is a Table Caption
Table Header 1 Table Header 2 Table Header 3
Table content 1.1 Table content 2.1 Table content 3.1
Table content 1.2 Table content 2.2 Table content 3.2
Table content 1.3 Table content 2.3 Table content 3.3
Table content 1.4 Table content 2.4 Table content 3.4
<table class="table">
  <caption>This is a Table Caption</caption>
  <thead>
    <tr>
      <th>Table Header 1</th>
      <th>Table Header 2</th>
      <th>Table Header 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Table content 1.1</td>
      <td>Table content 2.1</td>
      <td>Table content 3.1</td>
    </tr>
    <tr>
      <td>Table content 1.2</td>
      <td>Table content 2.2</td>
      <td>Table content 3.2</td>
    </tr>
    ...
  </tbody>
</table>

Example with table table-lined table-striped:

Table Header 1 Table Header 2 Table Header 3
Table content 1.1 Table content 2.1 Table content 3.1
Table content 1.2 Table content 2.2 Table content 3.2
Table content 1.3 Table content 2.3 Table content 3.3
Table content 1.4 Table content 2.4 Table content 3.4

Making wide tables responsive

If you have a lot of content in your table, it will probably break your page layout on small viewports (e.g. phones). The simplest way to make a table “responsive” is to wrap your table in a DIV with the overflow-x class to make it horizontally scrollable.

Column title Column title Column title Column title Column title Column title Column title Column title Column title Column title
Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content Tabel cell content
<div class="overflow-x">
  <table class="table">
    ...
  </table>
</div>

Making text bigger

The base font size is 100% (16px default). Additionally:

  1. There’s a t-lg class that can be used to make text 1.325em — good for a lead paragraph, large button, or important messaging.
  2. Classes .h1 through .h6 will resize text the same amount as for their respective heading tag sizes — use these when you want to make text bigger (or large text smaller) without adversely affecting accessibility/ SEO heading hierarchy.
  3. The t-long-read wrapping class uses a clamp() to ramp text from starting size 1em up to 1.25em (20px default) depending on container size. E.g. used for responsively increasing text size in article prose components. <h1> inside a t-long-read will have maximum font size 61px.
  4. The t-comfort wrapping class uses a clamp() to raise text from starting size 1em up to 1.625em (26px default) depending on container size. E.g. used for responsively increasing text size in comfortable reading components. <h1> inside a t-display will have maximum font size 79px.
  5. The t-display wrapping class uses a clamp() to raise text from starting size 1em up to 2em (32px default) depending on container size. E.g. used for responsively increasing text size in hero components. <h1> inside a t-display will have maximum font size 97px.
t-long-read wrapper t-comfort wrapper t-display wrapper

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Paragraph. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magni rem animi quaerat accusantium illum architecto, nemo, ex harum voluptatum adipisci eum blanditiis dolorum. Natus debitis quisquam, expedita accusantium quos cumque?

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Paragraph. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magni rem animi quaerat accusantium illum architecto, nemo, ex harum voluptatum adipisci eum blanditiis dolorum. Natus debitis quisquam, expedita accusantium quos cumque?

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Paragraph. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magni rem animi quaerat accusantium illum architecto, nemo, ex harum voluptatum adipisci eum blanditiis dolorum. Natus debitis quisquam, expedita accusantium quos cumque?

Code

<code> tags have monospaced text (set by --t-mono), with a thin border and a little padding to improve readability.

If the <code> tag is wrapped in a <pre> tag, then it becomes a block level element with more padding, a max-width of 100%, and y-axis overflow scrolling.

Other typographic utility classes

Besides those already introduced, Codebase also has utility classes for:

  • t-lg — increase font size by 1.5em. Use it directly on a <p> to enlarge the font (e.g. for a lead paragraph).
  • t-sm (or use the <small> HTML tag) — decrease font-size to 0.8em
  • t-highlight (or use the <mark> HTML tag) — text highlighter
  • t-thin, t-normal, t-semibold, t-bold, t-heavy — font weights
  • t-italic — font style italic
  • t-balance — balances word-wrap, so that e.g. long headings don't have orphans
  • t-uppercase — text transform to capitals
  • t-nowrap — prevents text wrapping (spaces behave as non-breaking spaces)

Note: links can also be styled as though they are buttons using the btn utility class. See components: buttons.