mirror of
https://git.sr.ht/~seirdy/seirdy.one
synced 2024-12-26 02:22:09 +00:00
297ad1e5cb
This one is simpler than the last attempt, since it doesn't overlap with any content except the navbar links' empty padding.
469 lines
14 KiB
CSS
469 lines
14 KiB
CSS
/* CSS that adds the bare minimum for a simple, accessible,
|
|
* touch-friendly layout.
|
|
* Nothing here exists purely for aesthetics; everything addresses a
|
|
* specific a11y, compatibility, or critical
|
|
* usability need.
|
|
*
|
|
* One exception: I re-set the input styles so Safari wouldn't make them
|
|
* pill-shaped.
|
|
*
|
|
* I also don't use any classes except for image presentation. (e.g. to
|
|
* specify that an image should have pixelated rendering or be inverted
|
|
* in dark mode).
|
|
* My HTML contains microformats2 classnames for IndieWeb parsers, but I
|
|
* don't actually use those for styling.
|
|
*
|
|
* To keep myself from caring about minute details, I limited myself to
|
|
* only defining spacing in increments of .25em. Pixels are 1px or
|
|
* multiples of 3px. This also improves compression. No more "finding
|
|
* the perfect value".
|
|
*
|
|
* I cite WCAG 2.2 success criteria with "SC". I also tried to meet
|
|
* the Google a11y requirement of 48px tap targets separated by atl
|
|
* 8px, excluding inline links. This involved increasing font size,
|
|
* padding, line-height, and margins. */
|
|
|
|
html {
|
|
/* Mobile screens benefit from greater line-spacing so links are
|
|
* further apart. Dyslexic users prefer the spacing too.
|
|
* Necessary to meet SC 1.4.8.
|
|
* <100dpi screens: sans-serif is better. Why did browsers settle
|
|
* on serif being the default?? */
|
|
font: 100%/1.5 sans-serif;
|
|
/* Nearly every page on my site is taller than the viewport.
|
|
* Paint the scrollbar ASAP to prevent layout shifts. */
|
|
overflow-y: scroll;
|
|
}
|
|
|
|
/* This should not take effect on printouts, to save paper. */
|
|
@media screen {
|
|
body {
|
|
/* Default font sizes are one-size-fits-all; they're optimized for a
|
|
* wide variety of complex pages. For single-column websites like
|
|
* mine, it's ideal to bump it up ever so slightly. This also makes
|
|
* <sup>, <sub>, <small>, etc. large enough to have decent contrast
|
|
* with minimal adjustment, and makes tap-targets larger.
|
|
* Only do this on screen, since printouts already improve legibility
|
|
* and cost paper + ink.
|
|
* 108.75% is the minimum required to get superscripts to reach 14.5
|
|
* CSS pixels with most default stylesheets. At that size, my dark
|
|
* color palette has sufficient contrast.*/
|
|
font-size: 108.75%;
|
|
|
|
/* Aligning to the center with space on both sides prevents accidental
|
|
* link activation on tablets, and is a common practice that users are
|
|
* more used to for articles. */
|
|
margin: auto;
|
|
|
|
/* WCAG recommends a max line width. Not everyone can resize the
|
|
* viewport. This isn't for large blocks of text yet, so we don't have
|
|
* to go by SC 1.4.8.
|
|
* 45em = lowest acceptable width for titles, nav, footers, etc */
|
|
max-width: 45em;
|
|
|
|
/* Phone cases can cover the edges. Swipe-from-edge navigations
|
|
* should not conflict with the page elements. Focus outlines for
|
|
* heavily-padded nav links should not be cut-off. All three concerns
|
|
* are addressed by adding some body padding.
|
|
* I followed Google's a11y recommendations of "at least 8px space
|
|
* between tappables" by creating margins/paddings between nav links;
|
|
* re-use that same amount of space here. 24px is what it takes to
|
|
* create atl 48px of non-interactive space on <ul> and <ol> elements
|
|
* containing lists of interactives, with 8px in between.
|
|
* Don't use relative units here; this margin shouldn't scale with
|
|
* zoom, or else text will get narrower with zoom. */
|
|
padding: 0 24px;
|
|
}
|
|
|
|
/* 45em is too wide for long body text.
|
|
* Typically meets SC 1.4.8, plus or minus a few characters. */
|
|
div[itemprop="articleBody"] {
|
|
margin: auto;
|
|
max-width: 35em;
|
|
}
|
|
|
|
summary {
|
|
/* It's not obvious that a <summary> has button semantics.
|
|
* "cursor: pointer" is used on MDN, web.dev, GitHub, gov.uk, and
|
|
* others so it's not "novel" and won't surprise users. */
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* If we have a list of disclosure widgets, we need some
|
|
* non-interactive space on the screen that's safe to tap. */
|
|
form,
|
|
li details {
|
|
margin: .5em 0;
|
|
}
|
|
|
|
/* Make superscripts a bit easier to tap. */
|
|
sup > a {
|
|
margin-left: .25em;
|
|
padding-bottom: .25em;
|
|
}
|
|
|
|
/* SC 2.5.5, Google a11y: Increase tap target size a bit
|
|
* - Summary is a tappable button
|
|
* - standalone links in lists are usually parts of collections of
|
|
* links that should be easy to fat-finger
|
|
* - links that directly follow h2 without being contained in a
|
|
* paragraph are section permalinks. */
|
|
|
|
input,
|
|
div[itemprop="comment"] dd > a,
|
|
dt > a,
|
|
summary,
|
|
nav[itemprop="breadcrumb"] a,
|
|
nav[itemprop="breadcrumb"] > span,
|
|
aside > a, /* Used for section permalinks */
|
|
li > a {
|
|
padding: .75em .25em;
|
|
}
|
|
|
|
/* Compensate for misalignment and wasted space caused by padding
|
|
* and margin adjustments in nav children made to meet SC 2.5.5
|
|
* Also prevent overlapping outlines on focus */
|
|
|
|
/* We've increased the padding for dt > a, but dt without a link
|
|
* should take up as much space. */
|
|
dt {
|
|
margin: .75em 0;
|
|
}
|
|
|
|
dt > a {
|
|
margin: -.75em 0 -.75em -.25em;
|
|
display: inline-block;
|
|
}
|
|
|
|
/* <dt> should not be closer to the previous <dd> than the following <dd>.
|
|
* That can happen in webmentions. */
|
|
dd {
|
|
padding-bottom: .25em;
|
|
}
|
|
|
|
aside > a {
|
|
margin: -.75em -.25em;
|
|
}
|
|
|
|
header a[href="#main"],
|
|
div[itemprop="comment"] dd > a ,
|
|
footer > nav,
|
|
/* List items with direct hyperlink children should only have one hyperlink. */
|
|
li > a,
|
|
aside > a,
|
|
nav ol a {
|
|
margin-left: -.25em;
|
|
display: inline-block;
|
|
}
|
|
|
|
/* The nav has to be distant-enough from the top to make room for a skip-link. */
|
|
header > nav {
|
|
margin: .75em 0 0 -.25em;
|
|
display: block;
|
|
}
|
|
|
|
/* Multiple consecutive <dt> that share a <dd> shouldn't have tap targets overlap */
|
|
dt + dt > a {
|
|
padding-top: 0;
|
|
}
|
|
|
|
nav:not([itemprop="breadcrumb"]) li,
|
|
ol li > a {
|
|
margin: .25em;
|
|
}
|
|
|
|
/* Increase backlink tap target size */
|
|
a[role="doc-backlink"] {
|
|
padding: 0 1.75em 1.5em .25em;
|
|
}
|
|
|
|
/* Make room for those big backlink buttons so they don't overlap
|
|
* with links on the following endnote */
|
|
section[role="doc-endnotes"] li {
|
|
margin-bottom: 1.75em;
|
|
}
|
|
|
|
header a[href="#main"] {
|
|
position: absolute;
|
|
top: -2em;
|
|
padding: 0 .25em;
|
|
}
|
|
|
|
header a[href="#main"]:focus {
|
|
top: 0;
|
|
}
|
|
}
|
|
|
|
/* narrow screens: reduce list indentation, hyphenate nested lists
|
|
* touch screens: lists of links should be easy to tap so give them
|
|
* some spacing (partial SC 2.5.5). There should be non-interactive
|
|
* space to the left that's safe to tap. */
|
|
dd,
|
|
ol,
|
|
ul {
|
|
margin: 0;
|
|
padding-left: 1.5em;
|
|
}
|
|
|
|
blockquote,
|
|
ol ol,
|
|
ul ul {
|
|
-webkit-hyphens: auto;
|
|
hyphens: auto;
|
|
margin: 0;
|
|
padding-left: 1em;
|
|
}
|
|
|
|
/* Save some space and paper by making the site nav and footer links
|
|
* single-line without bullets. The title should be visible in the fold
|
|
* on most screens so users can identify the current page. */
|
|
|
|
/* Step 1 to making the single-line nav: remove the bullet padding. */
|
|
nav ul {
|
|
padding: 0;
|
|
}
|
|
|
|
/* Make breadcrumbs inline, so they look familiar. */
|
|
nav[itemprop="breadcrumb"] ol,
|
|
nav[itemprop="breadcrumb"] li,
|
|
nav[itemprop="breadcrumb"] > span {
|
|
display: inline-block;
|
|
}
|
|
|
|
nav[itemprop="breadcrumb"] ol {
|
|
margin: -.25em 0;
|
|
padding: 0;
|
|
}
|
|
|
|
nav[itemprop="breadcrumb"] li:not(:last-of-type)::after {
|
|
content: "→";
|
|
}
|
|
|
|
/* step 2: remove bullets and make elements inline.
|
|
* Also: bump up the line-height and margins to increase space
|
|
* between tap-targets (SC 2.5.5). Google a11y guidelines require 8 CSS
|
|
* pixels between tap targets. */
|
|
nav ul li {
|
|
display: inline-block;
|
|
margin-right: .5em;
|
|
}
|
|
/* narrow screens: we reduce margin for blockquotes a lot, using
|
|
* a border instead. */
|
|
blockquote {
|
|
border-left: 3px solid;
|
|
}
|
|
|
|
/* Narrow screens: allow hyphenating titles
|
|
* I can't add soft hyphens to these. */
|
|
h1 {
|
|
-webkit-hyphens: auto;
|
|
hyphens: auto;
|
|
}
|
|
|
|
/* Very narrow screens: full hyphenation.
|
|
* This is the typical width of a smart feature phone. */
|
|
@media (max-width: 15em) {
|
|
body {
|
|
font-size: 100%;
|
|
-webkit-hyphens: auto;
|
|
hyphens: auto;
|
|
padding: 0 8px;
|
|
}
|
|
}
|
|
|
|
/* <kbd> should be distinguished from <code> and surrounding text
|
|
* in a way beyond font-face; at least two visual distinctions needed
|
|
* Also, Small text is easier to read when slightly bolder.
|
|
* This is important in the dark theme where I set my own colors and
|
|
* try to maintain good perceptual contrast even for small text, but
|
|
* I don't want toggling the theme to impact anything besides color so
|
|
* I set the weight here. */
|
|
dt,
|
|
kbd {
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* <ins> should not be mistaken for hyperlinks.
|
|
* "note" roles should look distinct. */
|
|
ins,
|
|
[role="note"],
|
|
[role="doc-tip"] {
|
|
font-style: italic;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/* narrow screens: remove unused figure margins
|
|
* figure captions shouldn't look like regular paragraphs; there should
|
|
* be some extra space.
|
|
* This does not hold true for figures in somewhat distinct sections; the
|
|
* section should instead get the spacing. A section that constitutes a
|
|
* separate schema.org object would qualify. */
|
|
section[itemprop="mentions"],
|
|
figure {
|
|
margin: 1.5em 0;
|
|
}
|
|
|
|
section[itemprop="mentions"] > figure {
|
|
margin: 0;
|
|
}
|
|
|
|
/* browsers make monospace small and unreadable for some dumb legacy
|
|
* reason and this somehow fixes that without overriding the user's
|
|
* font size preferences. */
|
|
code,
|
|
kbd,
|
|
pre, /* Needed for ancient browsers */
|
|
samp {
|
|
font-family: monospace, monospace;
|
|
}
|
|
|
|
/* Some browsers don't support the hidden attr.
|
|
* I use hidden spans in backlinks to provide ARIA labels.
|
|
* Some ancient browsers don't support input[type="hidden"] */
|
|
span[hidden],
|
|
input[type="hidden"] {
|
|
display: none;
|
|
}
|
|
|
|
/* Remove list style from data feeds. */
|
|
main[itemtype="https://schema.org/DataFeed"] > ol {
|
|
padding: 0;
|
|
list-style-type: none;
|
|
}
|
|
|
|
/* Narrow screens: long words can cause content to flow out of the
|
|
* viewport, triggering horizontal scrolling. Allow breaking words in
|
|
* content I don't control (comments, names). For content I do control,
|
|
* I just add soft hyphens to the HTML. */
|
|
div[itemprop="comment"],
|
|
:not(pre) > code,
|
|
:not(pre) > samp,
|
|
span[itemtype="https://schema.org/Person"] {
|
|
overflow-wrap: break-word;
|
|
}
|
|
|
|
/* Narrow screens: allow horizontal scroll in a pre block. */
|
|
pre {
|
|
overflow: auto;
|
|
padding: .5em;
|
|
}
|
|
|
|
/* Distinguish images from the background in case their color is
|
|
* too similar to the page background color. Also put a border around
|
|
* <pre> and <code> to distinguish them in ways besides font-family.
|
|
* The tappable region of a <summary> extends across the page: we
|
|
* need to tell users that the full space is interactive.
|
|
* This is Technique C25 of SC 1.4.8 */
|
|
input,
|
|
img,
|
|
mark, /* borders provide a distinguishing factor besides color */
|
|
pre,
|
|
summary {
|
|
border: 1px solid;
|
|
}
|
|
|
|
/* A black border is too harsh; the extra visual noise is distracting
|
|
* to users with eye-tracking or ADHD. Only special items like headings
|
|
* should draw gaze. */
|
|
:not(pre) > code,
|
|
:not(pre) > samp {
|
|
border: 1px solid #999;
|
|
|
|
/* borders shouldn't touch text */
|
|
padding: 0 .25em;
|
|
}
|
|
|
|
/* center standalone images; same justification as
|
|
* for centering the body contents. Also makes images easier to see
|
|
* for people holding a device with one hand. */
|
|
div[itemprop="articleBody"] img {
|
|
display: block;
|
|
height: auto;
|
|
margin: auto;
|
|
max-width: 100%;
|
|
}
|
|
|
|
audio {
|
|
width: 100%;
|
|
}
|
|
|
|
/* Some images look blurry when scaled; this makes them easier to
|
|
* read. */
|
|
.pix {
|
|
image-rendering: pixelated;
|
|
}
|
|
|
|
/* Make search box and submit button as wide as possible while keeping
|
|
* them next to each other. */
|
|
|
|
/* Use table-style layout (no, not actual tables. eww.). It's like a
|
|
* single-row flexbox that supports more browsers. Kanged this CSS from
|
|
* ww.gov.uk. Give the entire width of the row to the search box, but
|
|
* allow the minimum width for the submit button. */
|
|
legend, /* Makes the <legend> wrap text in some browsers. */
|
|
form > div {
|
|
display: table;
|
|
width: 100%
|
|
}
|
|
|
|
input {
|
|
/* Browsers like Safari make the submit button pill-shaped which
|
|
* clashes with the input box. The only purely-cosmetic change on this
|
|
* site. */
|
|
appearance: none;
|
|
|
|
/* Don't shrink the size of the text in forms or make it system-ui. */
|
|
font-family: sans-serif;
|
|
font-size: inherit;
|
|
}
|
|
|
|
/* A text box should take all available width */
|
|
input:not([type="submit"]) {
|
|
display: table-cell;
|
|
width: 98%;
|
|
}
|
|
|
|
/* Pseudo-table-cell containing the submit button */
|
|
form > div > div {
|
|
display: table-cell;
|
|
vertical-align: top; /* IE and some botique browsers need this */
|
|
width: 1%;
|
|
}
|
|
|
|
|
|
/* Some browser focus indicators are inaccessible; override them with
|
|
* something more visible. See WCAG 2.x SC 2.4.12. I also tried to
|
|
* match browser behavior; mainstream browsers use :focus-visible
|
|
* instead of focus but older/simpler browsers only support :focus.
|
|
* I borrowed these directives from
|
|
* https://www.tempertemper.net/blog/refining-focus-styles-with-focus-visible
|
|
* To my knowledge: <a>, <summary>, and <pre tabindex=0> are the only
|
|
* focusable elements.
|
|
* */
|
|
|
|
a:focus,
|
|
summary:focus,
|
|
pre[tabindex]:focus,
|
|
form :focus {
|
|
outline: 3px solid;
|
|
}
|
|
|
|
/* Remove :focus styling for browsers that do support :focus-visible.
|
|
* Leave it on for form stuff. */
|
|
@supports selector(:focus-visible) {
|
|
a:focus:not(:focus-visible),
|
|
summary:focus:not(:focus-visible),
|
|
pre[tabindex]:focus:not(:focus-visible) {
|
|
outline: none;
|
|
}
|
|
}
|
|
|
|
/* Todo:
|
|
* - Some browsers don't scale SVGs properly; the img container
|
|
* dimensions crop the image rather than scale it. Investigate
|
|
* if this only applies to Internet Explorer or if it applies to
|
|
* other uncommon browsers too. If any non-IE browsers do this and/or
|
|
* if the spec allows this behavior, try to correct it here.
|
|
* - Wait till Webkit fixes its broken-ass default dark stylesheet
|
|
* then consider trimming the dark stylesheet I provide.
|
|
* */
|