From 325e8cba2d63eae909a8f6ca1f92722ed2f514db Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 19 Jul 2021 19:36:09 -0500 Subject: [PATCH] Improve docs theme (#717) * Revert "Revert "New getting started guide (#715)"" This reverts commit dc4ba25b01254ed1c2088c081e8c861172ae58a4. * style: update docs theme * style: implement feedback * feat: remove FOUC * Update docs/src/pages/404.astro Co-authored-by: Caleb Jasik * Fix 404 title prop * chore: implement feedback * fix: ul, ol styles * fix: center logo on mobile * fix: improve navbar header contrast * fix: improve logo overlap * fix: `.nav-link` radius * fix: small mobile tweaks * feat: improve nav styles * feat: improve embed styles * fix: feedback items * fix: make header sticky on mobile Co-authored-by: Caleb Jasik --- docs/public/code.css | 171 ++++++----------- docs/public/index.css | 219 ++++++++++++++++------ docs/public/nav.js | 37 ++++ docs/public/theme.css | 35 ++-- docs/public/theme.js | 12 -- docs/src/components/SiteSidebar.astro | 46 ++++- docs/src/layouts/Main.astro | 164 +++++++++++------ docs/src/pages/404.astro | 242 +----------------------- docs/src/pages/index.astro | 254 +------------------------- examples/docs/public/index.css | 2 +- vercel.json | 5 +- 11 files changed, 445 insertions(+), 742 deletions(-) create mode 100644 docs/public/nav.js delete mode 100644 docs/public/theme.js diff --git a/docs/public/code.css b/docs/public/code.css index 76b44bd24..58a631e57 100644 --- a/docs/public/code.css +++ b/docs/public/code.css @@ -8,148 +8,91 @@ opacity: 0.7; } -.token.atrule { - color: #c792ea; +.token.plain-text, +[class*="language-bash"] span.token, +[class*="language-shell"] span.token { + color: var(--color-gray-200); } -.token.attr-name { - color: #ffcb6b; +[class*="language-bash"] span.token, +[class*="language-shell"] span.token { + font-style: bold; } -.token.attr-value { - color: #a5e844; -} - -.token.attribute { - color: #a5e844; -} - -.token.boolean { - color: #c792ea; -} - -.token.builtin { - color: #ffcb6b; -} - -.token.cdata { - color: #80cbc4; -} - -.token.char { - color: #80cbc4; -} - -.token.class { - color: #ffcb6b; -} - -.token.class-name { - color: #f2ff00; -} - -.token.comment { - color: #999; -} - -.token.constant { - color: #c792ea; +.token.prolog, +.token.comment, +[class*="language-bash"] span.token.comment, +[class*="language-shell"] span.token.comment { + color: var(--color-gray-400); } +.token.selector, +.token.tag, +.token.unit, +.token.url, +.token.variable, +.token.entity, .token.deleted { - color: #ff6666; + color: #FA5E5B; } -.token.doctype { - color: #999; +.token.boolean, +.token.constant, +.token.doctype, +.token.number, +.token.regex, +.token.builtin, +.token.class, +.token.hexcode, +.token.class-name, +.token.attr-name { + color: var(--color-yellow); } -.token.entity { - color: #ff6666; +.token.atrule, +.token.attribute, +.token.attr-value .token.punctuation, +.token.attr-value, +.token.pseudo-class, +.token.pseudo-element, +.token.string { + color: var(--color-green); } -.token.function { - color: #c792ea; -} - -.token.hexcode { - color: #f2ff00; +.token.symbol, +.token.function, +.token.id, +.token.important + { + color: var(--color-blue); } +.token.important, .token.id { - color: #c792ea; - font-weight: bold; + font-weight: bold; } -.token.important { - color: #c792ea; - font-weight: bold; + +.token.cdata, +.token.char, +.token.property { + color: #23B1AF; } .token.inserted { - color: #80cbc4; + color: var(--color-green); } .token.keyword { - color: #c792ea; -} - -.token.number { - color: #fd9170; + color: #FF657C; + font-style: italic; } .token.operator { - color: #89ddff; -} - -.token.prolog { - color: #999; -} - -.token.property { - color: #80cbc4; -} - -.token.pseudo-class { - color: #a5e844; -} - -.token.pseudo-element { - color: #a5e844; + color: var(--color-gray-300); } +.token.attr-value .token.attr-equals, .token.punctuation { - color: #89ddff; -} - -.token.regex { - color: #f2ff00; -} - -.token.selector { - color: #ff6666; -} - -.token.string { - color: #a5e844; -} - -.token.symbol { - color: #c792ea; -} - -.token.tag { - color: #ff6666; -} - -.token.unit { - color: #fd9170; -} - -.token.url { - color: #ff6666; -} - -.token.variable { - color: #ff6666; + color: var(--color-gray-200); } diff --git a/docs/public/index.css b/docs/public/index.css index 7fd76509c..490418abe 100644 --- a/docs/public/index.css +++ b/docs/public/index.css @@ -3,9 +3,14 @@ margin: 0; } +/* Global focus outline reset */ +*:focus:not(:focus-visible) { + outline: none; +} + :root { --user-font-scale: 1rem - 16px; - --max-width: calc(100% - 2rem); + --max-width: calc(100% - 1rem); } @media (min-width: 50em) { @@ -20,12 +25,9 @@ body { min-height: 100vh; font-family: var(--font-body); font-size: 1rem; - font-size: clamp( - 0.875rem, - 0.4626rem + 1.0309vw + var(--user-font-scale), - 1.0rem - ); - line-height: 1.625; + font-size: clamp(0.9rem, 0.7500rem + 0.3750vw + var(--user-font-scale), 1rem); + line-height: 1.5; + max-width: 100vw; } nav ul { @@ -37,11 +39,15 @@ nav ul { margin-top: 1rem; } +.content main > :first-child { + margin-top: 0; +} + /* Typography */ :is(h1, h2, h3, h4, h5, h6) { - margin-bottom: 1.38rem; - font-weight: 400; - line-height: 1.3; + margin-bottom: 1rem; + font-weight: bold; + line-height: 1.25; } :is(h1, h2) { @@ -53,29 +59,41 @@ nav ul { } h1 { - font-size: 3.5rem; - font-weight: bold; + font-size: 1.75rem; } h2 { - font-size: 34px; - font-weight: bold; + font-size: 1.25rem; } h3 { - font-size: 22px; - font-weight: bold; + font-size: 1.125rem; } h4 { font-size: 1rem; - font-weight: bold; } h5 { - font-size: clamp(1.2rem, 1.15rem + 0.125vw, 1.25rem); + font-size: 0.8rem; } + +@media (min-width: 60em) { + h1 { + font-size: 2.5rem; + } + + h2 { + font-size: 1.75rem; + } + + h3 { + font-size: 1.25rem; + } +} + + p, .content ul { color: var(--theme-text-light); @@ -90,11 +108,33 @@ a { color: var(--theme-text-accent); font-weight: 400; text-underline-offset: 0.08em; - display: inline-flex; align-items: center; gap: 0.5rem; } +article main :is(ul, ol) > * + * { + margin-top: 0.75rem; +} + +article main li > :is(p, pre, blockquote):not(:first-child) { + margin-top: 1rem; +} + +article main :is(ul, ol) { + padding-left: 1em; +} + +article main ::marker { + font-weight: bold; + color: var(--theme-text-light); +} + +article main iframe { + width: 100%; + height: auto; + aspect-ratio: 16 / 9; +} + a > code:not([class*='language']) { position: relative; color: var(--theme-text-accent); @@ -144,6 +184,7 @@ code:not([class*='language']) { padding: var(--padding-block) var(--padding-inline); margin: calc(var(--padding-block) * -1) -0.125em; border-radius: var(--border-radius); + box-shadow: 0 2px 1px 0 rgba(0,0,0,0.08); } pre > code:not([class*='language']) { @@ -154,24 +195,59 @@ pre > code:not([class*='language']) { color: inherit; } +table, pre { position: relative; - background-color: var(--theme-code-bg); - color: var(--theme-code-text); --padding-block: 1rem; --padding-inline: 2rem; padding: var(--padding-block) var(--padding-inline); padding-right: calc(var(--padding-inline) * 2); + margin-left: calc(var(--padding-inline) * -1); + margin-right: calc(var(--padding-inline) * -1); + font-family: var(--font-mono); - line-height: 1.414; + line-height: 1.5; + font-size: 0.85em; overflow-y: hidden; overflow-x: auto; } +table { + width: 100%; + padding: var(--padding-block) 0; + margin: 0; + border-collapse: collapse; +} + +/* Zebra striping */ +tr:nth-of-type(odd) { + background: var(--theme-bg-hover); +} +th { + background: var(--color-black); + color: white; + font-weight: bold; +} +td, th { + padding: 6px; + text-align: left; +} + +pre { + background-color: var(--theme-code-bg); + color: var(--theme-code-text); +} + +blockquote code:not([class*='language']) { + background-color: var(--theme-bg); +} + @media (min-width: 37.75em) { pre { --padding-inline: 1.25rem; border-radius: 8px; + margin-left: 0; + margin-right: 0; } } @@ -193,6 +269,11 @@ img { align-items: center; } +header { + position: relative; + margin-bottom: 0.5rem; +} + header button { background-color: var(--theme-bg); } @@ -231,7 +312,7 @@ button { gap: 0.25em; padding: 0.33em 0.67em; border-radius: 99em; - background-color: var(--theme-bg); + background-color: var(--color-gray-800); } #theme-toggle > label:focus-within { @@ -240,6 +321,7 @@ button { } #theme-toggle > label { + color: white; position: relative; display: flex; align-items: center; @@ -276,13 +358,12 @@ input[name='theme-toggle'] { .sidebar-nav { width: 100%; position: sticky; - min-height: calc(100vh - 3.5rem); - height: calc(100vh - 3.5rem); - top: 3.5rem; + top: 0; } .sidebar-nav-inner { height: 100%; - padding: 2rem 0; + padding: 0; + padding-top: 2rem; overflow: auto; } @@ -302,7 +383,8 @@ h2.heading { .header-link:hover, .header-link:focus { - border-left-color: var(--color-gray-300); + border-left-color: var(--theme-accent); + color: var(--theme-accent); } .header-link:focus-within { color: var(--theme-text-light); @@ -314,6 +396,10 @@ h2.heading { .header-link:hover svg { opacity: 0.8; } +.header-link a { + display: inline-flex; + gap: 0.5em; +} .header-link.depth-3 { padding-left: 2rem; @@ -335,36 +421,6 @@ h2.heading { font-size: 1rem; } -/* Scrollbar */ - -/* width */ -::-webkit-scrollbar { - width: 0.5rem; -} - -/* Track */ -::-webkit-scrollbar-track { - background: var(--theme-divider); - border-radius: 1rem; -} - -/* Handle */ -::-webkit-scrollbar-thumb { - background: var(--theme-text-lighter); - border-radius: 1rem; -} - -/* Handle on hover */ -::-webkit-scrollbar-thumb:hover { - background: var(--theme-text-light); -} - -/* Buttons */ -::-webkit-scrollbar-button { - display: none; -} -/* Scrollbar - End */ - /* Screenreader Only Text */ .sr-only { position: absolute; @@ -382,3 +438,50 @@ h2.heading { :target { scroll-margin-top: 4rem; } + +.logo { + display: flex; + align-items: center; + gap: 0; + font-size: 1rem; + font-weight: 600; + margin: 0; + line-height: 1; + color: var(--color-white); + text-decoration: none; + transform: translateX(-8px) scale(0.8); +} + +@media (min-width: 60em) { + .logo { + transform: translateX(-8px) scale(1); + } +} + +.logo a { + padding: 0.5em 0.25em; + margin: -0.5em -0.5em; +} + +.logo svg { + height: 40px; + width: auto; + display: block; + color: var(--theme-accent); +} + +.logo a:hover, +.logo a:focus { + background: rgba(var(--theme-accent-rgb), 0.6); +} + +.logo a:hover svg, +.logo a:focus svg { + color: var(--color-white); +} + +.logo h1 { + font: inherit; + color: inherit; + margin: 0; +} diff --git a/docs/public/nav.js b/docs/public/nav.js new file mode 100644 index 000000000..93fadcd61 --- /dev/null +++ b/docs/public/nav.js @@ -0,0 +1,37 @@ +const nav = document.querySelector('body > header'); + +if (!window.matchMedia('(prefers-reduced-motion)').matches) { + window.addEventListener('scroll', onScroll, { passive: true }); +} + +let prev = -1; +let prevDir = 0; +let threshold = 32; + +function onScroll() { + const curr = window.scrollY; + const dir = curr > prev ? 1 : -1; + + if (curr < threshold) { + show(); + document.documentElement.classList.add('initial'); + } else if (dir !== prevDir) { + if (dir === 1) { + hide(); + } else { + show(); + } + } + + prev = curr; +} + +const hide = () => { + nav.classList.add('hidden') + document.documentElement.classList.add('scrolled'); + document.documentElement.classList.remove('initial'); +}; +const show = () => { + nav.classList.remove('hidden'); + document.documentElement.classList.remove('scrolled'); +} diff --git a/docs/public/theme.css b/docs/public/theme.css index 22d765714..a16745daf 100644 --- a/docs/public/theme.css +++ b/docs/public/theme.css @@ -2,8 +2,7 @@ --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; --font-body: system-ui, var(--font-fallback); - --font-mono: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + --font-mono: "IBM Plex Mono", Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; --color-white: #fff; --color-black: #000014; @@ -37,14 +36,14 @@ :root { color-scheme: light; - --theme-accent: var(--color-blue); - --theme-accent-rgb: var(--color-blue-rgb); + --theme-accent: var(--color-orange); + --theme-text-accent: var(--color-orange); + --theme-accent-rgb: var(--color-orange-rgb); --theme-accent-opacity: 0.1; --theme-divider: var(--color-gray-100); --theme-text: var(--color-gray-800); --theme-text-light: var(--color-gray-600); --theme-text-lighter: var(--color-gray-400); - --theme-text-accent: var(--color-blue); --theme-bg: var(--color-white); --theme-bg-hover: var(--color-gray-50); --theme-bg-offset: var(--color-gray-100); @@ -53,6 +52,11 @@ --theme-code-inline-text: var(--theme-text); --theme-code-bg: var(--color-gray-700); --theme-code-text: var(--color-gray-100); + --theme-navbar-bg: var(--color-gray-700); + --theme-navbar-height: 3.5rem; + --theme-sidebar-offset: var(--theme-navbar-height); + --theme-selection-color: var(--color-orange); + --theme-selection-bg: rgba(var(--color-orange-rgb), var(--theme-accent-opacity)); } body { @@ -60,24 +64,33 @@ body { color: var(--theme-text); } +:root.scrolled { + --theme-sidebar-offset: 0; +} + :root.theme-dark { color-scheme: dark; - --theme-accent-opacity: 0.3; - --theme-divider: var(--color-gray-900); + --theme-accent-opacity: 0.4; + --theme-accent: var(--color-orange); + --theme-text-accent: var(--color-orange); + --theme-accent-rgb: var(--color-orange-rgb); + --theme-divider: var(--color-gray-950); --theme-text: var(--color-gray-200); --theme-text-light: var(--color-gray-300); --theme-text-lighter: var(--color-gray-600); - --theme-text-accent: var(--color-white); --theme-bg: var(--color-gray-800); --theme-bg-hover: var(--color-gray-600); --theme-bg-offset: var(--color-gray-950); - --theme-code-inline-bg: var(--color-gray-600); + --theme-code-inline-bg: var(--color-gray-900); --theme-code-inline-text: var(--color-white); --theme-code-bg: var(--color-gray-950); --theme-code-text: var(--color-white); + --theme-navbar-bg: var(--color-gray-900); + --theme-selection-color: var(--color-white); + --theme-selection-bg: rgba(var(--color-purple-rgb), var(--theme-accent-opacity)); } ::selection { - color: var(--theme-text-accent); - background-color: rgba(var(--theme-accent-rgb), var(--theme-accent-opacity)); + color: var(--theme-selection-color); + background-color: var(--theme-selection-bg); } diff --git a/docs/public/theme.js b/docs/public/theme.js deleted file mode 100644 index 91abd5504..000000000 --- a/docs/public/theme.js +++ /dev/null @@ -1,12 +0,0 @@ -(() => { - const root = document.documentElement; - if ( - localStorage.theme === 'dark' || - (!('theme' in localStorage) && - window.matchMedia('(prefers-color-scheme: dark)').matches) - ) { - root.classList.add('theme-dark'); - } else { - root.classList.remove('theme-dark'); - } -})(); diff --git a/docs/src/components/SiteSidebar.astro b/docs/src/components/SiteSidebar.astro index 6d003d71d..7edfda514 100644 --- a/docs/src/components/SiteSidebar.astro +++ b/docs/src/components/SiteSidebar.astro @@ -23,25 +23,34 @@ const {currentPage} = Astro.props; \ No newline at end of file + :global(:root.theme-dark) .nav-link.is-active a { + color: var(--color-white); + } + + @media (min-width: 60em) { + .nav-link a { + border-radius: 999px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .nav-groups { + padding: 0; + } + } + + @media (min-width: 86.25em) { + .nav-link a { + border-radius: 8px; + } + } + + diff --git a/docs/src/layouts/Main.astro b/docs/src/layouts/Main.astro index 52cfa741d..f2a73e07e 100644 --- a/docs/src/layouts/Main.astro +++ b/docs/src/layouts/Main.astro @@ -5,46 +5,72 @@ import ThemeToggle from '../components/ThemeToggle.tsx'; import DocSidebar from '../components/DocSidebar.tsx'; import MenuToggle from '../components/MenuToggle.tsx'; -const { content } = Astro.props; +const { content = {}, centered = false } = Astro.props; const headers = content?.astro?.headers; -const currentPage = Astro.request.url.pathname; -const currentFile = currentPage === '/' ? 'src/pages/index.md' : `src/pages${currentPage.replace(/\/$/, "")}.md`; -const githubEditUrl = `https://github.com/snowpackjs/astro/edit/main/docs/${currentFile}`; +const currentPage = Astro.request?.url?.pathname; +let currentFile; +let githubEditUrl; +if (currentPage) { + currentFile = currentPage === '/' ? 'src/pages/index.md' : `src/pages${currentPage.replace(/\/$/, "")}.md`; + githubEditUrl = `https://github.com/snowpackjs/astro/blob/main/docs/${currentFile}`; +} --- - + {content.title} + + + -