Skip to content

Commit

Permalink
more accessible heading-anchors w/ anchored-heading wrapper divs (#44)
Browse files Browse the repository at this point in the history
* more accessible heading-anchors with anchored-heading wrapper divs
  see conversation on mastodon at:
  https://tweesecake.social/@weirdwriter/112939207207501581

* add --anchored-heading-offset for mobile safari

* post + anchored-heading margin fixes and css cleanup

* spaces to tabs
  • Loading branch information
rdela authored Aug 20, 2024
1 parent 66656b5 commit 6ce0cae
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 43 deletions.
55 changes: 37 additions & 18 deletions _includes/layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,61 @@
4. Learn more: https://github.com/11ty/eleventy-plugin-bundle
#}

{#- Add the contents of a file to the bundle #}
{%- css %}{% include "public/css/index.css" %}{% endcss %}

{%- if not metadata.mono %}
{%- css %}{% include "public/css/rainbow.css" %}{% endcss %}
{% endif %}
{#- Or add from node_modules #}
{# {%- css %}{% include "node_modules/prismjs/themes/prism-okaidia.css" %}{% endcss %} #}

{#- Add an arbitrary string to the bundle #}
{%- css %}
* { box-sizing: border-box; }
:root {
--anchored-heading-gap: 0.375;
--anchored-heading-margin: calc(var(--anchored-heading-gap) * 1ch);
--anchored-heading-rem: calc(var(--anchored-heading-gap) * 1rem);
--anchored-heading-min-size: 1.328125rem; {# calc(var(--article-font-size) * var(--article-h4-size)) #}
--anchored-heading-difference: calc(var(--anchored-heading-gap) * var(--anchored-heading-min-size) - var(--anchored-heading-rem));
--anchored-heading-offset: calc(var(--anchored-heading-min-size) + var(--anchored-heading-difference));
}

.anchored-heading {
align-items: last baseline;
display: flex;
margin-block-end: 1.5rem;
margin-block-start: 1.5rem;
}

heading-anchors a[href^="#"] {
.anchored-heading :is(h1, h2, h3, h4) {
margin-block-end: 0;
margin-block-start: 0;
max-inline-size: calc(100% - var(--anchored-heading-offset));
}

heading-anchors a[href].direct-link {
color: transparent;
display: inline-block;
margin-inline-start: 0.375ch;
margin-inline-start: var(--anchored-heading-margin);
max-inline-size: 1ch;
overflow-x: hidden;
pointer-events: none;
text-decoration: none;
vertical-align: bottom;
white-space: nowrap;
}

heading-anchors a[href^="#"]::before {
content: "#";
heading-anchors a[href].direct-link::before {
color: var(--text-color-link);
content: "#";
pointer-events: auto;
}

heading-anchors a[href^="#"]:focus::before,
heading-anchors a[href^="#"]:hover::before {
heading-anchors a[href].direct-link:focus::before,
heading-anchors a[href].direct-link:hover::before {
color: var(--text-color-link-highlight);
text-decoration: underline;
}
{% endcss %}
{#- Add the contents of a file to the bundle #}
{%- css %}{% include "public/css/index.css" %}{% endcss %}

{%- if not metadata.mono %}
{%- css %}{% include "public/css/rainbow.css" %}{% endcss %}
{% endif %}
{#- Or add from node_modules #}
{# {%- css %}{% include "node_modules/prismjs/themes/prism-okaidia.css" %}{% endcss %} #}

{#- Render the CSS bundle using Inlined CSS (for the fastest site performance in production) #}
<style>{% getBundle "css" %}</style>
Expand Down Expand Up @@ -86,7 +105,7 @@ heading-anchors a[href^="#"]:hover::before {
</header>

<main id="skip">
<heading-anchors position="beforeend">
<heading-anchors>
{{ content | safe }}
</heading-anchors>
</main>
Expand Down
15 changes: 12 additions & 3 deletions _includes/layouts/post.njk
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@
layout: layouts/base.njk
---
{%- css %}
/* Only include the syntax highlighter CSS on blog posts */
{# Only include the syntax highlighter CSS on blog posts #}
{% include "node_modules/prismjs/themes/prism-okaidia.css" %}
{% include "public/css/prism-diff.css" %}
pre[class*="language-"] {
margin: .375rem 0 1.5rem;
}

{# no top margin on post hero or title #}
main figure.hero:first-of-type,
main h1.title:first-of-type {
margin-block-start: 0;
}
{%- endcss %}
<figure>
<figure class="hero">
{%- if hero and heroalt %}

{%- if herolink %}
Expand All @@ -28,7 +37,7 @@ layout: layouts/base.njk
{%- endif %}
{%- endif %}
</figure>
<h1>{{ title }}</h1>
<h1 class="title" data-heading-anchors-optout>{{ title }}</h1>

<ul class="post-metadata">
<li><time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></li>
Expand Down
2 changes: 1 addition & 1 deletion content/archive/thirdpost.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ function myCommand() {
console.log('Test');
```

## Section Header
#### This is a much longer Section Header with links: [Megatron](https://en.wikipedia.org/wiki/Megatron) always low key wished to be a [GoBot](https://en.wikipedia.org/wiki/GoBots).

Capitalize on low hanging fruit to identify a ballpark value added activity to beta test. Override the digital divide with additional clickthroughs from DevOps. Nanotechnology immersion along the information highway will close the loop on focusing solely on the bottom line.
2 changes: 0 additions & 2 deletions eleventy.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ export default async function(eleventyConfig) {
eleventyConfig.addPassthroughCopy({
"./public/": "/",
"./node_modules/prismjs/themes/prism-okaidia.css": "/css/prism-okaidia.css",
"./node_modules/@daviddarnes/heading-anchors/heading-anchors.js":
"/js/heading-anchors.js",
});

// Run Eleventy when these files change:
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"@11ty/eleventy-plugin-bundle": "^2.0.2",
"@11ty/eleventy-plugin-rss": "^2.0.2",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
"@daviddarnes/heading-anchors": "^2.0.0",
"@famebot/chromagen": "^1.0.1",
"luxon": "^3.4.4"
}
Expand Down
43 changes: 25 additions & 18 deletions public/css/index.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
/* Defaults */
:root {
--article-font-size: 1.25rem;
--article-h1-size: 2em;
--article-h2-size: 1.5em;
--article-h3-size: 1.125em;
--article-h4-size: 1.0625em;
--article-h5-size: 0.9375em;
--article-h6-size: 1.25rem;
--article-line-height-body: 1.5;
--article-line-height-heading: 1.25;
--font-family: -apple-system, system-ui, sans-serif;
--font-family-monospace: Consolas, Menlo, Monaco, Andale Mono WT, Andale Mono,
Lucida Console, Lucida Sans Typewriter, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Liberation Mono, Nimbus Mono L, Courier New,
Courier, monospace;
--article-font-size: 1.25rem;
--syntax-tab-size: 4;
--vspace: 1.5rem;
}

/* Default theme colors */
Expand Down Expand Up @@ -82,6 +91,7 @@ body {
.pantalla {
margin: 0 auto;
max-width: 50em;
position: relative;
}

/* https://www.a11yproject.com/posts/how-to-hide-content/ */
Expand All @@ -102,8 +112,8 @@ h4,
h5,
h6,
p {
margin-block-end: 1.5rem;
margin-block-start: 1.5rem;
margin-block-end: var(--vspace);
margin-block-start: var(--vspace);
}

h1,
Expand All @@ -112,32 +122,32 @@ h3,
h4,
h5,
h6 {
line-height: 1.25;
line-height: var(--article-line-height-heading);
}

h1 {
font-size: 2em;
font-size: var(--article-h1-size);
}

h2 {
font-size: 1.5em;
font-size: var(--article-h2-size);
}

h3 {
font-size: 1.125em;
font-size: var(--article-h3-size);
}

h4 {
font-size: 1.0625em;
font-size: var(--article-h4-size);
}

h5 {
font-size: 0.9375em;
font-size: var(--article-h5-size);
text-transform: uppercase;
}

h6 {
font-size: 0.875em;
font-size: var(--article-h6-size);
text-transform: uppercase;
}

Expand All @@ -147,7 +157,7 @@ p:last-child {

p,
li {
line-height: 1.5;
line-height: var(--article-line-height-body);
}

a {
Expand Down Expand Up @@ -202,7 +212,7 @@ button:active,
}

figure {
margin: 0;
margin: 0 0 calc(var(--vspace) / 2);
}

figcaption {
Expand Down Expand Up @@ -231,7 +241,7 @@ code {
}

pre:not([class*="language-"]) {
margin: 0.5em 0;
margin: calc(var(--vspace) / 4) 0 var(--vspace);
line-height: 1.375; /* 22px /16 */
-moz-tab-size: var(--syntax-tab-size);
-o-tab-size: var(--syntax-tab-size);
Expand All @@ -253,10 +263,7 @@ code {
main {
font-size: var(--article-font-size);
padding: 0 1rem;
}

main :first-child {
margin-block-start: 0;
position: relative;
}

main img {
Expand Down Expand Up @@ -401,7 +408,7 @@ header {
}

.postlist-text a {
line-height: 1.25;
line-height: var(--article-line-height-heading);
}

.ellipsize {
Expand Down
53 changes: 53 additions & 0 deletions public/js/heading-anchors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Thanks to @daviddarnes/heading-anchors 2.0.0
* https://github.com/daviddarnes/heading-anchors
* and 11ty
* https://github.com/11ty/11ty-website/blob/main/src/_includes/components/heading-anchors.js
*/
class HeadingAnchors extends HTMLElement {
static register(tagName) {
if ("customElements" in window) {
customElements.define(tagName || "heading-anchors", HeadingAnchors);
}
}

connectedCallback() {
this.headings.forEach((heading) => {
if (
heading.hasAttribute("data-heading-anchors-optout") === false
) {
heading.insertAdjacentHTML(this.position, this.anchor(heading));
heading.remove();
}
});
}

anchor(heading) {
// TODO this would be good use case for shadow dom
let anchor = document.createElement("a");
anchor.setAttribute("data-pagefind-ignore", "");
anchor.href = `#${heading.id}`;
anchor.classList.add("direct-link");
anchor.innerHTML = `<span class="sr-only">Jump to heading</span><span aria-hidden="true">#</span>`;
let flexybox = document.createElement("div");
flexybox.classList.add("anchored-heading");
flexybox.innerHTML = `${heading.outerHTML}${anchor.outerHTML}`;
return flexybox.outerHTML;
}

get headings() {
return this.querySelectorAll(
this.selector.split(",").map((entry) => `${entry.trim()}[id]`)
);
}

get selector() {
return this.getAttribute("selector") || "h1,h2,h3,h4";
}

get position() {
return this.getAttribute("position") || "beforebegin";
}
}

HeadingAnchors.register();

0 comments on commit 6ce0cae

Please sign in to comment.