Typography
The typography styles reset and normalize the default user-agent property values for standard HTML content with mildly opinionated styles written to be customized using CSS variables and :where()
for 0 specificity.
Global styles (anchor)
Margins have been reset to 0 and box-sizing
properties values are set to border-box
, and common properties for styles are reset with localised CSS variables for styling and to enable customizing them inline or in custom style sheets.
Localised variables
:where(html, body, h1, h2, h3, h4, h5, h6) {
color: var(--color);
font-size: var(--fs);
font-weight: var(--fw);
line-height: var(--lh);
}
:where(h1, h2, h3, h4, h5, h6, p, ol, ul, dl, address) {
text-wrap: var(--tw);
margin-block-end: var(--mb);
}
The default property values are provided as CSS variables that can be customized in the _configuration.scss
document, see customizing below for more information and to view all the default typography styles.
Headings (anchor)
<h1>
The quick brown fox jumps over the lazy dog.
<h2>
The quick brown fox jumps over the lazy dog.
<h3>
The quick brown fox jumps over the lazy dog.
<h4>
The quick brown fox jumps over the lazy dog.
<h5>
The quick brown fox jumps over the lazy dog.
<h6>
The quick brown fox jumps over the lazy dog.
Paragraph text (anchor)
<p>
The quick brown fox jumps over the lazy dog.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
123456789
<p>
The quick brown fox jumped over the lazy dog to leverage agile frameworks to provide a robust synopsis for high level overviews with iterative approaches to corporate strategy foster collaborative thinking.
Lists (anchor)
The styles for the default <ol>
, <ul>
and <dl>
list types are written with element-specific CSS variables that can also be used to customize lists inline or in custom styles if required.
Ordered and unordered (anchor)
<ol>
- Item
- Item
- Item
- Item
<ul>
- Item 1
- Item 2
- Item 3
- Item 4
<ol style="--marker: upper-alpha;">
- Item
- Item
- Item
- Item
<ul style="--marker: square;">
- Item
- Item
- Item
- Item
<ol style="--pl: 3rem;">
- Item
- Item
- Item
- Item
<ul style="--pl: 1rem;">
- Item
- Item
- Item
- Item
Definition (anchor)
<dl>
- Term 1
- Description
- Term 2
- Description
<dl style="--dt-mt: .25rem;">
- Term 1
- Description
- Term 2
- Description
<dl style="--fw: bold;">
- Term 1
- Description
- Term 2
- Description
<dl style="--dd-ml: 0;">
- Term 1
- Description
- Term 2
- Description
Inline elements (anchor)
- Bold/strong
- Italic/emphasis
- Superscript(1)
- Subscript(2)
Delete- Mark
- Small
- Keyboard
Code
- Abbr
Standard inline <small>
text uses a defined REM value included with the property variables below, small text within headings uses an EM value to scale the size to match each heading level.
Block elements (anchor)
<details>
Summary
Details body content
<blockquote>
— Editor Daily Blog
Blockquote with author and citation.
<hr>
<pre><code>
*
html {
color-scheme: light dark;
font-family: system-ui, -apple-system, sans-serif;
color: CanvasText;
background-color: Canvas;
}
*The syntax highlighting colors demonstrated throughout the website for code examples uses Hugo's Chroma syntax highlighting and is currently not included with Themalize.
<figure>
<img>
with <figcaption>
Optional inclusions (anchor)
Included with the typography styles but disabled by default, each can be enabled as demonstrated below in the _configuration.scss
document.
$enable-smooth-scroll: true;
$enable-view-transition: true;
(not yet baseline)
$enable-vis-hidden: true;
The first two if enabled are included using the @media
query (prefers-reduced-motion: no-preference)
to respect a users preference for animation styles.
The third enables a .vis-hidden
utility for making text available to assistive browsing but visually hiding it, and .vis-hidden-focus
for the same purpose but making it viewable when focused. Each comes with a Sass @mixin
that can be also used in custom CSS without the extension being enabled.
Extension utilities (anchor)
Seperate optional utilities are also available that extend and/or modify generic HTML typography elements using the styles and variables provided.
- Text utilities modifier classes for text styling.
- List utilities and list group components for all three list types.
- Accordions components for stylised
<details>
elements. - Image utilities for image aspect-ratios within
<figure>
elements.
Customizing (anchor)
The default typography property values can be customized in the _properties.scss
document, new values added must also be included with the typography Sass map in the _maps.scss
document for compiling.
Properties
Themalize uses a responsive font sizing method learned from the CSS behind Jeremy Keith's website. The $font-size
clamp()
value is applied to the html
tag and increases or decreases the fixed rem
values used for the other font sizes depending on the viewport.
Adjust the clamp()
values to alter font sizes globally and/or change the rem
values as required. Please note changing font family may require adjusting all values to suit.
$font-family: system-ui, -apple-system, Arial, Helvetica, sans-serif !default;
$font-size: clamp(100%, 40% + 0.666vw, 140%) !default;
$body: 1rem !default;
$fs-xl: 1.25rem !default;
$fs-lg: 1.1rem !default;
$fs-sm: 0.906rem !default;
$fs-xs: 0.813rem !default;
$fs-xxs: 0.75rem !default;
$h1: 2rem !default;
$h2: 1.725rem !default;
$h3: 1.5rem !default;
$h4: 1.35rem !default;
$h5: 1.2rem !default;
$h6: 1.063rem !default;
$lh-body: 1.5 !default;
$lh-header: 1.2 !default;
Sass map
$typography: (
"color": var(--text),
"font": #{$font-family},
"fs": #{$font-size},
"body": #{$body},
"fs-xl": #{$fs-xl},
"fs-lg": #{$fs-lg},
"fs-sm": #{$fs-sm},
"fs-xs": #{$fs-xs},
"fs-xxs": #{$fs-xxs},
"h1": #{$h1},
"h2": #{$h2},
"h3": #{$h3},
"h4": #{$h4},
"h5": #{$h5},
"h6": #{$h6},
"lh-body": #{$lh-body},
"lh-header": #{$lh-header},
) !default;
The typography styles can be customized in the _styles.scss
document, they're written as standard CSS with limited Sass functionality included for compiling purposes.
Styles
As the contents below shows _styles.scss
document also includes the buttons and forms and tables styles but they have not been included in the example below.
// ------------------------------------------------------------
// Styles
// 1. Resets
// 2. Typography
// 3. Smooth scroll and view-transition (if enabled)
// 4. Accessibility (if enabled)
// 5. Forms and buttons (if enabled)
// 6. Tables (if enabled)
// ------------------------------------------------------------
@use "../configuration" as *;
@use "../properties" as *;
// ------------------------------------------------------------
// 1. Resets
// ------------------------------------------------------------
* {
margin: 0;
}
*, *::before, *::after {
box-sizing: border-box;
}
// ------------------------------------------------------------
// 2. Typography
// ------------------------------------------------------------
:where(html, body, h1, h2, h3, h4, h5, h6) {
color: var(--color);
font-size: var(--fs);
font-weight: var(--fw);
line-height: var(--lh);
}
:where(html) {
color-scheme: light dark;
font-family: var(--font);
background-color: var(--body-bg);
height: 100%;
}
:where(body) {
--fs: var(--body);
--fw: normal;
--lh: var(--lh-body);
}
:where(a) {
--color: var(--link);
--hover: var(--link-hover);
--visited: var(--link-visited);
@if $enable-icon-mixins or $enable-icon-styles {
--ico: var(--color);
}
color: var(--color);
overflow-wrap: break-word;
text-decoration-color: color-mix(in srgb, var(--color) 75%, var(--body-bg));
text-decoration-thickness: 1px;
text-underline-offset: .1175em;
}
:where(a:visited) {
color: var(--visited);
text-decoration-color: color-mix(in srgb, var(--link) 35%, var(--body-bg));
}
:where(a:hover) {
@if $enable-icon-mixins or $enable-icon-styles {
--ico: var(--hover);
}
color: var(--hover);
text-decoration: none;
}
:where(a:focus-visible) {
outline: .094rem solid var(--link-hover);
outline-offset: .1175rem;
border-radius: .15em;
}
:where(h1, h2, h3, h4, h5, h6) a {
text-decoration: none;
}
:where(h1, h2, h3, h4, h5, h6, p, ol, ul, dl, address) {
text-wrap: var(--tw);
margin-block-end: var(--mb);
}
:where(h1, h2, h3, h4, h5, h6) {
--fw: 700;
--lh: var(--lh-header);
--tw: pretty;
--mb: .75rem;
}
:where(h1) {
--fs: var(--h1);
}
:where(h2) {
--fs: var(--h2);
}
:where(h3) {
--fs: var(--h3);
}
:where(h4) {
--fs: var(--h4);
}
:where(h5) {
--fs: var(--h5);
}
:where(h6) {
--fs: var(--h6);
--lh: 1.25;
}
:where(small) {
--fs: var(--fs-sm);
font-size: var(--fs);
}
:where(h1, h2, h3, h4, h5, h6) small {
--fs: .75em;
}
:where(bold, strong) {
--fw: bold;
font-weight: var(--fw);
}
:where(p, ol, ul, dl, address) {
--tw: pretty;
--mb: 1rem;
line-height: var(--lh);
}
:where(ol, ul) {
--pl: 2rem;
padding-inline-start: var(--pl);
}
:where(ol) {
list-style-type: var(--marker, decimal);
}
:where(ul) {
list-style-type: var(--marker, disc);
}
:where(ol ol, ul ul, ol ul, ul ol, dl dl) {
--mb: 0;
}
:where(dl) {
--fw: bold;
--dd-ml: 1rem;
}
:where(dt) {
font-weight: var(--fw);
}
:where(dt):not(:first-child) {
margin-block-start: var(--dt-mt);
}
:where(dd) {
margin-inline-start: var(--dd-ml);
}
:where(abbr[title]) {
border: none;
cursor: help;
}
:where(sup, sub) {
font-size: var(--fs-xxs);
}
:where(mark) {
color: marktext;
}
:where(code) {
color: color-mix(in srgb, var(--text) 60%, var(--body-bg));
word-wrap: break-word;
}
a > :where(code) {
color: inherit;
}
:where(pre, code, kbd, samp) {
font-family: Consolas, SFMono-Regular, monospace;
}
:where(kbd) {
padding-block: .1em;
padding-inline: .35em;
background-color: var(--surf-2);
border-radius: .25rem;
}
:where(pre) {
overflow: auto;
border: 1px solid var(--surf-2);
padding: 1rem;
margin-block-end: 1rem;
}
:where(pre code) {
color: revert;
word-break: normal;
}
:where(address) {
font-style: normal;
}
:where(blockquote) {
border: 1px solid var(--surf-1);
border-inline-start-width: 10px;
padding-block: .75rem;
padding-inline: 1rem;
margin-block-end: 1rem;
}
:where(blockquote p) {
--mb: 0;
}
:where(blockquote p:first-of-type) {
--fs: var(--fs-lg);
--mb: .25rem;
font-size: var(--fs);
}
:where(details) {
--fw: bold;
--mb-open: 1rem;
margin-block-end: 1rem;
}
:where(summary) {
font-weight: var(--fw);
cursor: pointer;
}
:where(details[open] summary) {
margin-block-end: var(--mb-open);
}
:where(hr) {
box-sizing: content-box;
height: 0;
overflow: visible;
border: none;
border-block-start: 1px solid var(--surf-2);
margin-block-end: 1rem;
}
:where(figure) {
margin: 0;
margin-block-end: 1rem;
}
:where(figcaption) {
font-size: var(--fs-xs);
padding-block-start: .5rem;
}
:where(img, svg, video, audio, iframe, embed, object) {
display: block;
}
:where(img, svg) {
max-width: 100%;
}
:where(iframe) {
border: 0;
}
.hidden {
display: none;
}
// ------------------------------------------------------------
// 3. Smooth scroll and view-transition (if enabled)
// ------------------------------------------------------------
@media (prefers-reduced-motion: no-preference) {
@if $enable-smooth-scroll {
:where(html) {
scroll-behavior: smooth;
}
}
@if $enable-view-transition {
@view-transition {
navigation: auto;
}
}
}
// ------------------------------------------------------------
// 4. Accessibility (if enabled)
// ------------------------------------------------------------
@mixin vis-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
}
@mixin vis-hidden-focus {
&:not(:focus):not(:focus-within) {
@include vis-hidden;
}
}
@if $enable-vis-hidden {
.vis-hidden, .vis-hidden-focus:not(:focus):not(:focus-within) {
@include vis-hidden;
}
}