Last active
January 2, 2024 17:46
-
-
Save knowler/af029df4a6568d6ea8467c7b0fb023c4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Modern CSS crash course: | |
* | |
* - Leverage flexibility for everything. The web is magic paper that adapts to whatever viewport it’s in. | |
* - This means using `display` values like `flex` and `grid`. | |
* - Avoid using `@media` for setting sizes: use fluid type and spacing (i.e. `clamp()`, `min()`, `max()` math functions). | |
* - Use logical properties for sizing and spacing. This helps with internationalization. | |
* - Think in axes: block (vertical: top is start, bottom is end), inline (horizontal: left is start, right is end). | |
* - Those are the left-to-right/top-to-bottom equivalances, but for other writing modes/directions you’ll be setting the correct direction (e.g. in RTL, inline-start is right and inline-end is left). | |
* - For flexbox and grid: “align” properties apply to the block axis and “justify” properties apply to the inline axis. | |
* - Use custom properties to avoid repetition. They are like variables (but a bit different). | |
* - Use variable fonts if you can. Some system fonts are variable fonts. | |
* - Almost never use `px`. Prefer `rem` and `em` instead (rem is based on the root font size which is set by a user preference — respects accessibility). | |
* - Don’t be afraid of targeting “semantic” selectors. | |
*/ | |
/* border-box is a more intuitive box-sizing */ | |
*, ::before, ::after { box-sizing: border-box; } | |
:root { | |
/* Dark mode by default, but respect user preference */ | |
color-scheme: dark light; | |
/* Using custom properties for our colour variables, but setting them to the browser defaults since I’m lazy. */ | |
--color-canvas: Canvas; | |
--color-canvas-text: CanvasText; | |
/* Dark mode + Safari link colours don’t play nice, so we’ll set our own link colour */ | |
--color-accent: hsl(210deg 80% 60%); /* h(ue) s(aturation) l(ightness) */ | |
/* Font variation settings we’ll use to make the system font look unique. */ | |
--font-settings-wide: "wdth" 130; | |
--font-settings-regular: "wdth" 110; | |
--font-settings-condensed: "wdth" 90; | |
} | |
/* Light colour scheme settings */ | |
@media (prefers-color-scheme: light) { | |
:root { | |
/* Dim the accent colour in light mode */ | |
--color-accent: hsl(210deg 80% 40%); | |
} | |
} | |
/* Default focus visible styles (i.e. when focused with keyboard, not mouse) */ | |
:focus-visible { | |
outline: 0.125em dotted var(--color-accent); | |
outline-offset: 0.25em; | |
border-radius: 0.25em; | |
} | |
html { | |
block-size: 100%; | |
/* Use the system font (macOS: San Francisco / Windows: Segoe UI / Android: Roboto / Linux: Ubuntu maybe) and fallback to the default serif font */ | |
font-family: system-ui, sans-serif; | |
/* Don’t use px for font-size on html element — it’ll ignore user preferences. */ | |
font-size: clamp(1rem, 0.8rem + 1vw, 1.5rem); | |
font-variation-settings: var(--font-settings-condensed); | |
line-height: 1.5; /* Minimum accessible line-height */ | |
} | |
body { | |
margin: 0; | |
padding-block: 2rem; | |
padding-inline: 1rem; | |
min-block-size: 100%; | |
display: grid; | |
gap: 2rem; | |
/* Centre the column and add an upper and lower bound for it’s max width, otherwise set it to 80% of the viewport width */ | |
grid-template-columns: min(clamp(20rem, 80vw, 40rem), 100%); | |
justify-content: center; | |
/* header main footer (skip link is excluded since it’s position: fixed) */ | |
grid-template-rows: max-content auto max-content; | |
} | |
/* Visually hidden elements (i.e. stuff you just want to expose to screen readers) */ | |
.visuallyhidden:not(:focus) { | |
position: absolute; | |
width: 1px; | |
height: 1px; | |
padding: 0; | |
margin: -1px; | |
overflow: hidden; | |
clip: rect(0, 0, 0, 0); | |
white-space: nowrap; | |
border-width: 0; | |
} | |
/* Default link colour */ | |
a { | |
color: var(--color-accent); | |
text-underline-offset: 0.1em; | |
} | |
/* Skip to content link (when focused) */ | |
a[href="#content"]:focus { | |
position: fixed; | |
display: inline-block; | |
inset-inline-start: 50%; | |
inset-block-start: 1rem; | |
padding: 0.5rem; | |
background-color: var(--color-canvas); | |
font-variation-settings: var(--font-settings-regular); | |
outline-offset: 0; | |
} | |
/* The current page */ | |
a[aria-current="page"] { | |
text-decoration: none; | |
background-color: var(--color-accent); | |
color: var(--color-canvas); | |
} | |
/* Header & footer styles */ | |
header { | |
font-size: 1.25rem; | |
} | |
footer p { | |
margin-block: 0; | |
} | |
header, footer { | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: space-between; | |
align-items: center; | |
column-gap: 1rem; | |
row-gap: 0.5rem; | |
font-variation-settings: var(--font-settings-wide); | |
} | |
:is(header, footer) > nav > ul { | |
list-style: none; | |
display: flex; | |
flex-wrap: wrap; | |
column-gap: 1rem; | |
row-gap: 0.5rem; | |
padding-inline-start: 0; | |
margin-block: 0; | |
} | |
/* Prose styles */ | |
h1, h2, h3, h4, h5, h6 { | |
font-variation-settings: var(--font-settings-wide); | |
font-weight: 500; | |
line-height: 1.2; | |
letter-spacing: 0.01em; | |
} | |
/* Heading with sub-title */ | |
hgroup { | |
display: grid; | |
justify-items: start; | |
gap: 0.5rem; | |
} | |
hgroup > * { | |
margin-block: 0; | |
} | |
hgroup > p { | |
font-size: 1.125rem; | |
font-variation-settings: var(--font-settings-regular); | |
letter-spacing: 0.01em; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<!-- Generally, include these two meta tags on every document --> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Content Title – Website</title> | |
<meta name="description" content="Description of the webpage"> | |
<link rel="stylesheet" href="/main.css"> | |
</head> | |
<body> | |
<!-- Allow keyboard navigators to skip the header/banner --> | |
<a class="visuallyhidden" href="#content">Skip to content</a> | |
<!-- This is the site banner — you only need one of these and it’s top-level --> | |
<header> | |
<!-- Set aria-current=page on current page for nav links – works as a nice hook in CSS --> | |
<a href="/" aria-current="page">Name of Website</a> | |
<nav aria-label="primary"> | |
<ul> | |
<li><a href="/about">About</a></li> | |
<li><a href="/blog">Blog</a></li> | |
<li><a href="/contact">Contact</a></li> | |
</ul> | |
</nav> | |
</header> | |
<!-- Only ever use one <main> and make sure it’s not nested in another semantic element (div is fine) --> | |
<!-- This is the main content of the page --> | |
<main id="content"> | |
<!-- Since you might want a sidebar or something, stuff the content of the page into an article element --> | |
<article> | |
<hgroup> | |
<h1>Title of the content</h1> | |
<p>Do this if you need a subtitle</p> | |
</hgroup> | |
<p>Don’t repeat h1 ever</p> | |
<h2>Section heading</h2> | |
<p>Some content for the section</p> | |
<h3>Sub-section heading</h3> | |
<p>This is a sub-section within the previous section</p> | |
<h2>Next section heading</h2> | |
<p>Next section content</p> | |
</article> | |
</main> | |
<!-- Info about the content, maybe a license, secondary nav (make sure it’s labelled). You only need one footer at the top-level --> | |
<footer> | |
<p>©2024 Author of Website</p> | |
<nav aria-label="secondary"> | |
<ul> | |
<li><a href="/accessibility">Accessibility</a></li> | |
<li><a href="/privacy">Privacy</a></li> | |
</ul> | |
</nav> | |
</footer> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment