1986 lines
76 KiB
HTML
1986 lines
76 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
|
|
|
|
<title>core CSS | hello hello</title>
|
|
<meta name="description" content="Lee Cattarin... on the internet!">
|
|
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="hello hello">
|
|
|
|
<meta property="og:title" content="core CSS | hello hello">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:description" content="Lee Cattarin... on the internet!">
|
|
<meta property="og:site_name" content="hello hello">
|
|
|
|
<meta property="og:image" content="/img/core-css.png">
|
|
<meta property="og:image:alt" content="A website mockup in dark mode with light pink accents. Everything is filler text such as the title 'This is my cool website', headers reading things like 'This is an h1', nav items 'Nav item 1', etc. There is a paragraph block - the opening of the Bee Movie - and part of an image visible - a screencap of the music video for Never Gonna Give You Up by Rick Astley.">
|
|
|
|
|
|
<meta name="generator" content="Eleventy v3.1.2">
|
|
|
|
<meta itemprop="ai-content-declaration:version" content="1.0.0">
|
|
<meta itemprop="ai-content-declaration:level" content="none">
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
|
|
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
|
|
|
|
|
|
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style>.post-metadata {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
justify-content: space-between;
|
|
align-items: baseline;
|
|
margin: 1.5rem 0 .5rem;
|
|
}
|
|
|
|
.post-metadata p {
|
|
font-size: .9rem;
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
gap: .5rem;
|
|
list-style: none;
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags li {
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags li a {
|
|
text-decoration: none;
|
|
color: var(--color-teal);
|
|
padding: 0 .5rem;
|
|
border-radius: 1rem;
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
border: .08rem solid var(--color-teal);
|
|
line-height: 2;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
transition: top .1s ease-in, left .1s ease-in;
|
|
}
|
|
|
|
.post-tags li a:focus-visible {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.post-tags li a:hover {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
.post-tags li a:focus-visible {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.post-tags li a:hover {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
.post-tags li a:active {
|
|
top: .1rem;
|
|
left: .1rem;
|
|
box-shadow: .05rem .05rem var(--color-shadow);
|
|
}
|
|
/* Adapted from PrismJS 1.30.0 Tomorrow Night theme
|
|
https://prismjs.com/download
|
|
*/
|
|
code,
|
|
pre,
|
|
code[class*=language-],
|
|
pre[class*=language-] {
|
|
font-family: var(--font-family-code);
|
|
background-color: var(--color-bg-alt);
|
|
font-size: .9em;
|
|
text-shadow: 0 1px var(--color-shadow);
|
|
-moz-tab-size: 4;
|
|
-o-tab-size: 4;
|
|
tab-size: 4;
|
|
-webkit-hyphens: none;
|
|
-moz-hyphens: none;
|
|
-ms-hyphens: none;
|
|
hyphens: none;
|
|
}
|
|
|
|
pre,
|
|
pre[class*=language-] {
|
|
margin: 1rem 0;
|
|
padding: 1rem;
|
|
line-height: 1.5;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
overflow-wrap: break-word;
|
|
border-radius: .5rem;
|
|
overflow: auto;
|
|
}
|
|
|
|
:not(pre)>code,
|
|
:not(pre)>code[class*=language-] {
|
|
padding: .2rem;
|
|
border-radius: .25rem;
|
|
white-space: normal;
|
|
}
|
|
|
|
/* Selected text */
|
|
code ::-moz-selection,
|
|
code::-moz-selection,
|
|
pre ::-moz-selection,
|
|
pre::-moz-selection,
|
|
code[class*=language-] ::-moz-selection,
|
|
code[class*=language-]::-moz-selection,
|
|
pre[class*=language-] ::-moz-selection,
|
|
pre[class*=language-]::-moz-selection,
|
|
code ::selection,
|
|
code::selection,
|
|
pre ::selection,
|
|
pre::selection,
|
|
code[class*=language-] ::selection,
|
|
code[class*=language-]::selection,
|
|
pre[class*=language-] ::selection,
|
|
pre[class*=language-]::selection {
|
|
text-shadow: none;
|
|
background-color: var(--color-bg);
|
|
}
|
|
|
|
/* Syntax highlighting */
|
|
.token.namespace {
|
|
opacity: .7;
|
|
}
|
|
|
|
.token.bold,
|
|
.token.important {
|
|
font-weight:700
|
|
}
|
|
|
|
.token.italic {
|
|
font-style:italic
|
|
}
|
|
|
|
.token.block-comment,
|
|
.token.cdata,
|
|
.token.comment,
|
|
.token.doctype,
|
|
.token.prolog,
|
|
.token.punctuation {
|
|
color: var(--color-grey);
|
|
}
|
|
|
|
.token.attr-name,
|
|
.token.deleted,
|
|
.token.namespace,
|
|
.token.tag {
|
|
color: var(--color-red);
|
|
}
|
|
|
|
.token.boolean,
|
|
.token.function,
|
|
.token.number {
|
|
color: var(--color-orange);
|
|
}
|
|
|
|
.token.class-name,
|
|
.token.constant,
|
|
.token.property,
|
|
.token.symbol {
|
|
color: var(--color-yellow);
|
|
}
|
|
|
|
.token.attr-value,
|
|
.token.char,
|
|
.token.regex,
|
|
.token.string,
|
|
.token.variable,
|
|
.token.inserted {
|
|
color: var(--color-green);
|
|
}
|
|
|
|
.token.entity,
|
|
.token.operator,
|
|
.token.url,
|
|
.token.function-name {
|
|
color:var(--color-blue);
|
|
}
|
|
|
|
.token.atrule,
|
|
.token.builtin,
|
|
.token.important,
|
|
.token.keyword,
|
|
.token.selector {
|
|
color: var(--color-purple);
|
|
}
|
|
#postlist,
|
|
#taglist {
|
|
list-style: none;
|
|
}
|
|
|
|
#postlist, .post,
|
|
#taglist, .tag {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Odd-numbered posts & tag layout/coloration */
|
|
.post:nth-child(odd) .postlink,
|
|
.tag:nth-child(odd) .taglink {
|
|
grid-template-areas:
|
|
'img h2'
|
|
'img info'
|
|
'img .';
|
|
grid-template-columns: 45% auto;;
|
|
--color-primary: var(--color-teal);
|
|
--color-accent: var(--color-pink);
|
|
}
|
|
|
|
/* Even-numbered posts & tags layout/coloration */
|
|
.post:nth-child(even) .postlink,
|
|
.tag:nth-child(even) .taglink {
|
|
grid-template-areas:
|
|
'h2 img'
|
|
'info img'
|
|
'. img';
|
|
grid-template-columns: auto 45%;
|
|
--color-primary: var(--color-pink);
|
|
--color-accent: var(--color-teal);
|
|
}
|
|
|
|
/* Layout for all posts on mobile */
|
|
@media (max-width: 650px) {
|
|
.post:nth-child(n) .postlink,
|
|
.tag:nth-child(n) .taglink {
|
|
grid-template-areas:
|
|
'img'
|
|
'h2'
|
|
'info';
|
|
grid-template-columns: auto;
|
|
}
|
|
}
|
|
|
|
/* Link */
|
|
.postlink,
|
|
.taglink {
|
|
display: grid;
|
|
border: .25rem solid var(--color-primary);
|
|
border-radius: 1.25rem;
|
|
box-shadow: .35rem .35rem var(--color-shadow);
|
|
margin: 2rem 0;
|
|
text-decoration: none;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
transition: top .05s ease-in, left .05s ease-in;
|
|
}
|
|
|
|
.postlink:focus-visible,
|
|
.taglink:focus-visible {
|
|
background-color: var(--color-primary);
|
|
outline: none;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.postlink:hover,
|
|
.taglink:hover {
|
|
background-color: var(--color-primary);
|
|
}
|
|
}
|
|
|
|
/* Forced colors */
|
|
@media (forced-colors: active) {
|
|
.postlink:focus-visible,
|
|
.taglink:focus-visible {
|
|
outline-offset: .25rem;
|
|
outline: .25rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.postlink:hover,
|
|
.taglink:hover {
|
|
outline-offset: .25rem;
|
|
outline: .25rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
.postlink:active,
|
|
.taglink:active {
|
|
box-shadow: none;
|
|
top: .2rem;
|
|
left: .2rem;
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
}
|
|
|
|
/* Post & tag elements */
|
|
.post h2, .post img,
|
|
.post ul, .post li,
|
|
.tag h2, .tag p,
|
|
.tag img {
|
|
margin: 0;
|
|
}
|
|
|
|
.post h2,
|
|
.tag h2 {
|
|
grid-area: h2;
|
|
padding: .25rem .5rem;
|
|
text-transform: uppercase;
|
|
font-size: 1.5rem;
|
|
color: var(--color-primary);
|
|
border-radius: 1rem 1rem 0 0;
|
|
border-bottom: .25rem solid var(--color-accent);
|
|
}
|
|
|
|
.post:nth-child(even) h2,
|
|
.tag:nth-child(even) h2 {
|
|
text-align: right;
|
|
}
|
|
|
|
.postlink:focus-visible h2,
|
|
.taglink:focus-visible h2 {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.postlink:hover h2,
|
|
.taglink:hover h2 {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
/* Images */
|
|
.post img,
|
|
.tag-imgs {
|
|
grid-area: img;
|
|
}
|
|
|
|
.blur {
|
|
filter: blur(.75rem);
|
|
clip-path: inset(0 round 1rem);
|
|
}
|
|
|
|
.tag-imgs {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: .15rem;
|
|
}
|
|
|
|
.tag-imgs img {
|
|
aspect-ratio: 3 / 2;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.missing-image {
|
|
width: 100%;
|
|
aspect-ratio: 3 / 2;
|
|
background-color: var(--color-bg-alt);
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
.taglink:focus-visible .missing-image {
|
|
opacity: .7;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.taglink:hover .missing-image {
|
|
opacity: .7;
|
|
}
|
|
}
|
|
|
|
/* Post tags */
|
|
.postlist-tags {
|
|
grid-area: info;
|
|
list-style: none;
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
gap: .5rem;
|
|
padding: .5rem;
|
|
}
|
|
|
|
.post:nth-child(odd) .postlist-tags {
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.postlist-tags li,
|
|
.tagcount {
|
|
background-color: var(--color-primary);
|
|
color: var(--color-bg);
|
|
padding: 0 .5rem;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
.postlink:focus-visible .postlist-tags li,
|
|
.taglink:focus-visible .tagcount {
|
|
background-color: var(--color-bg);
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.postlink:hover .postlist-tags li,
|
|
.taglink:hover .tagcount {
|
|
background-color: var(--color-bg);
|
|
color: var(--color-primary);
|
|
}
|
|
}
|
|
|
|
/* Tag count */
|
|
.tag p {
|
|
grid-area: info;
|
|
padding: .5rem;
|
|
}
|
|
|
|
.tag:nth-child(odd) p {
|
|
text-align: right;
|
|
}
|
|
img[tabindex="0"] {
|
|
cursor: pointer;
|
|
}
|
|
|
|
img[tabindex="0"]:focus-visible {
|
|
outline: .15rem solid var(--color-teal);
|
|
}
|
|
|
|
dialog {
|
|
margin: auto;
|
|
flex-flow: column;
|
|
background: transparent;
|
|
border: none;
|
|
position: absolute;
|
|
}
|
|
|
|
dialog[open] {
|
|
display: flex;
|
|
}
|
|
|
|
dialog::backdrop {
|
|
background-color: rgba(from var(--color-bg) r g b / .8);
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
body:has(dialog[open]) {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.close-dialog {
|
|
background-color: rgba(from var(--color-teal) r g b / .35);
|
|
font-size: 1.5rem;
|
|
padding: 0 .5rem .15rem;
|
|
border-radius: 1rem;
|
|
color: var(--color-teal);
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
border: .08rem solid var(--color-teal);
|
|
align-self: flex-end;
|
|
justify-self: flex-start;
|
|
margin: 0 .1rem;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 1rem;
|
|
left: -.15rem;
|
|
transition: top .1s ease-in, left .1s ease-in;
|
|
}
|
|
|
|
.close-dialog:focus-visible {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.close-dialog:hover {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
.close-dialog:focus-visible {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.close-dialog:hover {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
.close-dialog:active {
|
|
top: 1.1rem;
|
|
left: -.05rem;
|
|
box-shadow: .05rem .05rem var(--color-shadow);
|
|
}
|
|
|
|
.modal-img {
|
|
max-height: calc(90vh - 2rem);
|
|
object-fit: contain;
|
|
width: auto;
|
|
max-width: 90%;
|
|
margin: 0 auto;
|
|
}
|
|
:root {
|
|
color-scheme: light dark;
|
|
|
|
--font-family: 'Atkinson Hyperlegible Next', sans-serif;
|
|
--font-family-code: 'Atkinson Hyperlegible Mono', monospace;
|
|
|
|
--color-dark: #2e303e;
|
|
--color-dark-alt: #3c3f52;
|
|
--color-light: #ebeeef;
|
|
--color-light-alt: #dbe1e3;
|
|
|
|
--color-teal-dark: #18737b;
|
|
--color-teal-light: #25b0bc;
|
|
--color-pink-dark: #94195d;
|
|
--color-pink-light: #ee9fcb;
|
|
|
|
--color-shadow: rgba(2, 10, 40, .25);
|
|
|
|
/* Used for syntax highlighting */
|
|
--color-red-light: #f195aa;
|
|
--color-orange-light: #fab795;
|
|
--color-yellow-light: #fbe6bc;
|
|
--color-green-light: #29d398;
|
|
--color-blue-light: #26bbd9;
|
|
--color-purple-light: #ddaeea;
|
|
--color-grey-light: #b9c3c6;
|
|
|
|
--color-red-dark: #991433;
|
|
--color-orange-dark: #883206;
|
|
--color-yellow-dark: #6a4906;
|
|
--color-green-dark: #125940;
|
|
--color-blue-dark: #125663;
|
|
--color-purple-dark: #722999;
|
|
--color-grey-dark: #4a4b64;
|
|
|
|
--color-text: light-dark(var(--color-dark), var(--color-light));
|
|
--color-bg: light-dark(var(--color-light), var(--color-dark));
|
|
|
|
--color-text-alt: light-dark(var(--color-dark-alt), var(--color-light-alt));
|
|
--color-bg-alt: light-dark(var(--color-light-alt), var(--color-dark-alt));
|
|
|
|
--color-teal: light-dark(var(--color-teal-dark), var(--color-teal-light));
|
|
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
|
|
|
|
--color-red: light-dark(var(--color-red-dark), var(--color-red-light));
|
|
--color-orange: light-dark(var(--color-orange-dark), var(--color-orange-light));
|
|
--color-yellow: light-dark(var(--color-yellow-dark), var(--color-yellow-light));
|
|
--color-green: light-dark(var(--color-green-dark), var(--color-green-light));
|
|
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
|
|
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
|
|
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
|
}
|
|
|
|
/* Base */
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-family);
|
|
color: var(--color-text);
|
|
background-color: var(--color-bg);
|
|
}
|
|
|
|
main {
|
|
width: 60vw;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
scroll-margin-top: 7rem;
|
|
}
|
|
|
|
@media (max-width: 1050px) {
|
|
main {
|
|
width: 75vw;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
main {
|
|
width: 92vw;
|
|
}
|
|
}
|
|
|
|
/* Headers */
|
|
h1, h2, h3, h4, h5, h6 {
|
|
line-height: 1.25;
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 3rem;
|
|
font-size: 3.5rem;
|
|
text-align: center;
|
|
}
|
|
|
|
h2, h3, h4, h5, h6 {
|
|
scroll-margin-top: 5rem;
|
|
}
|
|
|
|
h2 {
|
|
margin-top: 2rem;
|
|
font-size: 2.2rem;
|
|
}
|
|
|
|
h3 {
|
|
margin-top: 1.5rem;
|
|
font-size: 1.6rem;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
h1 { font-size: 2.8rem; }
|
|
h2 { font-size: 1.8rem; }
|
|
h3 { font-size: 1.35rem; }
|
|
}
|
|
|
|
h4, h5, h6 {
|
|
margin-top: 1rem;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
/* Images */
|
|
img {
|
|
display: block;
|
|
max-width: 100%;
|
|
height: auto;
|
|
border-radius: 1rem;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* Paragraphs */
|
|
p {
|
|
margin: 1.25rem 0;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
strong,
|
|
b {
|
|
font-weight: 900;
|
|
}
|
|
|
|
/* Links */
|
|
a {
|
|
color: var(--color-text);
|
|
border-radius: .25rem;
|
|
text-decoration: underline;
|
|
text-decoration-style: solid;
|
|
text-decoration-thickness: .2em;
|
|
text-decoration-color: var(--color-teal);
|
|
transition: text-decoration-thickness .5s;
|
|
}
|
|
|
|
a:focus-visible {
|
|
text-decoration: none;
|
|
outline: .15rem solid var(--color-teal);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
a:hover {
|
|
text-decoration-thickness: .4em;
|
|
}
|
|
}
|
|
|
|
a:active {
|
|
text-decoration-thickness: .4em;
|
|
}
|
|
|
|
/* Heading anchors */
|
|
a.ha,
|
|
span.ha-placeholder {
|
|
color: var(--color-pink);
|
|
font-size: .8em;
|
|
vertical-align: .1em;
|
|
}
|
|
span.ha-placeholder {
|
|
opacity: .55;
|
|
}
|
|
|
|
/* Lists */
|
|
::marker {
|
|
color: var(--color-pink);
|
|
}
|
|
|
|
ul, ol, dl, li {
|
|
margin-left: 1rem;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
ul, ol, dl {
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
|
|
li {
|
|
line-height: 1.2 5;
|
|
margin-top: .65rem;
|
|
margin-bottom: .65rem;
|
|
}
|
|
|
|
li ul, li ol {
|
|
margin: .5rem 0;
|
|
}
|
|
|
|
dt {
|
|
font-weight: 900;
|
|
margin-top: .5rem;
|
|
}
|
|
|
|
dd {
|
|
margin-left: 2rem;
|
|
margin-bottom: .75rem;
|
|
}
|
|
|
|
/* Blockquotes */
|
|
blockquote {
|
|
margin: .5rem 0;
|
|
padding: 0 1rem;
|
|
border-radius: .25rem 1rem 1rem .25rem;
|
|
line-height: 1.25;
|
|
border-left: .5rem solid var(--color-pink);
|
|
}
|
|
|
|
blockquote,
|
|
blockquote p,
|
|
blockquote ol,
|
|
blockquote ul {
|
|
background-color: var(--color-bg-alt);
|
|
padding: .5rem;
|
|
}
|
|
|
|
blockquote p {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Tables */
|
|
table {
|
|
width: 100%;
|
|
border-spacing: 0; /* border collapse doesn't play nice with radii */
|
|
border-radius: .3rem;
|
|
border: thin solid var(--color-pink);
|
|
}
|
|
|
|
th {
|
|
color: var(--color-bg);
|
|
background-color: var(--color-pink);
|
|
}
|
|
|
|
th code {
|
|
color: var(--color-text); /* Yes, I actually do this somewhere */
|
|
}
|
|
|
|
th, td {
|
|
padding: .5rem;
|
|
text-align: left;
|
|
}
|
|
|
|
tr:nth-child(even) { background-color: var(--color-bg-alt); }
|
|
th:not(:first-child) { border-left: thin solid var(--color-bg); }
|
|
th:first-child { border-top-left-radius: .25rem; }
|
|
th:last-child { border-top-right-radius: .25rem; }
|
|
td:not(:first-child) { border-left: thin solid var(--color-pink); }
|
|
|
|
/* Times */
|
|
time {
|
|
color: var(--color-grey);
|
|
}
|
|
|
|
/* Horizontal rules */
|
|
hr {
|
|
border: .25rem solid var(--color-pink);
|
|
margin: 2rem 0;
|
|
}
|
|
|
|
/* Used on home, reference, gallery pages */
|
|
.centered {
|
|
text-align: center;
|
|
}
|
|
|
|
/* Currently only used for resume, but it's generalizable */
|
|
.upper {
|
|
text-transform: uppercase;
|
|
}
|
|
/* Header */
|
|
header {
|
|
position: sticky;
|
|
top: 0;
|
|
background-color: var(--color-bg);
|
|
padding: .75rem 0;
|
|
z-index: 10;
|
|
border-bottom: thick solid var(--color-teal);
|
|
box-shadow: 0 .25rem .15rem var(--color-shadow);
|
|
}
|
|
|
|
/* Header links, pagination links */
|
|
header a,
|
|
.pagination a,
|
|
.webring ul a {
|
|
border-radius: 1rem;
|
|
border: .125rem solid var(--color-pink);
|
|
color: var(--color-pink);
|
|
text-decoration: none;
|
|
padding: 0 .25rem;
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
font-size: 1.2rem;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
transition: top .05s ease-in, left .05s ease-in;
|
|
}
|
|
|
|
header a,
|
|
.pagination .older a,
|
|
.webring .prev a,
|
|
.webring .rand a {
|
|
padding-right: .35rem;
|
|
}
|
|
|
|
.pagination .newer a,
|
|
.webring .next a,
|
|
.webring .rand a {
|
|
padding-left: .35rem;
|
|
}
|
|
|
|
header a:focus-visible,
|
|
.pagination a:focus-visible,
|
|
.webring ul a:focus-visible {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-pink);
|
|
background-color: var(--color-pink);
|
|
outline: none;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover,
|
|
.pagination a:hover,
|
|
.webring ul a:hover {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-pink);
|
|
background-color: var(--color-pink);
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
header a:focus-visible,
|
|
.pagination a:focus-visible,
|
|
.webring ul a:focus-visible {
|
|
outline-offset: .125rem;
|
|
outline: .125rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover,
|
|
.pagination a:hover,
|
|
.webring ul a:hover {
|
|
outline-offset: .125rem;
|
|
outline: .125rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
header a:active,
|
|
.pagination a:active,
|
|
.webring ul a:active {
|
|
top: .1rem;
|
|
left: .1rem;
|
|
box-shadow: .05rem .05rem var(--color-shadow);
|
|
}
|
|
|
|
/* Current page */
|
|
header a[aria-current="page"] {
|
|
border-color: var(--color-teal);
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
header a[aria-current="page"]:focus-visible {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-teal);
|
|
background-color: var(--color-teal);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a[aria-current="page"]:hover {
|
|
color: var(--color-bg);
|
|
background-color: var(--color-teal);
|
|
border-color: var(--color-teal);
|
|
}
|
|
}
|
|
|
|
/* Header link icons, pagination icons */
|
|
header i,
|
|
.pagination i,
|
|
.webring ul i {
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
header i,
|
|
.pagination .older i,
|
|
.webring .prev i,
|
|
.webring .rand i:nth-child(1) {
|
|
padding-left: .25rem;
|
|
}
|
|
|
|
.pagination .newer i,
|
|
.webring .next i,
|
|
.webring .rand i:nth-child(2) {
|
|
padding-right: .25rem;
|
|
}
|
|
|
|
header a[aria-current="page"] i {
|
|
color: var(--color-pink);
|
|
}
|
|
|
|
header a:focus-visible i,
|
|
a[aria-current="page"] a:focus-visible i,
|
|
.pagination a:focus-visible i,
|
|
.webring ul a:focus-visible i {
|
|
color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover i,
|
|
header a[aria-current="page"]:hover i,
|
|
.pagination a:hover i,
|
|
.webring ul a:hover i {
|
|
color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
/* Skip link */
|
|
#skip {
|
|
left: -999px;
|
|
position: absolute;
|
|
top: auto;
|
|
width: 1px;
|
|
height: 1px;
|
|
overflow: hidden;
|
|
z-index: -99;
|
|
}
|
|
|
|
#skip:focus-visible {
|
|
display: inline-block;
|
|
left: auto;
|
|
top: auto;
|
|
width: auto;
|
|
height: auto;
|
|
overflow: auto;
|
|
margin: 0 10%;
|
|
z-index: 999;
|
|
}
|
|
|
|
/* Nav */
|
|
header ul {
|
|
display: flex;
|
|
list-style: none;
|
|
gap: 1rem;
|
|
justify-content: center;
|
|
}
|
|
|
|
header ul,
|
|
header li {
|
|
margin: 0;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
.menu-text {
|
|
display: none; /* Icons only on small screens */
|
|
}
|
|
|
|
header a {
|
|
padding: .15rem .5rem;
|
|
}
|
|
|
|
header i {
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
/* Footer */
|
|
footer {
|
|
padding: 1rem 0;
|
|
font-size: .9rem;
|
|
border-top: thick solid var(--color-pink);
|
|
margin-top: 2rem;
|
|
}
|
|
|
|
footer ul {
|
|
display: flex;
|
|
list-style: none;
|
|
gap: .5rem;
|
|
justify-content: center;
|
|
margin: 0;
|
|
}
|
|
|
|
footer li {
|
|
margin: 0;
|
|
}
|
|
|
|
footer li:nth-child(2)::before,
|
|
footer li:nth-child(2)::after {
|
|
content: " ● " / "";
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
footer ul {
|
|
flex-flow: column;
|
|
text-align: center;
|
|
}
|
|
|
|
footer li:nth-child(2)::before,
|
|
footer li:nth-child(2)::after {
|
|
content: none;
|
|
}
|
|
}
|
|
|
|
footer a {
|
|
text-decoration-color: var(--color-pink);
|
|
}
|
|
|
|
footer a:focus-visible {
|
|
outline-color: var(--color-pink);
|
|
}
|
|
|
|
/* Pagination */
|
|
.pagination,
|
|
.pagination li {
|
|
margin: 0;
|
|
}
|
|
|
|
.pagination {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-template-areas: "older newer";
|
|
list-style: none;
|
|
margin-top: 3rem;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
.post-pagination {
|
|
grid-template-columns: 1fr;
|
|
grid-template-areas:
|
|
"older"
|
|
"newer";
|
|
gap: .75rem;
|
|
}
|
|
}
|
|
|
|
.pagination .older {
|
|
grid-area: older;
|
|
}
|
|
|
|
.pagination .newer {
|
|
grid-area: newer;
|
|
text-align: right;
|
|
}
|
|
|
|
/* webring navigation */
|
|
.webring {
|
|
margin-bottom: 3rem;
|
|
}
|
|
|
|
.webring ul {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
list-style: none;
|
|
justify-content: space-around;
|
|
gap: .35rem;
|
|
}
|
|
|
|
.webring ul,
|
|
.webring li {
|
|
margin-left: 0;
|
|
}
|
|
@media print {
|
|
/* Nav elements */
|
|
header,
|
|
footer,
|
|
nav {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Base */
|
|
body {
|
|
background-color: #fff;
|
|
color: #000;
|
|
}
|
|
|
|
main {
|
|
width: 95vw;
|
|
}
|
|
|
|
h1,h2,h3,h4,h5,h6 {
|
|
color: #000;
|
|
}
|
|
|
|
/* Links */
|
|
/* Hover is not really necessary, but it's annoying when testing otherwise */
|
|
a,
|
|
a:hover {
|
|
text-decoration-style: dotted;
|
|
text-decoration-thickness: .1rem;
|
|
text-decoration-color: #000;
|
|
}
|
|
|
|
a::after{
|
|
content: " (" attr(href) ")";
|
|
}
|
|
|
|
|
|
/* Code */
|
|
code,
|
|
pre,
|
|
code[class*=language-],
|
|
pre[class*=language-] {
|
|
text-shadow: none;
|
|
background-color: var(--color-light);
|
|
color: #000 !important;
|
|
}
|
|
|
|
.token.namespace {
|
|
opacity: 1;
|
|
}
|
|
|
|
.token.block-comment,
|
|
.token.cdata,
|
|
.token.comment,
|
|
.token.doctype,
|
|
.token.prolog,
|
|
.token.punctuation,
|
|
.token.attr-name,
|
|
.token.deleted,
|
|
.token.namespace,
|
|
.token.tag,
|
|
.token.boolean,
|
|
.token.function,
|
|
.token.number,
|
|
.token.class-name,
|
|
.token.constant,
|
|
.token.property,
|
|
.token.symbol,
|
|
.token.attr-value,
|
|
.token.char,
|
|
.token.regex,
|
|
.token.string,
|
|
.token.variable,
|
|
.token.inserted,
|
|
.token.entity,
|
|
.token.operator,
|
|
.token.url,
|
|
.token.function-name,
|
|
.token.atrule,
|
|
.token.builtin,
|
|
.token.important,
|
|
.token.keyword,
|
|
.token.selector {
|
|
color: #000;
|
|
}
|
|
}</style>
|
|
|
|
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
|
|
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
|
|
let globalInstanceIndex = 0;
|
|
|
|
class HeadingAnchors extends HTMLElement {
|
|
static register(tagName = "heading-anchors", registry = window.customElements) {
|
|
if(registry && !registry.get(tagName)) {
|
|
registry.define(tagName, this);
|
|
}
|
|
}
|
|
|
|
static attributes = {
|
|
exclude: "data-ha-exclude",
|
|
prefix: "prefix",
|
|
content: "content",
|
|
}
|
|
|
|
static classes = {
|
|
anchor: "ha",
|
|
placeholder: "ha-placeholder",
|
|
srOnly: "ha-visualhide",
|
|
}
|
|
|
|
static defaultSelector = "h2,h3,h4,h5,h6";
|
|
|
|
static css = `
|
|
.${HeadingAnchors.classes.srOnly} {
|
|
clip: rect(0 0 0 0);
|
|
height: 1px;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
width: 1px;
|
|
}
|
|
.${HeadingAnchors.classes.anchor} {
|
|
position: absolute;
|
|
left: var(--ha_offsetx);
|
|
top: var(--ha_offsety);
|
|
text-decoration: none;
|
|
opacity: 0;
|
|
}
|
|
.${HeadingAnchors.classes.placeholder} {
|
|
opacity: .3;
|
|
}
|
|
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
|
|
opacity: 1;
|
|
}
|
|
.${HeadingAnchors.classes.anchor},
|
|
.${HeadingAnchors.classes.placeholder} {
|
|
display: inline-block;
|
|
padding: 0 .25em;
|
|
|
|
/* Disable selection of visually hidden label */
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
@supports (anchor-name: none) {
|
|
.${HeadingAnchors.classes.anchor} {
|
|
position: absolute;
|
|
left: anchor(left);
|
|
top: anchor(top);
|
|
}
|
|
}`;
|
|
|
|
get supports() {
|
|
return "replaceSync" in CSSStyleSheet.prototype;
|
|
}
|
|
|
|
get supportsAnchorPosition() {
|
|
return CSS.supports("anchor-name: none");
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
if(!this.supports) {
|
|
return;
|
|
}
|
|
|
|
let sheet = new CSSStyleSheet();
|
|
sheet.replaceSync(HeadingAnchors.css);
|
|
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
|
|
this.headingStyles = {};
|
|
this.instanceIndex = globalInstanceIndex++;
|
|
}
|
|
|
|
connectedCallback() {
|
|
if (!this.supports) {
|
|
return;
|
|
}
|
|
|
|
this.headings.forEach((heading, index) => {
|
|
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
|
|
let anchor = this.getAnchorElement(heading);
|
|
let placeholder = this.getPlaceholderElement();
|
|
|
|
// Prefers anchor position approach for better accessibility
|
|
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
if(this.supportsAnchorPosition) {
|
|
let anchorName = `--ha_${this.instanceIndex}_${index}`;
|
|
placeholder.style.setProperty("anchor-name", anchorName);
|
|
anchor.style.positionAnchor = anchorName;
|
|
}
|
|
|
|
heading.appendChild(placeholder);
|
|
heading.after(anchor);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Polyfill-only
|
|
positionAnchorFromPlaceholder(placeholder) {
|
|
if(!placeholder) {
|
|
return;
|
|
}
|
|
|
|
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
|
|
if(!heading.nextElementSibling) {
|
|
return;
|
|
}
|
|
|
|
// TODO next element could be more defensive
|
|
this.positionAnchor(heading.nextElementSibling);
|
|
}
|
|
|
|
// Polyfill-only
|
|
positionAnchor(anchor) {
|
|
if(!anchor || !anchor.previousElementSibling) {
|
|
return;
|
|
}
|
|
|
|
// TODO previous element could be more defensive
|
|
let heading = anchor.previousElementSibling;
|
|
this.setFontProp(heading, anchor);
|
|
|
|
if(this.supportsAnchorPosition) {
|
|
// quit early
|
|
return;
|
|
}
|
|
|
|
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
|
|
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
|
|
}
|
|
}
|
|
|
|
setFontProp(heading, anchor) {
|
|
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
let style = getComputedStyle(placeholder);
|
|
let props = ["font-weight", "font-size", "line-height", "font-family"];
|
|
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
|
|
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
|
|
let vars = style.getPropertyValue("font-variation-settings");
|
|
if(vars) {
|
|
anchor.style.setProperty("font-variation-settings", vars);
|
|
}
|
|
}
|
|
}
|
|
/* no longer used, using aria-labelledby instead - see getAnchorElement
|
|
getAccessibleTextPrefix() {
|
|
// Useful for i18n
|
|
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
|
|
}
|
|
*/
|
|
getContent() {
|
|
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
|
|
return this.getAttribute(HeadingAnchors.attributes.content);
|
|
}
|
|
return "#";
|
|
}
|
|
|
|
// Placeholder nests inside of heading
|
|
getPlaceholderElement() {
|
|
let ph = document.createElement("span");
|
|
ph.setAttribute("aria-hidden", true);
|
|
ph.classList.add(HeadingAnchors.classes.placeholder);
|
|
let content = this.getContent();
|
|
if(content) {
|
|
ph.innerHTML = content; // CHANGED HERE
|
|
}
|
|
|
|
ph.addEventListener("mouseover", (e) => {
|
|
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
this.positionAnchorFromPlaceholder(placeholder);
|
|
}
|
|
});
|
|
|
|
return ph;
|
|
}
|
|
|
|
getAnchorElement(heading) {
|
|
let anchor = document.createElement("a");
|
|
anchor.href = `#${heading.id}`;
|
|
anchor.classList.add(HeadingAnchors.classes.anchor);
|
|
|
|
let content = this.getContent();
|
|
anchor.innerHTML = `<span aria-labelledby=${heading.id}>${content}</span>`; // CHANGED HERE
|
|
|
|
anchor.addEventListener("focus", e => {
|
|
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
|
|
if(anchor) {
|
|
this.positionAnchor(anchor);
|
|
}
|
|
});
|
|
|
|
anchor.addEventListener("mouseover", (e) => {
|
|
// when CSS anchor positioning is supported, this is only used to set the font
|
|
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
|
|
this.positionAnchor(anchor);
|
|
});
|
|
|
|
return anchor;
|
|
}
|
|
|
|
get headings() {
|
|
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
|
|
}
|
|
|
|
get selector() {
|
|
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
|
|
}
|
|
}
|
|
|
|
HeadingAnchors.register();
|
|
|
|
export { HeadingAnchors }
|
|
/* don't even bother on mobile */
|
|
if (window.innerWidth > 650) {
|
|
const dialog = document.querySelector("dialog");
|
|
const closeButton = document.querySelector(".close-dialog");
|
|
const hero = document.querySelector(".hero");
|
|
|
|
hero.tabIndex = 0;
|
|
|
|
hero.addEventListener("click", (e) => dialog.showModal());
|
|
hero.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter" || e.key === " ") {
|
|
e.preventDefault();
|
|
dialog.showModal();
|
|
}
|
|
});
|
|
|
|
closeButton.addEventListener("click", (e) => dialog.close());
|
|
closeButton.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter" || e.key === " ") {
|
|
e.preventDefault();
|
|
dialog.close();
|
|
}
|
|
});
|
|
}</script>
|
|
|
|
</head>
|
|
<body>
|
|
<header>
|
|
|
|
<a href="#main" id="skip" title="skip to main content">
|
|
<i class="fa-solid fa-forward" aria-hidden="true"></i> skip
|
|
</a>
|
|
|
|
<nav aria-label="main navigation">
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/reference/" title="read reference posts">
|
|
<i class="fa-regular fa-folder-open" aria-hidden="true"></i>
|
|
<span class="menu-text">reference</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/gallery/" title="view the gallery">
|
|
<i class="fa-regular fa-images" aria-hidden="true"></i>
|
|
<span class="menu-text">gallery</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/" title="home">
|
|
<i class="fa fa-solid fa-crow" aria-hidden="true"></i>
|
|
<span class="menu-text">home</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/about/" title="about Lee">
|
|
<i class="fa-regular fa-user" aria-hidden="true"></i>
|
|
<span class="menu-text">about</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/contact/" title="contact Lee">
|
|
<i class="fa-solid fa-envelope-open-text" aria-hidden="true"></i>
|
|
<span class="menu-text">contact</span>
|
|
</a>
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
|
|
<main id="main">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
|
<article>
|
|
<h1 id="core-css">core CSS</h1>
|
|
|
|
<div class="post-metadata">
|
|
<p>
|
|
posted on
|
|
<time datetime="2026-06-30">June 30, 2026</time>
|
|
by Lee Cattarin
|
|
</p>
|
|
|
|
|
|
<ul class="post-tags">
|
|
|
|
<li>
|
|
|
|
<a href="/tags/software/">software</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
|
|
<dialog closedby="any" aria-label="image modal" tabindex="-1">
|
|
<button class="close-dialog" autofocus="" aria-label="close the image modal">×</button>
|
|
<img class="modal-img" src="/img/core-css.png" alt="A website mockup in dark mode with light pink accents. Everything is filler text such as the title 'This is my cool website', headers reading things like 'This is an h1', nav items 'Nav item 1', etc. There is a paragraph block - the opening of the Bee Movie - and part of an image visible - a screencap of the music video for Never Gonna Give You Up by Rick Astley." loading="lazy" decoding="async" width="1000" height="447">
|
|
</dialog>
|
|
<img class="hero" src="/img/core-css.png" alt="A website mockup in dark mode with light pink accents. Everything is filler text such as the title 'This is my cool website', headers reading things like 'This is an h1', nav items 'Nav item 1', etc. There is a paragraph block - the opening of the Bee Movie - and part of an image visible - a screencap of the music video for Never Gonna Give You Up by Rick Astley." loading="lazy" decoding="async" width="1000" height="447">
|
|
|
|
|
|
<p>What CSS would you implement if you had no or very low vision? Recently, a Blind friend wanted to know more about CSS. This is my attempt at a very minimal CSS file that cleans up a few <a href="https://browserdefaultstyles.com/" target="_blank" rel="external">browser defaults</a> for a more pleasant browsing experience without needing much if any visual testing.</p>
|
|
<p>Want to just see the final stylesheet? <a href="#result">Skip to the end of the page</a>.</p>
|
|
<h2 id="css-resets">CSS resets</h2>
|
|
<p>Before we start: this isn't a CSS reset. You may want to apply it in concert with one. While writing this, a friend recommended <a href="https://www.joshwcomeau.com/css/custom-css-reset/" target="_blank" rel="external">Josh W. Comeau's CSS Reset</a>, which looks largely very solid to me. However, if using that particular reset, I would <em><strong>not</strong></em> reset default margins (rule 2). They are tremendously useful in this case, where we are unlikely to be setting margins on elements individually.</p>
|
|
<h2 id="color">color</h2>
|
|
<p>Complex color palettes are a no-go. But browser defaults are also pretty bad - stark black and white are really hard on sighted users' eyes. Dulling the black and white down to nearby grays helps a lot. And of course, we'll support light and dark modes.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">:root</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color-scheme</span><span class="token punctuation">:</span> light dark<span class="token punctuation">;</span>
|
|
|
|
<span class="token property">--color-light</span><span class="token punctuation">:</span> #ddd<span class="token punctuation">;</span>
|
|
<span class="token property">--color-dark</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span>
|
|
|
|
<span class="token property">--color-bg</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-light<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">--color-text</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-light<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-text<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-bg<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h3 id="accents">accents</h3>
|
|
<p>To skip reading about accent colors, head right to <a href="#focus-indication">focus indication</a>.</p>
|
|
<p>If you have any opinions about color, you might pick accents. At the simplest level, I'd pick one for light mode and one for dark mode. <a href="https://xkcd.com/color/rgb/" target="_blank" rel="external">XKCD has a color sheet based on a wide survey</a> that is potentially useful here. Validate that the color contrast is enough with a tool like <a href="https://webaim.org/resources/contrastchecker/" target="_blank" rel="external">WebAIM's Contrast Checker</a>. You might color your headers and links.</p>
|
|
<p>If you're coloring links, it's worth considering browser defaults. Blue is unvisited, purple is visited, and red is inactive. Choosing a red or purple link color might confuse users. Blues are pretty safe. A green might be fun.</p>
|
|
<p>Being the person that I am, I'm picking a teal and a pink. XKCD labels these "dark teal" (contrast ratio of 7.11 against our gray-white) and "powder pink" (contrast ratio of 9.49 against our gray-black) respectively.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">:root</span> <span class="token punctuation">{</span>
|
|
<span class="token property">--color-teal</span><span class="token punctuation">:</span> #014d4e<span class="token punctuation">;</span>
|
|
<span class="token property">--color-pink</span><span class="token punctuation">:</span> #ffb2d0<span class="token punctuation">;</span>
|
|
|
|
<span class="token property">--color-accent</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-teal<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-pink<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">h1, h2, h3, h4, h5, h6,
|
|
a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="focus-indication">focus indication</h2>
|
|
<p>Focus indication is a visual change that occurs when something interactive on the screen (like a link) receives keyboard focus. Without it, sighted keyboard-only users can't tell where they are on the page. Conventionally, it's an outline. <a href="https://www.sarasoueidan.com/blog/focus-indicators/" target="_blank" rel="external">Read more about accessible focus indication</a>.</p>
|
|
<p>I would recommend a <em>smidge</em> of padding (spacing <em>inside</em> the border or outline of an element) around your links to allow for more space between the letters and focus outline in order to help with legibility.</p>
|
|
<p>If you recolor your links as mentioned in the previous section, recolor your focus indication for cohesiveness! Additionally, if you overwrite the browser default focus outline in this way or any other, you might want to add a very small border radius to your links. I find that perfectly square corners are a bit of a harsh look, but I'll admit this one is kind of personal preference.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">padding</span><span class="token punctuation">:</span> .1rem<span class="token punctuation">;</span>
|
|
<span class="token property">border-radius</span><span class="token punctuation">:</span> .05rem<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">a:focus-visible</span> <span class="token punctuation">{</span>
|
|
<span class="token property">outline</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="font">font</h2>
|
|
<p>All-serif everything (a common browser default) is, uh, kinda ugly and overwhelming. Little tails on every letter are visual clutter, at least to my eyes. It feels outdated, like an old-timey newspaper. Picking serif for headers and sans-serif for body (or vice versa) can be a nice alternative. Plus, the contrast will help on lower-level headings... if you ever drill down to <code>h5</code>s or <code>h6</code>s anyway.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">font-family</span><span class="token punctuation">:</span> sans-serif<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">h1, h2, h3, h4, h5, h6</span> <span class="token punctuation">{</span>
|
|
<span class="token property">font-family</span><span class="token punctuation">:</span> serif<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="margins">margins</h2>
|
|
<p>Margins create visual space around an element, and this whitespace helps significantly with focus. We're <em>super super not</em> going to reset the margins for everything. That puts us in design hell and becomes a very visually-oriented problem. Instead, we're just changing two things: the width of the body and where it sits on the page. Readers, particularly dyslexic readers, can more easily move to the next line when they are not trying to track back across the full width of the screen.</p>
|
|
<p>This margin rule defines a small amount of top/bottom space first (<code>1rem</code>), and then tells the page to make the left and right margins equal with <code>auto</code> - centering the body in the middle of the page. I'm also going to set a <code>max-width</code> to handle those mystical ultra-wide screens (never used one), and a couple of breakpoints for tablets and mobile.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 65%<span class="token punctuation">;</span>
|
|
<span class="token property">max-width</span><span class="token punctuation">:</span> 1800px<span class="token punctuation">;</span>
|
|
<span class="token property">margin</span><span class="token punctuation">:</span> 1rem auto<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 1050px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 85%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 650px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 92%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="links">links</h2>
|
|
<p>One quick note about accessible links: they should be identifiable by a method other than color. Basically, don't turn off your underlines! Additionally, I would recommend against using underlines for emphasis elsewhere - use <code><em></code> or <code><strong></code> instead.</p>
|
|
<h2 id="images">images</h2>
|
|
<p>As mentioned up top, this overlaps with the linked CSS Reset writeup.</p>
|
|
<p>By default, an image will be full size. If it's a large image, that can be even larger than the viewport. We'll give them a <code>max-width</code> and center them in case they are narrower than the body. <code>display: block</code> allows that centering to actually work.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">img, picture, video, canvas, svg</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
|
|
<span class="token property">max-width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
|
|
<span class="token property">margin</span><span class="token punctuation">:</span> 0 auto<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="headers-footers-navs">headers, footers, navs</h2>
|
|
<p>Let's talk the components that every page likely has - a header, a footer, and navs. I'm going to use a very simple design for our header - a <a href="https://webaim.org/techniques/skipnav/" target="_blank" rel="external">skip link</a>, an (optional) site title (the title could also be one of the nav links), and then an unordered list of links enclosed in a <code>nav</code> element. Like the following:</p>
|
|
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>header</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>skip<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#main<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Skip to content<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
|
|
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This is my cool website<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span>
|
|
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>nav</span> <span class="token attr-name">aria-label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main menu navigation<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/header-nav-1/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Header nav item 1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/header-nav-2/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Header nav item 2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/header-nav-3/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Header nav item 3<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>nav</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>header</span><span class="token punctuation">></span></span></code></pre>
|
|
<p>and our footer will be similar:</p>
|
|
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>footer</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>nav</span> <span class="token attr-name">aria-label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>footer navigation<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/footer-nav-1/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Footer nav item 1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/footer-nav-2/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Footer nav item 2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>nav</span><span class="token punctuation">></span></span>
|
|
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>footer</span><span class="token punctuation">></span></span></code></pre>
|
|
<h3 id="skip-link">skip link</h3>
|
|
<p>Let's handle the skip link first. Your skip link can be hard to style without visual feedback. Commonly, they start hidden and only appear when receiving keyboard focus. It's entirely reasonable, in my opinion, to leave it visible. <strong>I actually like this as a design choice</strong>, as it highlights the idea and hopefully purpose of a skip link to sighted readers. However, if you want to hide it, there's a lot (a <em>lot</em>) of ways to do so. Using <code>position: absolute</code>, <code>left</code>, and <code>top</code>, we can place the skip link outside of the page, then move it in when it receives focus. We'll also stick a background on there to prevent the text from overlaying our site title and becoming illegible.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">#skip</span> <span class="token punctuation">{</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-bg<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
|
|
<span class="token property">left</span><span class="token punctuation">:</span> -999px<span class="token punctuation">;</span>
|
|
<span class="token property">top</span><span class="token punctuation">:</span> -999px<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">#skip:focus-visible</span> <span class="token punctuation">{</span>
|
|
<span class="token property">left</span><span class="token punctuation">:</span> 10%<span class="token punctuation">;</span>
|
|
<span class="token property">top</span><span class="token punctuation">:</span> 5%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h3 id="site-title">site title</h3>
|
|
<p>I won't do much here, but I am going to remove the underline (which is the default for links). It's commonly understood that the site title (or sometimes just the word "home") links to the home page, and the underline is unnecessary visual clutter.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">header h2</span> <span class="token punctuation">{</span>
|
|
<span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h3 id="flexbox-navs">flexbox navs</h3>
|
|
<p>We're going to dip our toes into flexbox for this one - it allows us to make content fall neatly into rows or columns. It's pretty powerful, and can get pretty weird, but we'll keep it bare-bones.</p>
|
|
<p>By default, the unordered lists in the navs will display with each list item on a new line with a bullet point in front of the list item. Let's take up less space by putting them all on one line. I'm going to center the items, and I'm going to allow them to wrap onto a new line. I'm also taking the bullet points off of the list items and allowing for a bit of space between each item.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">nav ul</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
|
|
<span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
|
|
<span class="token property">flex-flow</span><span class="token punctuation">:</span> row wrap<span class="token punctuation">;</span>
|
|
<span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token property">gap</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h3 id="aria-current">aria-current</h3>
|
|
<p>Screen reader users get <code>aria-current</code> information, and it can be helpful to present it to sighted users as well. There are of course many ways to do this with color, but we'll avoid that. Let's add carets before and after the current page link to indicate this. We'll scope them only to the header and footer just in case we run across a weird case.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">header a[aria-current="page"]::before,
|
|
footer a[aria-current="page"]::before</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">"> "</span> / <span class="token string">""</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">header a[aria-current="page"]::after,
|
|
footer a[aria-current="page"]::after</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">" <"</span> / <span class="token string">""</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<p>The content after the forward slash is what is conveyed to screen reader users. The carets are not useful from a screen reader perspective, so this excerpts them.</p>
|
|
<h3 id="separating-header-and-footer-from-main">separating header and footer from main</h3>
|
|
<p>The header and footer can visually run into the main text area if there's not extra space or a border. We'll keep it simple with borders. If you're not using an accent color, use your text color instead.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">header</span> <span class="token punctuation">{</span>
|
|
<span class="token property">border-bottom</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">footer</span> <span class="token punctuation">{</span>
|
|
<span class="token property">border-top</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="print-media">print media</h2>
|
|
<p>There's a couple straightforward additions we can make to handle printing the site cleanly and making best use of the physical paper space. Remove the header and footer, reset the width and colors to limit ink usage, and print link URLs after the link.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@media</span> print</span> <span class="token punctuation">{</span>
|
|
<span class="token selector">header,
|
|
footer,
|
|
nav</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 95vw<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body,
|
|
h1, h2, h3, h4, h5,
|
|
a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">a::after</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">" ("</span> <span class="token function">attr</span><span class="token punctuation">(</span>href<span class="token punctuation">)</span> <span class="token string">")"</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
<h2 id="feedback">feedback</h2>
|
|
<p>Did I make a mistake? Is there more I could add? <a href="/contact/">Reach out</a>!</p>
|
|
<h2 id="result">result</h2>
|
|
<p>Here's our outcome.</p>
|
|
<pre class="language-css"><code class="language-css"><span class="token selector">:root</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color-scheme</span><span class="token punctuation">:</span> light dark<span class="token punctuation">;</span>
|
|
|
|
<span class="token property">--color-light</span><span class="token punctuation">:</span> #ddd<span class="token punctuation">;</span>
|
|
<span class="token property">--color-dark</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span>
|
|
<span class="token property">--color-teal</span><span class="token punctuation">:</span> #014d4e<span class="token punctuation">;</span>
|
|
<span class="token property">--color-pink</span><span class="token punctuation">:</span> #ffb2d0<span class="token punctuation">;</span>
|
|
|
|
<span class="token property">--color-bg</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-light<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">--color-text</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-light<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">--color-accent</span><span class="token punctuation">:</span> <span class="token function">light-dark</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--color-teal<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-pink<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-text<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-bg<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">font-family</span><span class="token punctuation">:</span> sans-serif<span class="token punctuation">;</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 65%<span class="token punctuation">;</span>
|
|
<span class="token property">max-width</span><span class="token punctuation">:</span> 1800px<span class="token punctuation">;</span>
|
|
<span class="token property">margin</span><span class="token punctuation">:</span> 1rem auto<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 1100px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 85%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 650px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 92%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token comment">/* Basic elements */</span>
|
|
<span class="token selector">h1, h2, h3, h4, h5, h6</span> <span class="token punctuation">{</span>
|
|
<span class="token property">font-family</span><span class="token punctuation">:</span> serif<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">h1, h2, h3, h4, h5, h6,
|
|
a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">padding</span><span class="token punctuation">:</span> .1rem<span class="token punctuation">;</span>
|
|
<span class="token property">border-radius</span><span class="token punctuation">:</span> .05rem<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">a:focus-visible</span> <span class="token punctuation">{</span>
|
|
<span class="token property">outline</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">img, picture, video, canvas, svg</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
|
|
<span class="token property">max-width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
|
|
<span class="token property">margin</span><span class="token punctuation">:</span> 0 auto<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token comment">/* Header, footer, nav */</span>
|
|
<span class="token selector">header</span> <span class="token punctuation">{</span>
|
|
<span class="token property">border-bottom</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">#skip</span> <span class="token punctuation">{</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-bg<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
|
|
<span class="token property">left</span><span class="token punctuation">:</span> -999px<span class="token punctuation">;</span>
|
|
<span class="token property">top</span><span class="token punctuation">:</span> -999px<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">#skip:focus-visible</span> <span class="token punctuation">{</span>
|
|
<span class="token property">left</span><span class="token punctuation">:</span> 10%<span class="token punctuation">;</span>
|
|
<span class="token property">top</span><span class="token punctuation">:</span> 5%<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">header a[aria-current="page"]::before,
|
|
footer a[aria-current="page"]::before</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">"> "</span> / <span class="token string">""</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">header a[aria-current="page"]::after,
|
|
footer a[aria-current="page"]::after</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">" <"</span> / <span class="token string">""</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">header h2 a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">nav ul</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
|
|
<span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
|
|
<span class="token property">flex-flow</span><span class="token punctuation">:</span> row wrap<span class="token punctuation">;</span>
|
|
<span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token property">gap</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">footer</span> <span class="token punctuation">{</span>
|
|
<span class="token property">border-top</span><span class="token punctuation">:</span> solid <span class="token function">var</span><span class="token punctuation">(</span>--color-accent<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token comment">/* Print media */</span>
|
|
<span class="token atrule"><span class="token rule">@media</span> print</span> <span class="token punctuation">{</span>
|
|
<span class="token selector">header,
|
|
footer,
|
|
nav</span> <span class="token punctuation">{</span>
|
|
<span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body</span> <span class="token punctuation">{</span>
|
|
<span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
|
|
<span class="token property">width</span><span class="token punctuation">:</span> 95vw<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">body,
|
|
h1, h2, h3, h4, h5,
|
|
a</span> <span class="token punctuation">{</span>
|
|
<span class="token property">color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token selector">a::after</span> <span class="token punctuation">{</span>
|
|
<span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">" ("</span> <span class="token function">attr</span><span class="token punctuation">(</span>href<span class="token punctuation">)</span> <span class="token string">")"</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span></code></pre>
|
|
|
|
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav aria-label="pagination">
|
|
<ol class="pagination post-pagination">
|
|
|
|
<li class="older">
|
|
<a href="/fedilearns/">
|
|
<i class="fa-solid fa-hand-point-left" aria-hidden="true"></i> fediLearns
|
|
</a>
|
|
</li>
|
|
|
|
|
|
</ol>
|
|
</nav>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
|
|
<section class="related-posts">
|
|
<h2 data-ha-exclude="" id="related-posts">related posts</h2>
|
|
<ol id="postlist">
|
|
|
|
<li class="post">
|
|
<a class="postlink" href="/screen-reader-optimizations/">
|
|
<h2 data-ha-exclude="" id="screen-reader-optimizations">screen reader optimizations </h2>
|
|
|
|
<ul class="postlist-tags">
|
|
|
|
<li>software</li>
|
|
|
|
</ul>
|
|
<img src="/img/crow.jpg" alt="Image unrelated to post. A crow poses on driftwood against a whitish sky." loading="lazy" decoding="async" width="1000" height="666">
|
|
|
|
</a>
|
|
</li>
|
|
|
|
<li class="post">
|
|
<a class="postlink" href="/accessible-image-modals/">
|
|
<h2 data-ha-exclude="" id="accessible-image-modals">accessible image modals </h2>
|
|
|
|
<ul class="postlist-tags">
|
|
|
|
<li>software</li>
|
|
|
|
</ul>
|
|
<img src="/img/snacking-seagull.jpg" alt="Image unrelated to post. A seagull floating in the water with a starfish hanging out of eir mouth." loading="lazy" decoding="async" width="1000" height="666">
|
|
|
|
</a>
|
|
</li>
|
|
|
|
<li class="post">
|
|
<a class="postlink" href="/comparing-text-editors/">
|
|
<h2 data-ha-exclude="" id="comparing-text-editors">comparing text editors </h2>
|
|
|
|
<ul class="postlist-tags">
|
|
|
|
<li>software</li>
|
|
|
|
</ul>
|
|
<img src="/img/horsetail.jpg" alt="Image unrelated to post. Close up on a horsetail plant's stem, with many small needle-like leaves emerging from all sides of the circular stem at each segmented joint." loading="lazy" decoding="async" width="1000" height="666">
|
|
|
|
</a>
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
</section>
|
|
|
|
|
|
</heading-anchors>
|
|
|
|
</main>
|
|
|
|
<footer>
|
|
<ul>
|
|
<li>
|
|
<a href="/colophon/">
|
|
colophon
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/" title="go home" aria-label="go home | hello hello from Lee Cattarin, copyright 2022-2026">
|
|
hello hello from Lee Cattarin, © 2022-2026</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://heckin.technology/inherentlee/leecat.art" title="source code" aria-label="source code" target="_blank" rel="external">
|
|
src
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</footer>
|
|
|
|
|
|
<!-- This page `/core-css/` was built on 2026-07-01T21:48:17.994Z -->
|
|
</body>
|
|
</html>
|