mirror of
https://git.sr.ht/~seirdy/seirdy.one
synced 2024-11-24 05:02:10 +00:00
343 lines
11 KiB
CSS
343 lines
11 KiB
CSS
/* CSS that adds the bare minimum for a simple layout.
|
|
* Nothing here exists purely for aesthetics; everything addresses a
|
|
* specific a11y, compatibility, or critical
|
|
* usability need.
|
|
*
|
|
* 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 .125em. Pixels are 1px or
|
|
* multiples of 3px; percentages are in increments of 2.5%. 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. */
|
|
font-size: 107.5%;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* Compensate for misalignment and wasted space caused by padding
|
|
* and margin adjustments in nav children made to meet SC 2.5.5 */
|
|
dt > a,
|
|
header > nav,
|
|
footer > nav,
|
|
h2 + a {
|
|
margin-left: -.25em;
|
|
}
|
|
header > nav {
|
|
margin-bottom: -.75em;
|
|
}
|
|
footer > nav {
|
|
margin-top: -.75em;
|
|
}
|
|
|
|
summary {
|
|
/* The tappable region of a <summary> extends across the page.
|
|
* we need to tell users that the full space is interactive.
|
|
* Use a border for that. */
|
|
border: 1px solid #999;
|
|
/* 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. */
|
|
li details {
|
|
margin: .5em .25em;
|
|
}
|
|
|
|
/* Google a11y: ensure tap targets have >=8px space between them */
|
|
nav li,
|
|
li details li {
|
|
padding: 1em 0;
|
|
}
|
|
|
|
/* 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. */
|
|
dt,
|
|
dt > a,
|
|
summary,
|
|
h2 + a,
|
|
li > a {
|
|
padding: .875em .25em;
|
|
}
|
|
|
|
nav li ol {
|
|
/* Don't duplicate bottom space: the last list item in the nested
|
|
* list and the list item that is the entire nested list will both
|
|
* have bottom padding */
|
|
margin-bottom: -1em;
|
|
/* Prevent nested lists from overlapping */
|
|
padding-top: 1em;
|
|
}
|
|
}
|
|
|
|
/* 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.625em;
|
|
}
|
|
|
|
ol ol,
|
|
ul ul {
|
|
-webkit-hyphens: auto;
|
|
hyphens: auto;
|
|
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
|
|
}
|
|
|
|
/* 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: .375em;
|
|
}
|
|
|
|
|
|
/* narrow screens: reduce margin for blockquotes a lot, using
|
|
* a border instead. Put it on the left and right to make it
|
|
* LTR/RTL-neutral, for machine translators that change text
|
|
* direction (e.g. the one in Edge). */
|
|
blockquote {
|
|
border-left: 3px solid;
|
|
margin: 0;
|
|
padding: 0 1em;
|
|
}
|
|
|
|
/* Narrow screens: allow hyphenating titles
|
|
* I can't add soft hyphens to these. */
|
|
h1 {
|
|
-webkit-hyphens: auto;
|
|
hyphens: auto;
|
|
}
|
|
|
|
/* Very narrow screens: full hyphenation */
|
|
@media (max-width: 13em) {
|
|
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. */
|
|
kbd {
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* 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 */
|
|
span[hidden] {
|
|
display: 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.
|
|
* This is Technique C25 of SC 1.4.8 */
|
|
img,
|
|
pre {
|
|
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 0.125em;
|
|
}
|
|
|
|
/* 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. */
|
|
picture > img {
|
|
display: block;
|
|
height: auto;
|
|
margin: auto;
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* Some images look blurry when scaled; this makes them easier to
|
|
* read. */
|
|
.pix {
|
|
image-rendering: pixelated;
|
|
}
|
|
|
|
/* WCAG Technique C25: use borders to separate sections.
|
|
* Also use "content-visibility: auto" to improve performance by
|
|
* reducing the number of DOM nodes rendered at once. */
|
|
aside,
|
|
footer,
|
|
section[role="doc-endnotes"],
|
|
section[aria-labelledby="webmentions"] {
|
|
border-top: 1px solid;
|
|
content-visibility: auto;
|
|
}
|
|
|
|
|
|
/* 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 {
|
|
outline: 3px solid;
|
|
}
|
|
|
|
/* Remove :focus styling for browsers that do support :focus-visible */
|
|
@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.
|
|
* */
|