mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-05-15 15:08:51 +02:00
feat: add heading anchors for direct linking to article sections
Uses markdown-it-anchor to generate linkable IDs on h2-h4 headings. Headings become clickable links with a subtle # indicator on hover. Includes scroll-margin-top so anchored headings don't hide behind the sticky header.
This commit is contained in:
@@ -468,6 +468,31 @@
|
||||
scroll-margin-top: 80px; /* Prevent header overlap when scrolling to anchors */
|
||||
}
|
||||
|
||||
/* Heading anchors — generated by markdown-it-anchor */
|
||||
.prose h2[id],
|
||||
.prose h3[id],
|
||||
.prose h4[id] {
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
.prose :is(h2, h3, h4) > a.header-anchor {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.prose :is(h2, h3, h4) > a.header-anchor:hover {
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--tw-prose-links, currentColor);
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
.prose :is(h2, h3, h4) > a.header-anchor::after {
|
||||
content: " #";
|
||||
opacity: 0;
|
||||
font-weight: normal;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
.prose :is(h2, h3, h4):hover > a.header-anchor::after {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.post-list li {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: auto 200px;
|
||||
|
||||
@@ -4,6 +4,7 @@ import embedEverything from "eleventy-plugin-embed-everything";
|
||||
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||
import sitemap from "@quasibit/eleventy-plugin-sitemap";
|
||||
import markdownIt from "markdown-it";
|
||||
import markdownItAnchor from "markdown-it-anchor";
|
||||
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
|
||||
import { minify } from "html-minifier-terser";
|
||||
import { createHash } from "crypto";
|
||||
@@ -48,6 +49,11 @@ export default function (eleventyConfig) {
|
||||
linkify: true, // Auto-convert URLs to clickable links
|
||||
typographer: true,
|
||||
});
|
||||
md.use(markdownItAnchor, {
|
||||
permalink: markdownItAnchor.permalink.headerLink(),
|
||||
slugify: (s) => s.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, ""),
|
||||
level: [2, 3, 4],
|
||||
});
|
||||
eleventyConfig.setLibrary("md", md);
|
||||
|
||||
// Syntax highlighting for fenced code blocks (```lang)
|
||||
|
||||
Generated
+36
@@ -19,6 +19,7 @@
|
||||
"eleventy-plugin-embed-everything": "^1.21.0",
|
||||
"html-minifier-terser": "^7.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-anchor": "^9.2.0",
|
||||
"pagefind": "^1.3.0",
|
||||
"rss-parser": "^3.13.0"
|
||||
},
|
||||
@@ -1053,6 +1054,31 @@
|
||||
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.18.63",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
|
||||
@@ -2812,6 +2838,16 @@
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-anchor": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
|
||||
"integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
|
||||
"license": "Unlicense",
|
||||
"peerDependencies": {
|
||||
"@types/markdown-it": "*",
|
||||
"markdown-it": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"eleventy-plugin-embed-everything": "^1.21.0",
|
||||
"html-minifier-terser": "^7.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-anchor": "^9.2.0",
|
||||
"pagefind": "^1.3.0",
|
||||
"rss-parser": "^3.13.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user