diff --git a/src/dropdown/index.html b/src/dropdown/index.html new file mode 100644 index 0000000..451780e --- /dev/null +++ b/src/dropdown/index.html @@ -0,0 +1,263 @@ + + + + + + + + Bird News Daily + + + +
+

Bird News Daily

+

+ Building a Disclosure Navigation with Baseline features +

+
+ +
+
+

Bird News Daily

+
+

+ Quail eider garganey eu scotering Tinamou nostrud Tinamou nightjar sit + sunt peregrine non cuckoo puffin incididunt. +

+

+ Vesper sparrow qui nisi labore ut do duail peregrine cupidatat occaecat + ea minim garganey avocet. Duail enim in scotering nisi avocet amet. +

+

+ Amet cackling goose ea hummingbird sunt amet puffin officia in quail + garganey cackling goose est. Ut hummingbird quail cuckoo peregrine + cackling goose ex consequat ut sunt owl ea vesper sparrow amet. +

+
+ + +
+
+ + + + + diff --git a/src/dropdown/script.js b/src/dropdown/script.js new file mode 100644 index 0000000..10fdd17 --- /dev/null +++ b/src/dropdown/script.js @@ -0,0 +1,43 @@ +window.addEventListener("hashchange", () => { + handleRoute(window.location.hash); +}); + +const CONTAINS_PATH_TEXT = "Contains current page link"; +let shownBlock = 0; + +function handleRoute(newPage) { + // Close all open popovers, would be unneeded if we actually had navigated to a new page + document.querySelectorAll(":popover-open").forEach((popover) => { + popover.hidePopover(); + }); + + // Replace the content + const heading = document.getElementById("id-page-title"); + heading.innerText = newPage; + + const contentBlocks = document.querySelectorAll("[data-article]"); + shownBlock = (shownBlock + 1) % contentBlocks.length; + + contentBlocks.forEach((block, index) => { + if(index === shownBlock) block.removeAttribute('hidden'); + else block.setAttribute('hidden', ''); + }); + + const formerLink = document.querySelector("[aria-current]"); + if (formerLink) formerLink.removeAttribute("aria-current"); + + const linkToRoute = document.querySelector(`[href="${newPage}"]`); + linkToRoute.setAttribute("aria-current", "page"); + + // Remove existing title attributes + document + .querySelectorAll(`[title="${CONTAINS_PATH_TEXT}"]`) + .forEach((element) => { + element.removeAttribute("title"); + }); + + // Add a title to ancestors + document.querySelectorAll("li:has(a[aria-current])").forEach((element) => { + element.setAttribute("title", CONTAINS_PATH_TEXT); + }); +} diff --git a/src/dropdown/style.css b/src/dropdown/style.css new file mode 100644 index 0000000..fe77322 --- /dev/null +++ b/src/dropdown/style.css @@ -0,0 +1,331 @@ +@layer reset, theme, layout, components; + +@layer components { + [data-menu] { + --popover-offset: -10px; + align-content: start; + border: 1px solid var(--border-color); + border-radius: 3px; + box-shadow: 4px 8px 10px 0 var(--shadow), + 0 6px 8px 0 var(--shadow); + opacity: var(--show-menu, 0); + padding: 1rem 0; + position: absolute; + /* Override default popover browser styles */ + margin: 0; + inset: auto; + transition: + opacity var(--slow), + inset var(--fast), + overlay var(--slow) allow-discrete, + display var(--display-timing, var(--slow)) allow-discrete; + + @supports not (overlay: auto) { + --display-timing: 0s; + } + + &:popover-open { + --show-menu: 1; + --outer-popover-inset: 0; + --nested-popover-inset: 0; + + display: grid; + + @supports not (position-area: block-end span-inline-end) { + --outer-popover-inset: auto; + --nested-popover-inset: auto; + } + + @starting-style { + --show-menu: 0; + --outer-popover-inset: -10px; + --nested-popover-inset: -10px; + } + + @media (prefers-reduced-motion: reduce) { + --outer-popover-inset: auto; + --nested-popover-inset: auto; + } + } + + li { + align-items: start; + display: flex; + flex-direction: row; + } + } + + [data-menu~='outer'] { + position-area: block-end span-inline-end; + position-try-fallbacks: flip-inline; + inline-size: max-content; + min-inline-size: anchor-size(); + inset-block-start: var(--outer-popover-inset, var(--popover-offset)); + } + + [data-menu~='nested'] { + position-area: span-block-end inline-end; + position-try: flip-inline, flip-start; + inset-inline-start: var(--nested-popover-inset, var(--popover-offset)); + } + + .nav-list { + align-items: center; + display: flex; + flex-wrap: wrap; + background: var(--color-gray); + list-style: none; + margin: 0; + padding: 0; + + button:has(+ :popover-open) { + --rotate-btn-icon: 90deg; + } + } + + .nav-list-item button, + .nav-list-item a { + background: var(--navlist-item-bg, transparent); + border: thin solid transparent; + padding: 0.5em 0.75em; + inline-size: 100%; + + &:hover, + &:focus { + --link-focus-color: var(--highlight-color); + --btn-text: var(--highlight-color); + --navlist-item-bg: light-dark(oklch(90.5% 0.013 196), oklch(35.3% 0.085 238)); + } + } + + [data-icon~="triangle"] { + --gradient-start-default: var(--outline-color); + --gradient-end-default: var(--highlight-color); + + margin-block-start: .25ch; + rotate: var(--rotate-btn-icon, 0); + transition: rotate var(--fast) ease-in; + + .gradient-start { + stop-color: var(--disclosure-gradient-start, var(--gradient-start-default)); + } + + .gradient-end { + stop-color: var(--disclosure-gradient-end, var(--gradient-end-default)); + } + + @media (forced-colors: active) { + --disclosure-gradient-start: currentColor; + --disclosure-gradient-end: currentColor; + } + } + + a[aria-current], + li:has(a[aria-current])>button { + --navlist-item-bg: var(--active); + --link-focus-color: transparent; + } + + [data-button] { + --btn-text: var(--text-color); + + align-items: center; + background: var(--btn-bg); + color: var(--btn-text); + cursor: pointer; + display: inline-flex; + font-size: inherit; + padding: 0.5em 0.75em; + transition: background var(--slow) ease-in, color var(--slow) ease-in-out; + } + + [data-icon] { + block-size: 1em; + display: inline-block; + inline-size: 1em; + overflow: visible; + } +} + + +@layer layout { + body { + display: grid; + grid-template: + "header" min-content + "nav" min-content "main" 1fr "footer" min-content / 100%; + } + + main { + display: grid; + grid-area: main; + grid-template-columns: minmax(0, 60ch); + margin-inline: auto; + padding: var(--gap) 1em calc(var(--gap) * 3); + } + + nav { + grid-area: nav; + } + + header { + grid-area: header; + padding: .5em 1em; + + .title { + margin: 0; + } + + .tagline { + margin-block-end: 0; + } + } + + footer { + grid-area: footer; + padding: 0.5em; + } +} + +@layer theme { + + html { + + /* Sizing */ + --text-small: clamp(0.938rem, 0.824rem + 0.568cqi, 1.25rem); + --text-normal: clamp(1.25rem, 1.023rem + 1.136cqi, 1.875rem); + --text-large: clamp(1.35rem, 0.818rem + 2.659cqi, 2.813rem); + --text-xlarge: clamp(1.7rem, 0.784rem + 4.58cqi, 4.219rem); + --gap: clamp(2cqi, 0.5lh, 5cqi); + --quarter-gap: calc(var(--gap) / 4); + --double-gap: calc(var(--gap) * 2); + + /* Transition Timing */ + --faster: 100ms; + --fast: 250ms; + --slow: 500ms; + + /* colors */ + color-scheme: light dark; + --accent-color: light-dark(oklch(66.3% 0.234 253), oklch(45.2% 0.054 302)); + --active: var(--color-primary); + --text-color: light-dark(oklch(0% 0 none), oklch(100% 0 none)); + --highlight-color: light-dark(oklch(43.9% 0.132 250), + oklch(92.6% 0.132 250)); + --border-color: light-dark(oklch(62.5% 0 none), oklch(87% 0 none)); + --shadow: light-dark(oklch(from var(--border-color) l c h / 0.753), oklch(24.899% 0.00564 285.917 / 0.83)); + --outline-color: light-dark(oklch(50.9% 0.37 323.38), + oklch(93.9% 0.37 323.38)); + --color-primary: light-dark(oklch(88.631% 0.02763 225), + oklch(43.3% 0.085 238)); + --color-gray: light-dark(oklch(94.912% 0 none), oklch(41.7% 0 none)); + --background-color: light-dark(oklch(91.141% 0.00652 16.403), oklch(22.635% 0.01351 291.83)); + ; + + /* from https://modernfontstacks.com/ */ + --sans-serif-font: + Seravek, "Gill Sans Nova", Ubuntu, Calibri, "DejaVu Sans", + source-sans-pro, sans-serif; + --serif-font: Charter, "Bitstream Charter", "Sitka Text", Cambria, serif; + font-family: var(--sans-serif-font); + } + + body { + background: var(--background-color); + color: var(--text-color); + font-size: var(--text-normal); + margin: 0; + } + + header { + background-color: var(--color-primary); + + .tagline { + font-family: var(--serif-font); + font-style: italic; + } + } + + + + footer { + background-color: var(--color-primary); + font-family: var(--serif-font); + font-size: var(--text-small); + font-style: italic; + } + + :focus { + outline: medium dotted var(--outline-color); + outline-offset: 0.18em; + } + + :any-link { + color: var(--link-text-color, currentColor); + text-decoration: underline; + text-underline-offset: 0.18em; + text-decoration-color: var(--link-focus-color, var(--highlight-color)); + text-decoration-thickness: var(--underline-thickness, 0.1em); + transition: + color 0.3s ease-in-out, + text-decoration-thickness 0.3s ease-in, + text-decoration-color 0.3s linear; + + &:hover, + &:focus { + --link-text-color: var(--highlight-color); + --link-focus-color: var(--background-color); + --underline-thickness: 0.18em; + } + } + + .visually-hidden:not(:focus, :active) { + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(1px 1px 1px 1px); + height: 1px; + overflow: hidden; + pointer-events: none; + position: absolute; + width: 1px; + } + + svg { + fill: var(--fill, currentColor); + padding: 1px; + } +} + +@layer reset { + * { + box-sizing: border-box; + } + + html { + block-size: 100%; + } + + body { + margin: unset; + min-block-size: 100vh; + } + + picture { + display: contents; + } + + img { + display: block; + } + + img, + svg { + max-inline-size: 100%; + } + + input, + button, + textarea, + select { + font: inherit; + } +} diff --git a/src/index.html b/src/index.html index aaa5501..2c8cf99 100644 --- a/src/index.html +++ b/src/index.html @@ -28,6 +28,7 @@

List of Demos