Oatcake: Plain Web Typography
A drop-in CSS stylesheet that makes pages attractive and readable. Looks good without drawing attention to the design. Works great on both mobile and desktop.
This page is styled with Oatcake, my universal typography theme. Possibly the world's most deadpan stylesheet, Oatcake aims to look good without being distracting or drawing too much attention to itself. Plain but pretty.
- Just one little CSS file. ~2.2KB minified and compressed.
- Styles ordinary HTML elements. No CSS classes or JavaScript, you can style semantic HTML straight from Markdown.
- Does lots with little. No library of custom components, but Oatcake styles many standard elements and flexibly enough to be combined in creative ways.
-
Handles minutiae and edge cases.
Sweats details like typographic rhythm, nested lists, and stacked
headings; prevents horizontal overflows; supports obscure elements
like
<samp>,<kbd>,<hgroup>,<aside>,<details>and<figure>; etc. - Use alone or as a base layer. Create a more interesting look by adding your own styles. Oatcake provides variables for fonts, colors, etc, and uses a CSS layer so your rules take precedence regardless of specificity.
To style your own site with Oatcake, see the instructions in the README.
The rest of this tremendously long page will demo Oatcake's features, show you how to use them, and explain some of the design choices. You might even learn something about HTML along the way! Oatcake works with standard HTML elements, so every component comes with a semantic definition and usage guidelines, complete with examples, from the HTML Standard and MDN.
Fonts
Oatcake uses a
system font stack based on
the system-ui font-family: it chooses the default interface
font from the user's OS.
For code blocks Oatcake uses a font stack based on the
ui-monospace font-family which selects the operating
system's default monospaced font.
Details: fonts
Design notes
Many themes use idiosyncratic fonts that distract from reading and writing. A system font stack follows Oatcake's philosophy of looking good without drawing attention to its design choices. It's fast (no fonts to download), readable (modern operating systems ship high-quality fonts adapted to today's screens and legible at small sizes), and feels native to the user's system (nothing too distinctive).
A system font stack also supports a wide range of weights:
bold (font-weight: 700), bolder (font-weight: 900), light (font-weight: 300), lighter (font-weight: 100).
Customizing Oatcake's fonts
You can customize the fonts by setting some CSS variables in your own custom stylesheet:
<style>
:root {
--ok-font-family: 'ui-rounded, source-sans-pro, sans-serif';
--ok-font-family-mono: '"Nimbus Mono PS", "Courier New", monospace';
}
</style>
Or to change the fonts only within certain elements set the variables only on those elements, for example:
<style>
#myElement {
--ok-font-family: 'ui-rounded, source-sans-pro, sans-serif';
--ok-font-family-mono: '"Nimbus Mono PS", "Courier New", monospace';
}
</style>
For example, click this button to change this page to a handwritten font stack:
Here's the full list of font variables you can change:
--ok-font-family-
The
font-familyfor the main<body>text. --ok-font-size-
The
font-sizefor the main<body>text. --ok-line-height-
The
line-heightfor the main<body>text. --ok-font-size-small-
The
font-sizefor small text:<small>elements, subscripts (<sub>) and superscripts (<sup>). --ok-font-family-mono- The
font-familyfor monospaced text.
Emoji
Oatcake's font stack also adds support for native emoji. Here's a bunch:
🫢 💀 🥄 🍴 😒 🤎 🔪 😨 💚 🧘 😴 🤗 😆 😼 😾 😰 🤪 🩵 😏 🤭 🫙 🌍 👽 🤫 🙀 🏺 💌 🍆 🛀 🥒 🍊 🤕 💜 🧄 😢 🌽 😗 💙 🌐 🌏 🥐 💛 🫣 🧡 👾 🙈 💝 🥹 🩷 🤍 💖 🫚 🌎 🤔 🖤 🩶 🫛 ☠ 😝 🤒 💢 🍞 😿 🥲 💯 🥰 🤬 🚴 💋 👋 🧭 🗾 🛌 🥑 🫰 🥥 ✌ 🧒 🧔 🙎 👦 😃 😍 🎨 🙃 🤩 🌸 😘 🎯 🌟 🎭 🐿
The monospaced font stack also adds the same emoji support:
# 🚀 Initialize the rocket launch sequence
status = "Ready for liftoff! 🌟"
countdown = [3, 2, 1] # ⏰ T-minus...
print(f"{status} {'🔥' * len(countdown)}")
# 🎉 Mission success! 🛸
Colors
By default Oatcake uses black text on a white background, and the
standard
bright blue links. It sets a typical
light-gray background and/or border for code, sample
output, preformatted text blocks, block quotes, disclosure widgets and
asides. A yellow background for highlights, and a
muted text color
for footers.
Details: colors
Design notes
Like its fonts, Oatcake's colors are also chosen to be readable and not to be noticed.
Dark purple is used to differentiate visited links from un-visited ones. Links also flash red while being activated to give visual feedback. The exact colors used for visited, un-visited and active links are those suggested in the HTML standard.
Customizing Oatcake's colors
As with the fonts, you can customize Oatcake's colors by setting some CSS variables in your own custom stylesheet:
<style>
:root {
--ok-color-bg: black;
--ok-color-fg: white;
}
</style>
Or to change the colors only within certain elements set the variables only on those elements, for example:
<style>
#myElement {
--ok-color-bg: black;
--ok-color-fg: white;
}
</style>
For example, click this button to change this page to a dark mode color theme:
Here's the full list of color variables you can change:
--ok-color-bg- The primary background color.
--ok-color-fg- The primary foreground
color. --ok-color-block-bg-
The
background-colorof preformatted text blocks, code blocks, sample output blocks, disclosure widgets and asides. --ok-color-block-fg- The foreground
colorof blocks. --ok-color-code-bg-
The
background-colorof inline<code>and<samp>elements. --ok-color-code-fg-
The foreground
colorof inline<code>'s and<samp>'s. --ok-color-muted-fg-
The foreground
colorof footers, and list item markers. --ok-color-border-
The
border-colorof block quotes, preformatted text blocks, code blocks, sample output blocks, disclosure widgets, asides, images, videos, iframes and horizontal rules. --ok-color-highlight-bg-
The
background-colorof highlighted text (<mark>elements). --ok-color-highlight-fg- The foreground
colorof highlighted text. --ok-color-link-fg- The foreground
colorof links. --ok-color-link-visited-fg- The foreground
colorof visited links. --ok-color-link-active-fg-
The foreground
colorof links while they're being clicked on or otherwise activated. Provides visual feedback that the link was clicked. --ok-color-summary-marker-
The foreground
colorof the open/close triangles on disclosure widgets.
Rhythm
Oatcake picks a comfortable base line-height and sets all sizes, margins and paddings to multiples of that rhythm, like writing on a sheet of lined paper:
Lorem ipsum
Ut convallis nisl ac tempor molestie. Pellentesque consectetur mattis orci sit amet dignissim. Mauris in erat aliquam tellus efficitur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed aliquam suscipit nisi lacinia aliquam. Proin at lacinia massa. Etiam blandit tortor nunc. Mauris ut porttitor elit. Nam massa nibh, ultrices a consectetur ut, blandit at orci.
Maecenas semper commodo venenatis
- Vestibulum rutrum porta lorem at feugiat.
- Praesent varius egestas tincidunt.
- Suspendisse rhoncus, erat vitae cursus consectetur, est lectus iaculis tellus, non pellentesque est eros at eros.
def main():
print("Hello, world!")
if __name__ == "__main__":
main()
When the lines are hidden, the regularity makes pages more enjoyable to read: things flow like they belong together and everything feels calmer, more orderly and harmonious.
It's surprisingly difficult to get this comprehensively right, without some element or combination throwing off the rhythm. Click the button to toggle vertical rhythm lines for this entire page:
Horizontal alignment
Oatcake also aligns things horizontally, using consistent margins, borders and paddings:
This is a normal paragraph.
This is a block quote.
This is a description list:
- Term
- Description
Here's a code block:
print("Hello, world!")
Here's an <aside>:
Here's a disclosure widget:
This is the summary
Here are the details.Inline elements
All of HTML's inline elements work as you'd expect:
links, code(),
bold, italics, strikethroughs,
underlines, highlights, (even mid-word highlights:
unfriggingbelievable), small text,
subscripts24 and superscripts42, abbreviations
like HTML, quotes
,
and keyboard input: Ctrl + c.
The inline element styles are chosen so that they can be combined in
many ways. For example you can combine two <strong>'s
to make extra bold. You can also combine bold and italic; code spans can be italic, bold, or
struck-throughhighlighted; links can be
italic, bold, struck-through or
highlighted; even <kbd>'s can contain italics, bold, highlights
or strikethroughs: Ctrl +
Shift + Alt +
Del; you can put a link in a code span or in a
<kbd>: Super; small text can contain
bold, italics, code,
highlights, links and
strikethroughs, etc.
Details: inline elements
Here's a pocket guide to some of the more useful inline elements that Oatcake supports and the HTML Standard's advice for using them.
The <code> and <samp> elements:
code and sample output
To represent code, filenames, the names of computer programs, etc,
wrap them in <code> tags (HTML Standard,
MDN). This: <code>this is code</code>, renders
like this: this is code. This is what
`backticks` do in Markdown. For multi-line code blocks
see code blocks.
To represent sample output from a program wrap it in
<samp>
tags (HTML Standard,
MDN). This:
<samp>Keyboard not found. Press F1 to
continue</samp>, renders like this:
Keyboard not found. Press F1 to continue. For multi-line
sample output see sample output blocks.
Design notes
Oatcake styles <samp> the same as
<code>, making the difference only semantic. I
didn't think two different styles for these would be likely to clearly
say "this is code" whereas "this is output" to the reader, and too
many different styles would only be distracting and make more design
work and CSS.
Customization:
how to make <samp> and
<code> look different from each other
If you want <samp>'s and
<code>'s to look different you can easily get that
by adding a little custom CSS on top of Oatcake. For example:
<style>
samp {
border: 1px dashed #999;
}
</style>
Now <samp>sample output</samp> renders like
this: sample output
The <kbd> element: text input
To represent user input from a keyboard or other text entry device
wrap it in <kbd> tags (HTML Standard,
MDN). This:
<kbd>Ctrl</kbd> + <kbd>Alt</kbd> +
<kbd>Del</kbd>, renders like this:
Ctrl + Alt + Del
Tip: representing multiple keystrokes
There are three different ways to represent multiple keystrokes that form a single input. All three ways are equally valid:
-
You can just write the whole sequence as a single
<kbd>. This:<kbd>Ctrl + c</kbd>…will render like this: Ctrl + c
-
Alternatively, you can wrap each keystroke in its own separate
<kbd>. This:<kbd>Ctrl</kbd> + <kbd>c</kbd>…will render like this: Ctrl + c
-
Finally, you can use an outer
<kbd>containing nested<kbd>'s for each of the individual keystrokes. Many themes try to show the nested structure visually but it doesn't work very well: there isn't enough space to make it look good. In Oatcake nested<kbd>'s are semantic only: they look the same as a single<kbd>. This:<kbd><kbd>Ctrl</kbd> + <kbd>c</kbd></kbd>…will render like this: Ctrl + c
Tip: avoid long <kbd>'s
Oatcake prevents line-wrapping within a
<kbd> (even if there are spaces) so don't make
<kbd>'s too long or they'll overflow their
container and break the layout.
Tip: use non-breaking spaces between <kbd>'s
Oatcake prevents browsers from wrapping a
<kbd> over multiple lines even if the
<kbd> contains multiple words separated by spaces,
but if you're using a chain of separate <kbd>'s (as
in Ctrl + c) you must use non-breaking
spaces ( ) instead of normal spaces around the
+
if you want to prevent line breaks from being inserted in-between the
<kbd>'s.
Wrapping the whole sequence of <kbd>'s in a
<span style="white-space: nowrap;"> also works.
You can also use either technique if you don't want a
<code>, <samp>,
<mark>, etc to be wrapped, for example:
<code style="white-space: nowrap;">
(Oatcake doesn't prevent wrapping within these elements by default
because often you do want them to wrap, especially if they contain
long strings that might otherwise
overflow the container).
The <cite> element: marking the title of a work
Instead of <code>, you can also use
<cite> (HTML standard,
MDN) for the name or title of a computer program or any other work
(book, research paper, poem, song, play, film, TV show, game,
painting, website or web page, etc). Oatcake styles
<cite> in italics, here's an example from the HTML
Standard:
My favorite book is The Reality Dysfunction by Peter F. Hamilton. My favorite comic is Pearls Before Swine by Stephan Pastis. My favorite track is Jive Samba by the Cannonball Adderley Sextet.
You can use <cite> whenever mentioning the title of
a work: you don't have to be quoting from or referencing the work. But
<cite> is only for the titles of works:
it's wrong to wrap a person's name (e.g. the author) in a
<cite>.
Also, only the title of the work should go in a
<cite>. This is wrong:
According to <cite>the Wikipedia article on HTML</cite>, [...]
Only the title should be in the
<cite>:
According to the Wikipedia article on <cite>HTML</cite>, [...]
You can add the cite attribute to a
<cite>
element to give a URL for the work being cited. This isn't rendered,
it's just for scripts:
<cite cite="https://www.w3.org/Consortium/">About W3C</cite>
The <var> element: variables
Instead of <code>, you can also use
<var>
(HTML standard,
MDN) for variables, constants, symbols, quantities, parameters, and
placeholders. Oatcake styles <var> in italics:
The variables minSpeed and maxSpeed control the minimum and maximum speed of the apparatus in revolutions per minute (RPM).
The <mark> element: highlighting for relevance
<mark> (HTML standard,
MDN) highlights text:
this is some text highlighted with <mark>.
<mark> is for denoting the
relevance of a span of text to the current context.
It can be used in a quote or block quote to add a highlight that was
not present in the original source. This is better than using italics
or bold: it's both semantically correct and visually distinct from any
italics or bold that might be in the original text. Here's an example
from the HTML Standard:
Consider the following quote:
Look around and you will find, no-one's really colour blind.
As we can tell from the spelling of the word, the person writing this quote is clearly not American.
Another use for <mark> is to highlight parts of a
code block that you want to refer to from the text. Again this is
semantically correct and won't conflict with any syntax highlighting
in the code block. Example from the standard:
The highlighted part below is where the error lies:
var i: Integer; begin i := 1.1; end.
Finally, a third use for <mark> is to highlight the
parts of a document that match a search string. Here's an example from
MDN:
Search results for "salamander":
Several species of salamander inhabit the temperate rainforest of the Pacific Northwest.
Most salamanders are nocturnal, and hunt for insects, worms, and other small creatures.
The <dfn> element: defining terms
<dfn>
(HTML standard,
MDN) can be used to mark up the defining instance of a term. You wrap a
term in <dfn> and then the definition of that term
should be in the same paragraph,
description list group, or
<section> as the <dfn>. Oatcake
styles <dfn>'s in italics. Here's an example from
MDN:
A validator is a program that checks for syntax errors in code or documents.
You can give a <dfn> an id
so that you can link to it. Then whenever using the term elsewhere in
the document you can link the usages to the definition. Here's an
example from MDN:
<p>
The HTML Definition element
(<dfn id="definition-dfn">DFN</dfn>) is used to indicate the term being defined within the context of a
definition phrase or sentence.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Graece donan, Latine voluptatem vocant. Confecta res esset.
Duo Reges: constructio interrete. Scrupulum, inquam,
abeunti;
</p>
<p>
Because of all of that, we decided to use the
<a href="#definition-dfn">DFN</a> element for this project.
</p>
A <dfn> can have a title attribute
containing the exact value of the term being defined. This is only
necessary if the <dfn>'s contents aren't already
the exact value of the term. For example when using an abbreviation:
<p>The <dfn title="Garage Door Opener">GDO</dfn> is a device
that allows off-world teams to open the iris.</p>
The <abbr> element: abbreviations and acronyms
<abbr>
(HTML standard,
MDN) is for abbreviations and acronyms.
An <abbr> on its own has no visual effect with
Oatcake: it's semantic only. But if you provide the expansion as the
value of a title attribute on the
<abbr> then Oatcake adds a dotted underline and
makes the mouse cursor change to a "help" cursor when hovering over
the <abbr>. The title appears in a tooltip on
hover. For example, this:
<abbr title="HyperText Markup Language">HTML</abbr>
…renders like this:
HTML
You don't have to use <abbr>: the HTML Standard
explicitly says that marking up abbreviations and acronyms with
<abbr> is optional.
When using <abbr> you don't have to use the
title attribute: it's just as good to put the expansion
in parentheses following the first use of the abbreviation. Subsequent
uses of the abbreviation don't need to repeat the expansion. This is
probably better than the title attribute in most
cases because some browsers (e.g. mobile browsers) don't support
tooltips. Here's an example from MDN:
You can use <abbr>CSS</abbr> (Cascading Style Sheets) to
style your <abbr>HTML</abbr> (HyperText Markup Language).
Using style sheets, you can keep your <abbr>CSS</abbr>
presentation layer and <abbr>HTML</abbr> content layer
separate. This is called "separation of concerns."
You can use <abbr> and
<dfn> together as in this example from MDN:
<p>
The
<dfn><abbr title="Hubble Space Telescope">HST</abbr></dfn>
is among the most productive scientific instruments ever
constructed. It has been in orbit for over 20 years,
scanning the sky and returning data and photographs of
unprecedented quality and detail.
</p>
<p>
Indeed, the <abbr title="Hubble Space Telescope">HST</abbr>
has arguably done more to advance science than any device
ever built.
</p>
The <strong> element: importance
<strong>
(HTML standard,
MDN) is what **double asterisks** or
__double underscores__ do in Markdown, it makes text
bold:
this is bold text with <strong>.
<strong> isn't a generic "bold" element (use CSS
for that: font-weight: bold).
<strong> is meant to be used to mark something as
important. Examples from the HTML Standard and MDN:
Chapter 1: The Praxis
Figure 1. Ant colony dynamics. The ants in this colony are affected by the heat source (upper left) and the food source (lower right).
… the most important rule, the rule you can never forget, no matter how much he cries, no matter how much he begs: never feed him after midnight.
Important: Before proceeding, make sure you add plenty of butter.
Welcome to Remy, the reminder system.
Your tasks for today:
Turn off the oven.
Put out the trash.
Do the laundry.
Warning. This dungeon is dangerous. Avoid the ducks. Take any gold you find. Do not take any of the diamonds, they are explosive and will destroy anything within ten meters. You have been warned.
As you can see in that last example: you can nest
<strong>'s to indicate increasing levels of
importance. Oatcake styles nested <strong>'s even
bolder:
bold and bolder
(whether this is visible may depend on your browser and font).
The <b> element: bring attention to
<b>
(HTML standard,
MDN) also styles text in bold but with a different semantic meaning:
<b> is for
text to which attention is being drawn for utilitarian purposes
without conveying any extra importance and with no implication of an
alternate voice or mood
.
To make something bold for purely stylistic (rather than utilitarian)
purposes use CSS (font-weight: bold), for importance use
<strong>, for alternate voice or mood use
<i>. If none of these apply and you still want to
bring attention to some text by making it bold then fall back to
<b>.
Some examples from the HTML Standard and MDN:
-
Highlighting key words without marking them up as important:
The frobonitor and barbinator components are fried.
-
Highlighting course names:
The two most popular science courses offered by the school are chemistry (the study of chemicals and the composition of substances) and physics (the study of the nature and properties of matter and energy).
-
Actionable words or objects in a text adventure game:
You enter a small room. Your sword glows brighter. A rat scurries past the corner wall.
-
A lead paragraph or sentence in an article
Kittens 'adopted' by pet rabbit
Six abandoned kittens have found an unexpected new mother figure — a pet rabbit.
Veterinary nurse Melanie Humble took the three-week-old kittens to her Aberdeen home.
[...]
The <em> element: stress emphasis
<em>
(HTML standard,
MDN) is what *single asterisks* or
_single underscores_ do in Markdown, it makes text
italic: this is italic text with <em>.
<em> isn't a generic "italics" element (use CSS for
that: font-style: italic): <em> is
meant to be used for
stress emphasis that changes the meaning of the sentence. Examples from the HTML standard:
Dogs are cute animals.
Cats are cute animals.
Cats are not cute animals.
Cats are cute animals.
Cats are mean animals.
Cats are cute animals.
Cats are cute vegetables.
Cats are cute animals.
Cats are cute animals!
The <i> element: alternate voice
<i>
(HTML standard,
MDN) also styles text in italics but with a different semantic meaning:
<i> is for
a span of text in an alternate voice or mood, or otherwise offset
from the normal prose in a manner indicating a different quality of
text.
To make something italic for purely stylistic purposes use CSS (font-style: italic), use <em> for stress emphasis, use
<dfn> to mark the defining instance of a term, use
<cite> for the titles of works, use
<var> for variables, use
<strong> for importance and use
<b> to bring attention to something. If none of
these apply and you still want to make something italic to indicate a
different voice/mood/mode/quality/semantics from the surrounding text
then fall back to <i>.
Some examples from the HTML Standard and MDN:
-
Names of things (e.g. ships). Here the italics doesn't add any emphasis to “Queen Mary”, it just indicates that it's not a queen named Mary but a ship named “Queen Mary.”:
The Queen Mary sailed last night.
-
Taxonomic designations:
the Felis silvestris catus is cute.
-
Technical terms:
the term bandwidth describes the measure of how much information can pass through a data connection in a given amount of time.
-
An idiomatic phrase from another language: et cetera.
In this case the
langattribute (HTML standard, MDN) should be added to the<i>to indicate which language is being used:<p>There is a certain <i lang="fr">je ne sais quoi</i> in the air.</p> -
Thoughts:
She wondered, What is this writer talking about, anyway?
-
When the text refers to the definition of a word instead of representing its semantic meaning:
the word the is an article.
-
A dream sequence:
Raymond tried to sleep.
The ship sailed away on Thursday, he dreamt. The ship had many people aboard, including a beautiful princess called Carey. He watched her, day-in, day-out, hoping she would notice him, but she never did.
Finally one night he picked up the courage to speak with her—
Raymond woke with a start as the fire alarm rang out.
The <q> element: inline quotations
<q>
(HTML standard,
MDN) is for inline quotations:
Whatever you lose, you've won. Whatever you win, you've lost.
For long or multi-paragraph quotations use
<blockquote> instead.
Notes on <q>:
-
You don't have to use
<q>for quotes: the HTML Standard explicitly states that typing quotation marks normally is just as correct. -
If you do use
<q>then you don't need to enter the quotation marks: it will add them automatically. -
Only use
<q>when quoting from another source. For other uses of quotation marks (e.g. sarcasm) enter the quotation marks manually. In this example from the standard quotation marks are just used to name a word, not to quote a source, so<q>would be inappropriate:<p>The word "ineffable" could have been used to describe the disaster resulting from the campaign's mismanagement.</p> -
When typing quotation marks manually, if you want to be fancy you can use
“for the opening quote and”for the closing quote. This creates curly left and right quotes like<q>does. This:“ineffable”renders like this: “ineffable”.Use
‘and’for fancy single quotes. -
If the source has a URL you can put it in the
citeattribute (this is just for scripts to read, it's not rendered). You can also use a<cite>element to mark up a citation nearby to the quote. Here's an example with both from the standard:<p>The W3C page <cite>About W3C</cite> says the W3C's mission is <q cite="https://www.w3.org/Consortium/">To lead the World Wide Web to its full potential by developing protocols and guidelines that ensure long-term growth for the Web</q>. I disagree with this mission.</p> -
You can nest
<q>'s and Oatcake will vary the quotation mark styles to distinguish the inner and outer quotes. Here's an example from the standard:In Example One, he writes
The man said
. Well, I disagree even more!Things that are impossible just take longer
. I disagreed with him
The <small> element: side-comments and small print
<small>
(HTML standard,
MDN) makes text smaller:
this is some small text created with the
<small> element.
<small>
is meant to be used for side-comments and small print: disclaimers,
caveats, legal restrictions, copyrights, attribution, and licensing
requirements, etc. It's only meant for short runs of text, not
multi-paragraph sections. Here's an example from MDN
MDN Web Docs is a learning platform for Web technologies and the software that powers the Web.
The content is licensed under a Creative Commons Attribution-ShareAlike 2.5 Generic License.
The <sub> and <sup> elements:
subscript and superscript
<sub> and <sup> (HTML standard, MDN:
sub,
sup) are for subscriptssub and superscripts.sup
Superscripts can be used for ordinal numbers. Example from MDN:
The ordinal number "fifth" can be abbreviated in various languages as follows:
- English: 5th
- French: 5ème
Superscripts can also be used to create footnotes:
According to the computations by Nakamura, Johnson, and Mason1 this will result in the complete annihilation of both particles.
<sub> and <sup> can be used
(perhaps inside a <var>) for mathematical
expressions or chemical formulas:
Almost every developer's favorite molecule is C8H10N4O2, also known as "caffeine."
Then she turned to the blackboard and picked up the chalk. After a few moment's thought, she wrote E = mc2. The teacher looked pleased.
The <ins> and <del> elements:
insertions and deletions
<ins>
(HTML standard,
MDN) represents text that has been inserted into the document. Oatcake
styles <ins> with an underline:
this is inserted text with <ins>.
<ins> goes with
<del>
(HTML standard,
MDN) which represents text that has been deleted from the document.
Oatcake styles <del> with a strikethrough:
this is text that has been marked as deleted with
.
<del>
<ins> and <del> together can be
used to create a diff, like this example from MDN:
There isnothingno code either good or bad, butthinkingrunning it makes it so.
You can add a cite attribute to an
<ins> or <del> to give the URL
of a document that explains the change, for example:
<del cite="/edits/r192">. (This won't be rendered:
it's just for scripts.)
You can also add a datetime attribute to an
<ins> or <del> to give the date
and time at which the change was made, for example:
<ins datetime="2008-02-12T15:20Z">. (This
won't be rendered either: it's also just for scripts.)
The <s> element: no longer accurate or relevant
<s>
(HTML standard,
MDN) strikes though text:
this is struck-through text with . It looks the same as <s><del> but has a different
semantic meaning: <s> is for text that is
no longer accurate or no longer relevant
rather than for text
that has been removed from the document. Here's a couple of examples
from the HTML standard and MDN:
Buy our Iced Tea and Lemonade!
Recommended retail price: $3.99 per bottleNow selling for just $2.99 a bottle!
There will be a few tickets available at the box office tonight.SOLD OUT!
The <u> element: spelling mistakes
Finally, <u> (HTML standard,
MDN) underlines text:
this is underlined text with <u>. It looks the same as <ins> but has a different
semantic meaning: <u> is meant to be used as
an unarticulated, though explicitly rendered, non-textual
annotation,
such as labelling a spelling mistake:
You could use this element to highlight speling mistakes, so the writer can corect them.
You could use CSS to give
<u class="spelling"> elements a red wavy underline
typical of spellcheckers (Oatcake doesn't do this for you):
This paragraph includes a wrnogly spelled word.
<u> is not meant to be used as a generic
"underline" element (use CSS for that:
text-decoration: underline;). The HTML Standard and MDN
encourage you to avoid <u> in most cases and choose
other elements such as <em>,
<b>, <mark>,
<strong>, <cite> and
<i>.
- This is an example footnote. ↩
Headings
Oatcake uses both the font-size and the amount of vertical space above
and below to provide three visually distinct levels of headings:
<h1>, <h2>, and
<h3>. While you can also use
<h4>'s, <h5>'s and
<h6>'s, they look identical to
<h3>'s. Here's what all six headings look like:
Level 1 heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
Level 2 heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
Level 3 heading
Suspendisse vitae bibendum libero. In in lorem lacus. Proin pharetra neque venenatis, fringilla justo id, elementum magna. Maecenas vestibulum tortor urna, vel pharetra nisi commodo vel.
Level 4 heading
Suspendisse dignissim tempor ultricies. Phasellus in sollicitudin felis, eget fringilla quam. Vestibulum suscipit arcu dapibus placerat cursus. Suspendisse dignissim orci in nibh convallis, sit amet tempus dui tincidunt.
Level 5 heading
Suspendisse dignissim tempor ultricies. Phasellus in sollicitudin felis, eget fringilla quam. Vestibulum suscipit arcu dapibus placerat cursus.
Level 6 heading
Suspendisse dignissim tempor ultricies.
Details: headings
Design notes
Headings are one of the hardest things to get right and one of the parts of Oatcake that I'm most happy with.
HTML's six levels of headings are more than most documents need.
Themes often resort to desperate measures to try to make all six
levels visually distinct: bottom-of-the-barrel tactics like overlarge
font sizes, excessively heavy weights, ALL CAPS, underlines, centered
text, too many font faces, too much indentation, etc. Most themes make
<h1>'s too big for my taste, meanwhile subheadings
often come in smaller fonts than the main body text.
Just because HTML has six levels of headings doesn't mean you should
use them all. Oatcake is opinionated about this and thinks that most
pages shouldn't use more than three levels of headings, ideally not
more than two: a single <h1> page title then
<h2>'s to break up the document into sections
and—only if really necessary—<h3>'s for
subsections. More levels are confusing and make it difficult for
readers to orient themselves within the document.
By restraining itself to just three visually distinct levels—using the smallest necessary increments in font size and space above and below to distinguish the levels from each other—Oatcake is able to make the levels distinct without gimmicks.
If you really do need to use more than three levels you can try hierarchically numbering your headings, see below.
Design notes: vertical alignment of headings
A common mistake is to vertically align headings closer to the paragraph above than to the one below, or evenly mid-way between them. Oatcake gives all levels of headings a little more vertical space above than below so they're visually related more with the text below (that belongs to the heading) than to the unrelated text above.
Tip: hierarchical headings
If you really need several levels of headings I recommend making the structure explicit by hierarchically numbering the headings as the HTML standard itself does (you have to do this yourself, Oatcake won't do it for you):
Document title (first-level heading)
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1. Second-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.1 Third-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.1.a Fourth-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.1.a.i Fifth-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.1.a.ii Another fifth-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.1.b Another fourth-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
1.2 Another third-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
2. Another second-level heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer malesuada, justo tincidunt mattis gravida, velit orci facilisis nibh, at hendrerit risus sem eu arcu.
Edge case: stacked headings
Sometimes a heading directly follows another heading, without any other text between them. Themes often mess this up by allowing the vertical space between stacked headings to look weird with large unnecessary gaps between the headings. Oatcake avoids this by styling headings that immediately follow other headings with less vertical space than they would have otherwise:
First-level heading
Second-level heading
Third-level heading
Fourth-level heading
Fifth-level heading
Sixth-level heading
Edge case: inline elements in headings
A lot of themes break or look weird if you try to use inline elements in a heading. Oatcake makes sure that all the inline elements work in headings:
A heading with bold in it
A heading with italics in it
A heading with a kbd in it
A heading with underlined text in it
A heading with highlighted text in it
A heading with deleted text in it
A heading with a link in it
A heading with mid-word emphasis in it
A heading withsuperscript andsubscript and small text in it
Edge case: <code> and
<samp> in headings
<code> and <samp> elements in
headings get a monospaced font but this can be quite subtle so Oatcake
also surrounds the code in backticks (thanks to
Tailwind CSS Typography
for the idea). Oatcake also prevents line-wrapping within a
<code> or <samp> in a heading.
An <h1> with code and sample output
An <h2> with code and sample output
An <h3> with code and sample output
Edge case: headings that wrap
Sometimes a heading wraps onto multiple lines, especially on small
screens. Many themes fail to account for this and the multiple lines
of a heading either have too much space between them or too little,
often actually overlapping. With Oatcake multi-line headings wrap
well, this is a multi-line <h1> heading:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
This is a multi-line <h2> heading:
Lorem ipsum dolgor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
This is a multi-line <h3> heading:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
Multi-line headings can even contain inline elements. This is where things go wrong in many themes:
This is a long multi-line <h1> heading containing
emphasis, <code>, a couple of
<kbd>'s:
Ctrl + c, underlined text,
highlighted text, struck-through text,
a link, a bold link,
a code link
and evensuperscript andsubscript and
small text
This is a long multi-line <h2> heading containing
emphasis, <code>, a couple of
<kbd>'s:
Ctrl + c, underlined text,
highlighted text, struck-through text,
a link, a bold link,
a code link
and evensuperscript andsubscript and
small text
This is a long multi-line <h3> heading containing
emphasis, <code>, a couple of
<kbd>'s:
Ctrl + c, underlined text,
highlighted text, struck-through text,
a link, a bold link,
a code link
and evensuperscript andsubscript and
small text
Subheadings
You can add a subheading to an <h1>–<h6>
heading by wrapping the
<h1>–<h6> in an
<hgroup> along with the subheading in a
<p>. Oatcake will style the <p> in
a larger font-size and/or lighter weight. Here's some examples from MDN
and the HTML Standard, this <h1> with a subheading:
<hgroup>
<h1>Frankenstein</h1>
<p>Or: The Modern Prometheus</p>
</hgroup>
<p>
Victor Frankenstein, a Swiss scientist, has a great ambition: to create
intelligent life. But when his creature first stirs, he realizes he has made a
monster. A monster which, abandoned by his master and shunned by everyone who
sees it, follows Dr Frankenstein to the very ends of the earth.
</p>
…renders like this:
Frankenstein
Or: The Modern Prometheus
Victor Frankenstein, a Swiss scientist, has a great ambition: to create intelligent life. But when his creature first stirs, he realizes he has made a monster. A monster which, abandoned by his master and shunned by everyone who sees it, follows Dr Frankenstein to the very ends of the earth.
Here's what an <h2> with a subheading looks like:
The reality dysfunction
Space is not the only void
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris et facilisis purus. Cras molestie tortor velit, interdum fringilla diam ornare vel. Nam quis venenatis nibh.
And an <h3>:
Dr. Strangelove
Or: How I Learned to Stop Worrying and Love the Bomb
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris et facilisis purus. Cras molestie tortor velit, interdum fringilla diam ornare vel. Nam quis venenatis nibh.
Details: <hgroup> and subheadings
Usage
<hgroup>
(HTML Standard,
MDN) is a container for a single <h1>–<h6>
heading and one or more <p>'s representing a
subheading, alternative title or tagline. The <p>'s
can come before and/or after the heading.
We've seen examples of a subheading and an alternative title, here's a
third example from MDN that uses the <p> as a
tagline containing related or secondary content. I've modified the
example to put the tagline before the heading:
Last Updated 12 July 2022
HTML: Living Standard
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris et facilisis purus. Cras molestie tortor velit, interdum fringilla diam ornare vel. Nam quis venenatis nibh.
Edge case: multi-paragraph subheadings
Subheadings can be as long as you want, even multiple
<p>'s:
Lorem ipsum dolor sit amet
Consectetur adipiscing elit. Nam interdum, mi et iaculis laoreet, erat felis accumsan lorem, in cursus sem sem vitae quam. Integer aliquam ullamcorper feugiat.
Sed tellus velit, ultrices eu fermentum tincidunt, auctor maximus diam. Cras in erat nec elit aliquet auctor. Vivamus imperdiet nisl nec porttitor consequat.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris et facilisis purus. Cras molestie tortor velit, interdum fringilla diam ornare vel. Nam quis venenatis nibh.
Edge case: inline elements in subheadings
All the inline elements work in subheadings:
Aenean lacinia porta ullamcorper
This is a subheading containing
italics, bold, <code>,
a couple of <kbd>'s:
Ctrl + c, underlined text,
highlighted text, struck-through text,
a link, a code link, and evensuperscript andsubscript and
small text.
Lists
This simple unordered list with <ul>:
<ul>
<li>Vivamus sit amet elit bibendum</li>
<li>Aliquam ornare sapien ut nisl tristique</li>
<li>Praesent aliquet erat eu felis</li>
</ul>
…renders like this with Oatcake:
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
The same thing but with <ol> creates an
ordered list:
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
Some or all the items in a list can wrap over multiple lines and it'll work nicely:
- Vivamus sit amet elit bibendum.
- Morbi tempor sit amet mi nec auctor. Nulla metus purus, pulvinar sed eros non, ornare hendrerit lacus. Nullam rhoncus pretium turpis iaculis sollicitudin. Mauris ligula velit, ullamcorper a luctus sed, gravida vitae leo.
- Praesent aliquet erat eu felis.
- Duis finibus commodo velit, ac aliquam nibh interdum vitae. Sed luctus vel dolor vel fringilla. Cras bibendum, turpis nec vestibulum vestibulum, augue sem ultricies urna, eu condimentum libero sapien eget nisi.
Details: lists
Edge case: nested lists
It's probably not great writing to use too many nested lists, but it happens. Themes often mess up nested lists: erasing the nested structure by collapsing the indentation, putting incorrect vertical space before or after a nested list, or otherwise making it look bad. Oatcake doesn't mess it up and allows indentation to show the nested structure:
- Vivamus non arcu quis sem aliquam
- Quisque in quam tempor, finibus odio nec
- Aenean lacinia augue vel orci efficitur
-
Mauris nec sem dapibus, convallis dolor eu
- Ut quis neque ac lectus vestibulum
- Fusce congue tortor blandit elit
-
Suspendisse porttitor justo at massa
- Vestibulum a turpis non urna
- Integer non orci a ex aliquam
- Nullam sit amet turpis sit amet
- Cras nec nulla tincidunt
- Vivamus ullamcorper orci a leo pretium
- Maecenas volutpat est eget purus placerat
Edge case: paragraph list items
If you leave blank lines between a list's items Markdown renders them
as
<li><p>'s rather than just
<li>'s, which results in the list being rendered
with some vertical space between items. Here's what a list of
<li><p>'s looks like with Oatcake:
-
Vivamus sit amet elit bibendum, sollicitudin turpis vel, ullamcorper purus.
-
Morbi tempor sit amet mi nec auctor. Nulla metus purus, pulvinar sed eros non, ornare hendrerit lacus. Nullam rhoncus pretium turpis iaculis sollicitudin. Mauris ligula velit, ullamcorper a luctus sed, gravida vitae leo.
-
Praesent aliquet erat eu felis malesuada maximus.
-
Duis finibus commodo velit, ac aliquam nibh interdum vitae. Sed luctus vel dolor vel fringilla. Cras bibendum, turpis nec vestibulum vestibulum, augue sem ultricies urna, eu condimentum libero sapien eget nisi.
Nested lists also work inside paragraph lists (a common source of bugs in other themes). The nested list can itself be a paragraph list, or not:
-
Here's a nested list inside a paragraph list item:
- First list item
- Second list item
- Third list item
Praesent aliquet erat eu felis malesuada maximus.
-
A nested paragraph list inside a paragraph list item:
First list item
Second list item
Third list item
- Phasellus congue tortor sed elementum placerat.
Edge case: other block elements inside lists
Block elements like block quotes, code blocks, etc inside lists are another common source of breakage that works fine with Oatcake:
-
A list item with a block quote:
This is a block quote inside a list item.
-
A list item with a code block:
<code goes here>And an image:
-
A list item with a description list in it:
- Term
- Description
- Term
- Description
- A normal list item to end the list.
Usage: <ul> or <ol>?
According to the HTML Standard and MDN
<ul> (unordered list) is for
where changing the order [of the list items] would not materially
change the meaning of the document.
If the order of the list items matters, use <ol>.
Tip: tricks with ordered lists
Did you know that you can reverse the order of the numbers in a
numbered list by adding a reversed attribute to an
<ol>?
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
Or you can change the list starting number by adding a
start="n" attribute:
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
reversed and start can be used together on
the same list:
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
You can change the type of list markers using the
type attribute: type="1" for numbers (the
default), type="a" for lower-case letters,
type="A" for upper-case letters,
type="i" for lower-case roman numerals, or
type="I" for upper-case roman numerals:
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
- Vivamus sit amet elit bibendum
- Aliquam ornare sapien ut nisl tristique
- Praesent aliquet erat eu felis
Description lists
You create a description list with
<dl>, <dt>, and
<dd>. This:
<dl>
<dt>Oatcake</dt>
<dd>Thin flat unleavened cake of baked oatmeal.</dd>
<dt>Oatmeal</dt>
<dd>Porridge made of rolled oats.</dd>
</dl>
…renders like this with Oatcake:
- Oatcake
- Thin flat unleavened cake of baked oatmeal.
- Oatmeal
- Porridge made of rolled oats.
Details: description lists
Description lists (HTML Standard,
MDN) can be lists of
…terms and definitions, metadata topics and values,
questions and answers, or any other groups of name-value data.
Within a <dl> you use pairs of
<dt>'s for the names ("terms") and
<dd>'s for the values ("descriptions" or
"definitions"). You can have multiple <dt>'s in a
row if an item has more than one name and/or multiple
<dd>'s in a row if an item has more than one value.
Here's a couple of examples from the HTML standard, this:
<dl>
<dt> Authors
<dd> John
<dd> Luke
<dt> Editor
<dd> Frank
</dl>
…renders like this:
- Authors
- John
- Luke
- Editor
- Frank
Here's an example of multiple terms with a single description:
<dl>
<dt lang="en-US"><dfn>color</dfn></dt>
<dt lang="en-GB"><dfn>colour</dfn></dt>
<dd>A sensation which (in humans) derives from the ability of
the fine structure of the eye to distinguish three differently
filtered analyses of a view.</dd>
</dl>
Note the (entirely optional) use of
<dfn>
to mark the terms being defined. The whole example renders like this:
- color
- colour
- A sensation which (in humans) derives from the ability of the fine structure of the eye to distinguish three differently filtered analyses of a view.
The contents of a <dd> can be wrapped in a
<p> and a <dd> can contain
multiple <p>'s if it's a multi-paragraph
description. Oatcake handles <dd>'s containing
either a single or multiple <p>'s just fine:
- Pancake
-
A flat cake of thin batter fried on both sides on a griddle.
- Pancake turtle
-
Voracious aquatic turtle with a flat flexible shell covered by a leathery skin; can inflict painful bites.
Synonym: soft-shelled turtle.
- Tortoise
- Tortoises
-
Usually herbivorous land turtles having clawed elephant-like limbs.
-
Etymology: Old English tortuce, from Old French tortis crooked, from Latin tortus twisted, crooked, contorted, past participle of torquere, tortum, to wind.
Block quotes
Use <blockquote> to create block quotes. This:
<blockquote>
<p>
Ut fermentum turpis quis ligula sagittis, a fringilla orci
ultrices. Nam fringilla erat ac bibendum tristique. Morbi
nec maximus augue.
</p>
</blockquote>
…renders like this:
Ut fermentum turpis quis ligula sagittis, a fringilla orci ultrices. Nam fringilla erat ac bibendum tristique. Morbi nec maximus augue.
If your block quote contains only a single paragraph you can omit the
<p> and it'll look the same. This:
<blockquote>
Ut fermentum turpis quis ligula sagittis, a fringilla orci
ultrices. Nam fringilla erat ac bibendum tristique. Morbi nec
maximus augue.
</blockquote>
…renders like this:
Ut fermentum turpis quis ligula sagittis, a fringilla orci ultrices. Nam fringilla erat ac bibendum tristique. Morbi nec maximus augue.
Details: block quotes
Design notes
Many themes style <blockquote>'s in italics or bold
but this is problematic when the quoted text itself contains italics
or bold. Another common choice is to use a different font or font-size
for block quotes, but that can be distracting.
Oatcake uses indentation and a left border. This is a common, recognizable style for block quotes, it makes block quotes distinct from any other element in Oatcake, it works well with nested block quotes (see below), and the left border makes it extra clear where the block quote starts and ends which is helpful with long block quotes.
Customization
You can customize the style of block quotes with your own CSS. For example this will use a larger font-size and a thinner font-weight, and will use a "left double quotation mark" character rather than a left border to indicate the block quote:
<style>
blockquote {
border: none;
font-size: 19px;
font-weight: 300;
position: relative;
}
blockquote::before {
position: absolute;
font-size: 3em;
z-index: -1;
color: var(--ok-color-border);
content: "\201C";
left: 0;
top: 0;
}
</style>
Now block quotes will look like this:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a turpis at lacus accumsan dignissim sed vitae diam. Nullam bibendum egestas libero, tincidunt tincidunt ex iaculis quis.
Maecenas eget velit luctus, maximus urna quis, condimentum odio. Curabitur ultrices nunc quis turpis ullamcorper rutrum quis sit amet massa. Sed vel odio vel massa rutrum scelerisque.
Edge case: nested block quotes
Sometimes a quoted section itself contains another quoted section. You
can nest <blockquote>'s to an arbitrary depth and
Oatcake will show the nested structure. A lot of themes get this
wrong:
Fusce porta quam non varius viverra.
Vestibulum molestie nec massa et porta.
Donec imperdiet pretium luctus.
Etiam in malesuada lacus. Suspendisse eget velit lacinia, hendrerit lorem nec, pretium urna.
Morbi tempor luctus sodales. Vitae vehicula lorem gravida nec.
Nam commodo felis at tortor tempor, sit amet vestibulum lorem gravida. Suspendisse dignissim felis velit.
Usage: don't put quotation marks inside quotes or block quotes
You shouldn't put quotation marks around the text inside a block
quote: putting the text in a <blockquote> is enough
to show that it's a quotation, and the quotation marks aren't part of
the quoted text.
Usage: how to mark up abbreviations and additions to quotes and block quotes
In English it's traditional to use square brackets if abbreviating or
adding context to a block or inline quote, as in this example from the
HTML standard (Jane
has been added and something has been
removed between liked
and fish
):
[Jane] then said she liked […] fish.
(If you want to be fancy you can use an
ellipsis—…—instead of typing three
dots).
Usage: attributions and citations
Any attribution for the quotation is supposed to go before or after
the <q> or <blockquote>, not
inside it, because the attribution isn't part of the quoted text. For
example, the attribution could go in a following
<p>, as in this example from the HTML Standard:
<blockquote>
<p>I contend that we are both atheists. I just believe in one
fewer god than you do. When you understand why you dismiss
all the other possible gods, you will understand why I
dismiss yours.</p>
</blockquote>
<p>— Stephen Roberts</p>
Alternatively, you can put a <blockquote> in a
<figure> and the attribution in the
<figure>'s <figcaption>, see
the section on figures for an example.
Usage: the <cite> element
If the attribution contains the title of a work you can wrap it in a
<cite>, as in this example also from the HTML standard:
<p>His next piece was the aptly named <cite>Sonnet 130</cite>:</p>
<blockquote>
<p>My mistress' eyes are nothing like the sun,<br>
Coral is far more red, than her lips red,<br>
…
Usage: the cite attribute
You can add a cite attribute to a
<blockquote> whose value is a URL for the quoted
source. cite attributes aren't visible in the rendered
HTML, they're meant to be read by scripts:
<blockquote cite="https://quotes.example.org/s/sonnet130.html">
Images
Images need a little more space above and below them than paragraphs do, otherwise they feel cramped. Oatcake gives images just enough space–not too much, not too little, but just right. Images also get a very subtle border and rounded corners: it looks nicer and it's consistent with other elements in Oatcake that get the same borders and rounded corners:
Details: images
Customization: removing borders from images
You can remove the border from an image by adding the CSS
border: none;. For example, this:
<img style="border: none;" src="…" alt="…" />
…renders like this:
To turn off borders for all images add this to your site's stylesheet:
img {
border: none;
}
Customization: removing rounded corners from images
If you want to remove the rounded corners from images add
border-radius: 0; to the <img>'s CSS.
This:
<img style="border-radius: 0;" src="…" alt="…" />
…renders like this:
To turn off rounded corners for all images add this to your site's stylesheet:
img {
border-radius: 0;
}
Videos
The same extra little bit of vertical space, borders and rounded corners
are also applied to video players created using
<video>:
Details: videos
Customization: removing borders from videos
As with images you can remove the border from a video by adding the
CSS border: none;. This:
<video style="border: none;" src="…"></video>
…renders like this:
To turn off borders for all videos add this to your site's stylesheet:
video {
border: none;
}
Customization: removing rounded corners from videos
To remove the rounded corners from a video add
border-radius: 0; to the <video>'s
CSS. This:
<video style="border-radius: 0;" src="…"></video>
…renders like this:
To turn off rounded corners for all videos add this to your site's stylesheet:
video {
border-radius: 0;
}
Audio
Oatcake also supports audio players with
<audio>, again giving them a little more vertical
space to breathe in, aligning them with the vertical rhythm and making
sure that the player controls use all the horizontal width available for
easier scrubbing:
iframes
Finally, the same extra vertical breathing room, borders and rounded
corners are also applied to embedded pages created with
<iframe>:
Details: iframes
Customization: removing borders from iframes
As with images and videos you can remove the border from an iframe by
adding the CSS border: none;. This:
<iframe style="border: none;" src="…"></iframe>
…renders like this:
To turn off borders for all iframes add this to your site's stylesheet:
iframe {
border: none;
}
Customization: removing rounded corners from iframes
To remove the rounded corners from an iframe add
border-radius: 0; to the <iframe>'s
CSS. This:
<iframe style="border-radius: 0;" src="…"></iframe>
…renders like this:
To turn off rounded corners for all iframes add this to your site's stylesheet:
iframe {
border-radius: 0;
}
Figures and captions
Oatcake supports figures and captions with
<figure>
and
<figcaption>. For example, this:
<figure>
<img src="media/spoon.jpg" alt="A wooden spoon full of oats" title="A wooden spoon full of oats">
<figcaption><b>Figure 1:</b> a wooden spoon full of oats.</figcaption>
</figure>
…renders like this:
You can also put the caption above the figure contents if you prefer:
Details: figures and captions
Design notes
As with images, videos and audio players, figures have a little extra vertical breathing space above and below so they don't feel cramped. This applies even if the figure just contains text (e.g. a block quote or code block), not only when the figure contains an image or video.
Both top and bottom figure captions are placed slightly closer to the figure they belong to than to the other content before and after the figure.
Edge case: inline elements in figure captions
All the inline elements work in figure captions:
esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui Usage: figure captions
Captions can be used for additional information about the figure content or its source, and/or to give a figure a number or other label so it can be moved away from the primary content (e.g. to a dedicated figures section or appendix) and referred to from the primary content by its number.
If you add an id attribute to a
<figure> then you can link to it when referring to
it. Here's an example from the HTML Standard:
<p>In <a href="#l4">listing 4</a> we see the primary core
interface API declaration.</p>
<figure id="l4">
<figcaption>Listing 4. The primary core interface API declaration.</figcaption>
<pre><code>interface PrimaryCore {
boolean verifyDataLine();
undefined sendData(sequence<byte> data);
undefined initSelfDestruct();
}</code></pre>
</figure>
Tip: left-aligned figure captions
Oatcake center-aligns figure captions by default. If you want to
left-align a caption add
style="text-align:left;" to the
<figcaption>. This:
<figure>
<img src="media/oats.jpg" alt="A bowl of oats" title="A bowl of oats">
<figcaption style="text-align:left;">
Lorem ipsum dolor sit amet […] Mauris rutrum aliquet libero
vel tempor.
</figcaption>
</figure>
…renders like this:
If you want to left-align all figure captions add this to your site's CSS:
figcaption {
text-align: left;
}
Tip: small text figure captions
Small text can work well for figure captions: wrap the contents of the
<figcaption> in a <small>. This:
<figure>
<img src="media/oats.jpg" alt="A bowl of oats" title="A bowl of oats">
<figcaption>
<small>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</small>
</figcaption>
</figure>
…renders like this:
Tip: anything can go in a figure
Figures aren't just for images. You can put anything in a figure. Here's an example from MDN with some code in a figure:
navigator.
function NavigatorExample() {
let txt = `Browser CodeName: ${navigator.appCodeName};\n`;
txt += `Browser Name: ${navigator.appName};\n`;
txt += `Browser Version: ${navigator.appVersion};\n`;
txt += `Cookies Enabled: ${navigator.cookieEnabled};\n`;
txt += `Platform: ${navigator.platform};\n`;
txt += `User-agent header: ${navigator.userAgent};`;
console.log("NavigatorExample", txt);
}
Here's another example from MDN with a
<blockquote> in a <figure> and
the quote's attribution in the <figcaption>:
If debugging is the process of removing software bugs, then programming must be the process of putting them in.
Preformatted text
You can create a block of preformatted text—where whitespace,
indentation and line breaks are rendered as-is, without compressing or
re-wrapping—using the <pre> element.
Preformatted text blocks look like this in Oatcake:
Heaven and earth aren't humane. To them the thousand things are straw dogs. Wise souls aren't humane. To them the thousand families are straw dogs. Heaven and earth act as a bellows: Empty yet structured, it moves, inexhaustibly giving.
Code blocks
HTML code blocks are created by wrapping the entire contents of a
<pre> in a <code>. This is what
indenting a block of text by four spaces or one tab does in Markdown (or
"fenced code blocks" with ``` in many versions of
Markdown).
Oatcake aims to do more with fewer visual styles, so code blocks look the same as preformatted text blocks but with a monospaced font. This is less distracting for readers and makes Oatcake easier to maintain:
#include <stdio.h>
int main()
{
printf("Hello World!\n");
}
You can use inline elements in preformatted text and code blocks: bold, italics, underline, strikethrough, small text. Here's one with a bunch:
#include <stdio.h>
int main()
{
/* Here's a code comment withsubscript and.superscript */
/* Here's a code comment in small text. */
/* Here's an inline quote
in a code block. */
/* Here's a highlight in a code block. */
/* Here's a link. */
printf("Hello World!\n");
}
Customization: code blocks
You can customize the fonts and colors of code blocks by setting a couple of CSS variables. For example:
<style>
pre:has(> code:only-child),
pre > code:only-child {
--ok-color-block-bg: #282828;
--ok-color-block-fg: #ebdbb2;
--ok-color-border: #d65d03;
--ok-font-family-mono: 'Nimbus Mono PS', 'Courier New', monospace;
}
</style>
Now code blocks will look like this:
#include <stdio.h>
int main()
{
printf("Hello World!\n");
}
Sample output blocks
HTML sample output blocks are created by wrapping the contents
of a <pre> in a <samp> instead of
a <code>. Sample output blocks have a different
semantic meaning than code blocks: they represent a block of computer
output rather than input code.
As with inline <code> and
<samp> elements, Oatcake styles sample output blocks
the same as code blocks, letting the difference be semantic only. This
is to avoid having too many distracting visual styles and because
there's no obvious way to visually indicate the semantic difference
between "code" and "output".
Here's what a sample output block looks like with Oatcake:
_________________________________
/ You are taking yourself far too \
\ seriously. /
---------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Tip: using <pre>, <code>,
<samp>, and <kbd> together
<code>, <samp> and
<kbd> can be mixed together in a single
<pre> block, with different semantic meanings. For
example here the prompt output by the terminal (> ) is
a <samp>, the code entered by the user (console.log(2.3 + 2.4)) is a <code> element, the Enter key
clicked by the user to submit the code is a <kbd>,
and finally the result output by the terminal
(4.699999999999999) is another <samp>.
<code> and <samp> look the same
in Oatcake so the difference is mostly only semantic, except for the
<kbd>.
> console.log(2.3 + 2.4) Enter
4.699999999999999
If you want <samp>'s and
<code>'s to look different in a preformatted text
block you can easily get that by adding a little custom CSS on top of
Oatcake. For example:
<style>
pre code {
font-weight: bold;
}
pre samp {
color: var(--ok-color-muted-fg);
}
<style>
Now the previous example will render like this:
> console.log(2.3 + 2.4) Enter
4.699999999999999
Disclosure widgets
I've already used these extensively in a desperate attempt to control
the length of this page: you can create collapsible disclosure widgets
with
<details> and <summary>. This:
<details>
<summary>Material</summary>
<p>The picture frame is made of solid oak wood.</p>
</details>
…renders like this:
Material
The picture frame is made of solid oak wood.
Details: disclosure widgets
Design notes
To avoid distracting readers with too many different visual styles, Oatcake styles disclosure widgets similarly to preformatted text, code, and sample output blocks: the same background color, border, rounded corners, and padding. The difference is that instead of being preformatted or monospaced, disclosure widgets are collapsible.
For usability Oatcake gives a nice big click-target for opening and closing disclosure widgets (indicated by the background color) and changes the cursor to a "pointer" cursor when it's over this target area.
Tip: pre-opened disclosure widgets with the
open attribute
Adding the open attribute to a
<details> makes it already be open when the page
loads:
This is the summary
And here are the details:
- Cash on hand: $500.00
- Current invoice: $75.30
- Due date: 5/6/19
Tip: mutually-exclusive disclosure widgets with the
name attribute
You can create a mutually-exclusive group of disclosure widgets by
giving them all the same name attribute. Only one
disclosure widget with the same name can be open at the
same time. If the user opens one of the named group of widgets it'll
close any other that's already open. For example, this:
<details name="test">
<summary>This is the first disclosure widget</summary>
These are the first details.
</details>
<details name="test">
<summary>This is the second disclosure widget</summary>
These are the second details.
</details>
<details name="test">
<summary>This is the third disclosure widget</summary>
These are the third details.
</details>
…creates these:
This is the first disclosure widget
These are the first details.This is the second disclosure widget
These are the second details.This is the third disclosure widget
These are the third details.Edge case: raw text nodes in disclosure widgets
If your <details> contains only a single paragraph
you can omit the <p> and it'll look the same. This:
<details>
<summary>Material</summary>
The picture frame is made of solid oak wood.
</details>
…renders like this:
Material
The picture frame is made of solid oak wood.Asides
You can create pull-quotes and call-out boxes with
<aside>.
In-line with Oatcake's consistently unshowy nature, asides are styled the same as preformatted text blocks, code blocks and sample output blocks, and very similarly to disclosure widgets. The difference is that an aside's contents aren't preformatted, monospaced, or collapsible. It's just a box!
This:
<aside>
<p>
People ask me what I do for fun when I'm not at work.
But I'm paid to do my hobby, so I never know what to answer.
</p>
</aside>
…renders like this:
If your <aside> contains only a single paragraph you
can omit the <p> and it'll look the same. This:
<aside>
People ask me what I do for fun when I'm not at work.
But I'm paid to do my hobby, so I never know what to answer.
</aside>
…renders like this:
Details: asides
Usage
<aside>
(HTML Standard,
MDN) is for
content that is tangentially related to the content around the
. MDN defines them as for content that is
aside element, and which could be considered separate
from that contentonly indirectly related to the document's main content.
The HTML standard mentions
typographical effects like pull quotes
as an example use-case
for asides. These can be achieved by putting a
<q> or <blockquote> in an
<aside>. Here's the example that the standard
gives:
He later joined a large company, continuing on the same work.
I love my job. People ask me what I do for fun when I'm not at work. But I'm paid to do my hobby, so I never know what to answer. Some people wonder what they would do if they didn't have to work... but I know what I would do, because I was unemployed for a year, and I filled that time doing exactly what I do now.Of course his work — or should that be hobby? — isn't his only passion. He also enjoys other pleasures.
MDN gives two examples of asides used for
call-out boxes
containing facts related to the main content:
Salamanders are a group of amphibians with a lizard-like appearance, including short legs and a tail in both larval and adult forms.
Several species of salamander inhabit the temperate rainforest of the Pacific Northwest, including the Ensatina, the Northwestern Salamander and the Rough-skinned Newt. Most salamanders are nocturnal, and hunt for insects, worms and other small creatures.
The Disney movie The Little Mermaid was first released to theatres in 1989.
More info about the movie…
The HTML standard gives a similar fact-box example with an
<aside> containing an <h2> and a
<p>—background material on Switzerland in a much longer news story on
Europe
:
Tip: begin an aside with a text label
Don't rely on the CSS to convey the meaning of an aside, the contents should make the semantics clear. Beginning an aside with a label in bold can help:
Tip: you can use an <hr> to split an aside
into segments
Customization: aside colors
It was tempting to provide a variety of different colors for asides like other frameworks do. But documents with lots of different-colored boxes would distract from both reading and writing (always having to remember all the different types of boxes and choose which one to use) and would make it harder to add support for dark mode and for different color schemes in future.
If you do want to make asides in more interesting colors you can add your own CSS classes to do so. For example:
<style>
aside.warning {
background-color: rgb(248, 215, 218);
border-color: #f1aeb5;
}
</style>
Now this:
<aside class="warning">
<strong>Warning!</strong>
Too many asides can overwhelm the reader.
</aside>
…will render like this:
Customization: aside design
You can change the design of asides by adding your own CSS. For example:
<style>
aside {
border-left: none;
border-right: none;
border-radius: 0;
background-color: inherit;
font-weight: 300;
}
</style>
Now <aside>'s will look like this:
Footers
Oatcake styles <footer> elements with text in a muted
color. This:
<footer>
<strong>Posted:</strong> Wed 14 August 2019 ·
<strong>Tags:</strong> <a href="#">HTML</a>,
<a href="#">CSS</a>
</footer>
…renders like this:
All the inline elements work in footers, but elements that would
normally stand out like
links, highlights and code have
a more muted style:
You can wrap the contents of a <footer> in a
<small> to create a small-text footer:
Usage: footers
A <footer> (HTML Standard,
MDN) represents a footer for its nearest containing
<article>, <aside>,
<nav>, <section> or the
<body>. The HTML standard describes footers as
typically containing information about the author, links to related
documents, copyright data, etc. Examples given in the standard include
navigation links, publication dates, author credits and contact
information, links for editing, deleting and renaming an article, etc.
Footers don't need to be at the end of a section.
Horizontal rules
Finally, here's what an <hr> (a horizontal rule
representing a thematic break like a change of scene or topic) looks
like with Oatcake:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean condimentum vulputate turpis, in congue nisl tempor a.
Suspendisse potenti. Aliquam erat volutpat. Sed luctus felis et metus viverra eleifend.
Wrapping and horizontal scrollbars
Oatcake forces long words to wrap if necessary
Long unbroken words or other strings (such as URLs) that are too long to fit on one line (even with a whole line to themselves) can overflow their containers, especially on mobile, causing unwanted horizontal scrollbars or other layout breakage. Oatcake fixes this by wrapping long words over multiple lines if necessary to prevent overflow.
This really long Sanskrit word will get wrapped: िरन्तरान्धकारित-दिगन्तर-कन्दलदमन्द-सुधारस-बिन्दु-सान्द्रतर-घनाघन-वृन्द-सन्देहकर-स्यन्दमान-मकरन्द-बिन्दु-बन्धुरतर-माकन्द-तरु-कुल-तल्प-कल्प-मृदुल-सिकता-जाल-जटिल-मूल-तल-मरुवक-मिलदलघु-लघु-लय-कलित-रमणीय-पानीय-शालिका-बालिका-करार-विन्द-गलन्तिका-गलदेला-लवङ्ग-पाटल-घनसार-कस्तूरिकातिसौरभ-मेदुर-लघुतर-मधुर-शीतलतर-सलिलधारा-निराकरिष्णु-तदीय-विमल-विलोचन-मयूख-रेखापसारित-पिपासायास-पथिक-लोकान्.
So will this really long URL in a <code> tag:
https://github.com/seanh/oatcake/commit/8675ffcb168b1d76d708c84a2821c20a3f99e86d.
You can insert <wbr> elements into words to tell the
browser about good points to wrap the word. This example from the HTML
Standard:
<p>So then she pointed at the tiger and screamed
"there<wbr>is<wbr>no<wbr>way<wbr>you<wbr>are<wbr>ever<wbr>going<wbr>to<wbr>catch<wbr>me"!</p>
…renders like this:
So then she pointed at the tiger and screamed "thereis no way you are ever going to catch me"!
Oatcake prevents wrapping within certain elements
Oatcake prevents any wrapping inside preformatted text
(<pre>) blocks (including code and sample output
blocks)—you don't want your code or other preformatted text being
wrapped for you. So to prevent them from stretching out the width of the
page or causing a page-level horizontal scrollbar, preformatted blocks
get their own internal horizontal scrollbar if necessary:
url = 'https://github.com/seanh/oatcake/commit/8675ffcb168b1d76d708c84a2821c20a3f99e86d'
A horizontal scrollbar is also used to prevent wrapping in long
<summary>'s:
This is a really long <summary> element that will
get a horizontal scrollbar rather than wrapping.
These are the details.
Oatcake also prevents wrapping within certain inline elements:
<kbd>'s, and within headings:
<code> and <samp>. To avoid
horizontal scrollbars don't put anything too long in any of these
elements.
Tables
Tables get a pared-down look and the same colors and vertical rhythm as
Oatcake uses for other elements. The design is blatantly appropriated
from the tables in
Tailwind CSS Typography, with added support for the <caption> element for
table captions:
| Wrestler | Origin | Finisher |
|---|---|---|
| Bret "The Hitman" Hart | Calgary, AB | Sharpshooter |
| Stone Cold Steve Austin | Austin, TX | Stone Cold Stunner |
| Randy Savage | Sarasota, FL | Elbow Drop |
| Vader | Boulder, CO | Vader Bomb |
| Razor Ramon | Chuluota, FL | Razor's Edge |
Forms
Won't fix! Oatcake is for styling articles, posts, etc: think Markdown files. It's not meant for creating apps, UIs, forms, etc.