Typography
Consistent styles for standard HTML elements covering typography, lists, inline and block elements, plus optional styles for smooth-scroll and view-transition.
Examples
Headings and text
<h1>
Heading 1
<h2>
Heading 2
<h3>
Heading 3
<h4>
Heading 4
<h5>
Heading 5
<h6>
Heading 6
<p>
The quick brown fox jumps over the lazy dog.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
123456789
<small>
The quick brown fox jumps over the lazy dog.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
123456789
Lists
<ol>
- Item
- Item
- Item
- Item
<ul>
- Item 1
- Item 2
- Item 3
- Item 4
<dl>
- Term 1
- Description
- Term 2
- Description
Inline elements
Bold/strong
Italic/emphasis
Superscript(1)
Subscript(2)
Delete
Mark
Small
Keyboard
Code
Abbr
Block elements
<details>
Summary
Details body content
<blockquote>
— Editor Daily Blog
Blockquote with author and citation.
<hr>
<pre>
:where(html) {
color-scheme: light dark;
color: CanvasText;
background-color: Canvas;
}
<figure>
with caption
![Forest covered in snow with sunset filtering between tall trees.](/img/docs/winter-forest-300.webp)
Smooth-scroll and view-transition
Optional Smooth scroll and view-transition styles are included with the _typography.scss
document but provided as individual modules to allow using them independently.
Using the modules
Add the sassmods.scss
to your custom styles as below, use the Sass variables from the module's source code (see below) to customize the default property values if required, then include the Sass mixin(s) anywhere below.
// custom.scss
@use "sassmods/scss/sassmods" as *;
$font-family: "OpenSans", system-ui, -apple-system, sans-serif; // example
$h1-font-size: 2.2rem; // example
@include typography-css;
@media (prefers-reduced-motion: no-preference) {
@include smooth-scroll-css;
@include view-transition-css;
}
Using the framework
Enable the module(s) in the sassmods-system.scss
document as below, if required customize the styles or the Sass variables for the default property values directly in the source code (see below).
$enable-typography: true;
$enable-smooth-scroll: true;
$enable-view-transition: true;
Source
The source code is a self-contained Sass document that compiles the style modules as Sass mixins using Sass variables provided for the core property values that can be customized as described above.
_typography.scss
Use the property specific CSS variables to create root level variables for global styles and/or editing inline, or change all the values to suit your own parameters.
// ----------------------------------------------------------
// Typography
// ----------------------------------------------------------
$text-color: var(--text, CanvasText) !default;
$background-color: var(--background, Canvas) !default;
$font-family: system-ui, -apple-system, Arial, Helvetica, sans-serif !default;
$html-font-size: var(--html-fs, clamp(100%, 40% + 0.666vw, 140%)) !default;
$body-font-size: var(--body-fs, 1rem) !default;
$body-font-weight: var(--body-fw, normal) !default;
$body-line-height: var(--body-lh, 1.5) !default;
$link-color: var(--link, LinkText) !default;
$link-decoration-color: color-mix(in srgb, var(--link, LinkText) 75%, Canvas) !default;
$link-underline-offset: 0.1175em !default;
$visited-color: color-mix(in srgb, var(--visited, LinkText) 75%, white) !default;
$visited-decoration-color: color-mix(in srgb, var(--visited, LinkText) 50%, Canvas);
$hover-color: color-mix(in srgb, var(--hover, LinkText) 75%, white) !default;
$heading-font-weight: var(--heading-fw, 700) !default;
$heading-line-height: var(--heading-lh, 1.2) !default;
$heading-text-wrap: var(--heading-tw, pretty) !default;
$heading-margin-bottom: var(--heading-mb, 0.75rem) !default;
$h1-font-size: var(--h1-fs, 2rem) !default;
$h2-font-size: var(--h2-fs, 1.725rem) !default;
$h3-font-size: var(--h3-fs, 1.5rem) !default;
$h4-font-size: var(--h4-fs, 1.35rem) !default;
$h5-font-size: var(--h5-fs, 1.2rem) !default;
$h6-font-size: var(--h6-fs, 1.063rem) !default;
$para-margin-bottom: var(--para-mb, 1rem) !default;
$para-text-wrap: var(--para-tw, pretty) !default;
$list-margin-bottom: var(--list-mb, 1rem) !default;
$list-text-wrap: var(--list-tw, pretty) !default;
$list-indent: var(--li-ps, 2rem) !default;
$dl-list-indent: var(--dd-ms, 1rem) !default;
$small-font-size: 0.906em !default;
$small-font-size-heading: 0.75em !default;
$code-color: color-mix(in srgb, CanvasText 60%, Canvas) !default;
$kbd-padding-block: 0.1em !default;
$kbd-padding-inline: 0.35em !default;
$kbd-background-color: color-mix(in srgb, CanvasText 5%, Canvas) !default;
$kbd-radius: 0.125em !default;
$pre-padding: 1rem !default;
$pre-margin-bottom: 1rem !default;
$pre-border-color: color-mix(in srgb, CanvasText 12%, Canvas) !default;;
$pre-background-color: color-mix(in srgb, CanvasText 1%, Canvas) !default;;
$blockquote-padding-block: 0.75rem !default;
$blockquote-padding-inline: 1rem !default;
$blockquote-margin-bottom: 1rem !default;
$blockquote-border-color: color-mix(in srgb, CanvasText 12%, Canvas) !default;
$blockquote-border: 1px !default;
$blockquote-border-left: 10px !default;
@mixin typography-css {
:where(:not([popover], dialog)) {
margin: 0;
}
*, *::before, *::after {
box-sizing: border-box;
}
:where(html) {
color-scheme: light dark;
color: #{$text-color};
font-size: #{$html-font-size};
font-family: #{$font-family};
background-color: #{$background-color};
block-size: 100%;
}
:where(body) {
font-size: #{$body-font-size};
font-weight: #{$body-font-weight};
line-height: #{$body-line-height};
}
:where(a) {
color: #{$link-color};
overflow-wrap: break-word;
text-decoration-color: #{$link-decoration-color};
text-decoration-thickness: 1px;
text-underline-offset: #{$link-underline-offset};
}
:where(a:visited) {
color: #{$visited-color};
text-decoration-color: #{$visited-decoration-color};
}
:where(a:hover) {
color: #{$hover-color};
text-decoration: none;
}
:where(h1, h2, h3, h4, h5, h6) a {
text-decoration: none;
}
:where(h1, h2, h3, h4, h5, h6) {
font-weight: #{$heading-font-weight};
line-height: #{$heading-line-height};
text-wrap: #{$heading-text-wrap};
margin-block-end: #{$heading-margin-bottom};
}
:where(h1) {
font-size: #{$h1-font-size};
}
:where(h2) {
font-size: #{$h2-font-size};
}
:where(h3) {
font-size: #{$h3-font-size};
}
:where(h4) {
font-size: #{$h4-font-size};
}
:where(h5) {
font-size: #{$h5-font-size};
}
:where(h6) {
--heading-lh: 1.25;
font-size: #{$h6-font-size};
}
:where(p) {
text-wrap: #{$para-text-wrap};
margin-block-end: #{$para-margin-bottom};
}
:where(ol, ul, dl) {
text-wrap: #{$list-text-wrap};
margin-block-end: #{$list-margin-bottom};
}
:where(ol, ul) {
padding-inline-start: #{$list-indent};
}
: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(dt) {
font-weight: var(--fw);
}
:where(dt):not(:first-child) {
margin-block-start: var(--dt-mt);
}
:where(dd) {
margin-inline-start: #{$dl-list-indent};
}
:where(small) {
font-size: #{$small-font-size};
}
:where(h1, h2, h3, h4, h5, h6) small {
font-size: #{$small-font-size-heading};
}
:where(bold, strong) {
font-weight: var(--fw, bold);
}
:where(abbr[title]) {
cursor: help;
}
:where(code) {
color: #{$code-color};
word-wrap: break-word;
}
a > :where(code) {
color: inherit;
}
:where(kbd) {
padding-block: #{$kbd-padding-block};
padding-inline: #{$kbd-padding-inline};
background-color: #{$kbd-background-color};
border-radius: #{$kbd-radius};
}
:where(pre) {
overflow: auto;
padding: #{$pre-padding};
margin-block-end: #{$pre-margin-bottom};
border: 1px solid #{$pre-border-color};
background-color: #{$pre-background-color};
}
:where(pre code) {
color: revert;
word-break: normal;
}
:where(address) {
font-style: normal;
margin-block-end: var(--mb, 1rem);
}
:where(blockquote) {
padding-block: #{$blockquote-padding-block};
padding-inline: #{$blockquote-padding-inline};
margin-block-end: #{$blockquote-margin-bottom};
border: #{$blockquote-border} solid #{$blockquote-border-color};
border-inline-start-width: #{$blockquote-border-left};
}
:where(blockquote p) {
--mb: 0;
}
:where(blockquote p:first-of-type) {
--mb: 0.25rem;
}
:where(details) {
margin-block-end: 1rem;
}
:where(summary) {
cursor: pointer;
}
:where(details[open] summary) {
margin-block-end: var(--mb-open, 0.75rem);
}
:where(hr) {
box-sizing: content-box;
block-size: 0;
overflow: visible;
border: none;
border-block-start: 1px solid color-mix(in srgb, CanvasText 12%, Canvas);
margin-block-end: 1rem;
}
:where(figure) {
margin-block-end: 1rem;
}
:where(img, svg, video, audio, iframe, embed, object) {
display: block;
}
:where(img, svg) {
max-inline-size: 100%;
}
:where(iframe) {
border: 0;
}
} // End typography mixin
// Motion-animation
@mixin smooth-scroll-css {
:where(html) {
scroll-behavior: smooth;
}
}
@mixin view-transition-css {
@view-transition {
navigation: auto;
}
}