Enhanced Footnote Navigation with Visual Highlighting
Summary
Implemented comprehensive footnote navigation improvements including visual highlighting animations, proper scroll positioning, and enhanced user experience for both footnote references and definitions.
Why Care
These improvements significantly enhance the reading experience by providing clear visual feedback when navigating between footnotes and their references. The smooth animations and proper scroll positioning make it easier to track footnote relationships in long-form content, reducing cognitive load and improving content discoverability.
Implementation
Changes Made
Core Files Modified:
site/src/components/markdown/AstroMarkdown.astro- Main footnote rendering and highlighting logicsite/src/utils/slugify.ts- Fixed text extraction for inline code in headingssite/src/components/articles/OneArticleOnPage.astro- Added scroll-margin-top for headingssite/src/layouts/OneArticle.astro- Added scroll-margin-top for headingssite/src/components/markdown/TableOfContents.astro- Improved progress bar visibilitysite/src/components/markdown/CopyLinkButton.astro- Fixed TypeScript linter error
Test File Created:
content/lost-in-public/market-maps/Footnote-Highlight-Test.md- Comprehensive test document for footnote functionality
Key Improvements:
- Visual Highlighting System
- Added CSS animations for footnote references and definitions
- Implemented separate animation styles for references (with scaling) and definitions (without layout changes)
- Created smooth 1-second animations with proper easing
- Enhanced Navigation
- Fixed scroll positioning for footnote references with proper header clearance
- Improved element ID handling for both numeric and alphanumeric footnote IDs
- Added scroll-margin-top to prevent elements from being hidden behind fixed header
- Robust JavaScript Implementation
- Replaced setTimeout-based animation removal with animationend event listeners
- Eliminated flickering issues by properly timing class removal
- Added comprehensive debugging and error handling
- Layout Improvements
- Moved Table of Contents progress bar outside scroll area for better visibility
- Fixed heading ID generation to include inline code content
- Improved scroll behavior consistency across different content types
Technical Details
CSS Animation System
css
/* Footnote reference highlighting with scaling */
.footnote-ref.highlighted {
background: rgba(4, 229, 229, 0.6);
border-radius: 6px;
padding: 8px;
box-shadow: 0 0 20px rgba(4, 229, 229, 0.8), 0 0 40px rgba(4, 229, 229, 0.4);
animation: footnote-highlight 1s ease-out;
transform: scale(1.1);
}
/* Footnote definition highlighting without layout changes */
.footnote-definition.highlighted {
background: rgba(4, 229, 229, 0.3);
box-shadow: 0 0 20px rgba(4, 229, 229, 0.6);
animation: footnote-highlight-definition 1s ease-out;
} JavaScript Event Handling
javascript
// Listen for animation end to remove the class
const handleAnimationEnd = () => {
targetElement.classList.remove('highlighted');
targetElement.removeEventListener('animationend', handleAnimationEnd);
console.log('[Footnote Highlight] Animation ended, removed highlight class');
};
targetElement.addEventListener('animationend', handleAnimationEnd); Enhanced Element Detection
javascript
// Check for footnote references (#ref-*) or footnote definitions (any alphanumeric ID)
if (hash.startsWith('#ref-') || /^#[a-zA-Z0-9]+$/.test(hash)) {
if (hash.startsWith('#ref-')) {
// For footnote references, use querySelector (safe for #ref-*)
targetElement = document.querySelector(hash);
} else {
// For footnote definitions (#1, #2, etc.), use getElementById to avoid CSS selector issues
const id = hash.substring(1);
targetElement = document.getElementById(id);
}
} Scroll Positioning Fixes
css
/* Added to both OneArticleOnPage.astro and OneArticle.astro */
.prose :global(h1),
.prose :global(h2),
.prose :global(h3),
.prose :global(h4),
.prose :global(h5),
.prose :global(h6) {
scroll-margin-top: 150px; /* Account for fixed header */
}
.footnote-ref {
scroll-margin-top: 150px; /* Account for fixed header when scrolling back to reference */
display: inline-block; /* Ensure proper scroll positioning */
position: relative; /* Ensure proper scroll positioning */
} Integration Points
Markdown Processing Pipeline
- Enhanced
extractAllTextfunction inslugify.tsto properly handle inline code in headings - Updated footnote rendering to use correct element IDs and structure
- Integrated with existing scroll behavior and navigation systems
Table of Contents Integration
- Modified progress bar positioning to ensure visibility
- Maintained compatibility with existing TOC scroll tracking
- Preserved all existing TOC functionality while improving layout
Content Management
- Created test document following project's markdown structure
- Ensured compatibility with existing content processing pipeline
- Maintained backward compatibility with existing footnote formats
Documentation
Test File Structure
The created test file (
Footnote-Highlight-Test.md) includes:- Multiple footnote references and definitions
- Direct navigation links for testing
- Expected behavior documentation
- Comprehensive test scenarios
Usage Examples
Browser Compatibility
- Tested with modern browsers supporting CSS animations and ES6 features
- Graceful degradation for older browsers (animations disabled, navigation still works)
- Mobile-friendly touch interactions
Performance Considerations
- Lightweight CSS animations using transform and opacity
- Efficient event listener management with automatic cleanup
- Minimal DOM manipulation for optimal performance
Citations
[a1b2c3] This footnote definition will highlight when navigated to directly.