start working on sidenotes post

This commit is contained in:
Joseph Montanaro 2023-08-15 11:10:22 -07:00
parent 60eea00b88
commit 7d5c696fa7

View File

@ -0,0 +1,94 @@
---
title: Sidenotes
description: An entirely-too-detailed dive into how I implemented sidenotes for this blog.
date: 2023-08-14
draft: true
---
<script>
import Dropcap from '$lib/Dropcap.svelte';
import Sidenote from '$lib/Sidenote.svelte';
</script>
<style>
.counter {
counter-increment: sidenote;
}
.counter::before {
content: counter(sidenote);
color: var(--accent-color);
font-size: 0.75rem;
position: relative;
bottom: 0.2rem;
margin-left: 0.1rem;
}
.sidenote-absolute {
position: absolute;
left: calc(50vw + var(--content-width) / 2 + 1rem);
max-width: 12rem;
font-size: 0.75rem;
}
.sidenote-absolute::before {
content: counter(sidenote);
color: var(--accent-color);
font-size: 0.75rem;
position: relative;
bottom: 0.2rem;
margin-right: 0.1rem;
}
.example-sidenote {
float: right;
clear: right;
max-width: 14rem;
margin-right: -16rem;
padding-left: 2rem;
}
.example-sidenote.nested {
margin-right: 0;
}
.example-sidenote.animated {
animation: slideover 1.5s ease-in-out infinite;
}
@keyframes slideover {
from {margin-right: 0;}
to {margin-right: -16rem;}
}
</style>
<Dropcap word="One">of my major goals when building this blog was to have sidenotes. I've always been a fan of sidenotes on the web, because the most comfortable reading width for a column of text is <em>far</em> less than the absurd amounts of screen width we tend to have available, and what else are we going to use it for?<Sidenote>Some sites use it for ads, of course, which is yet another example of how advertising ruins everything.</Sidenote></Dropcap>
Footnotes don't really work on the web the way they do on paper, since the web doesn't have page breaks. You _can_ stick your footnotes in a floating box at the bottom of the page, so they're visible at the bottom of the text just like they would be on a printed page, but this sacrifices precious vertical space.<Sidenote>On mobile, it's _horizontal_ space that's at a premium, so I do use approach there. Although I'm a pretty heavy user of sidenotes, so I have to make them toggleable as well or they'd fill up the entire screen.</Sidenote> Plus, you usually end up with the notes further away from the point of divergence than they would be as sidenotes anyway.
I'm also not a huge fan of show-on-hover/click for marginalia, because it requires an extra interaction--and often a fairly precise one, which is always annoying.<Sidenote>This is especially true on mobile, where I've found myself selecting text instead of showing/hiding a note because I didn't get my finger in quite the right place.</Sidenote> Admittedly this style _does_ get you the absolute minimum distance between the marginalia and the main content, but I think the extra interaction is too heavy a price to pay.<Sidenote>Except on mobile, as mentioned. Mobile displays just don't have _any_ extra space at all, so you're left choosing between various unappealing options.</Sidenote>
So we're left with sidenotes, which I consider the crème de la crème of web-based marginalia. So okay, sure, sidenotes are great and all, but how do we actually _do_ them? Well! _wipes imaginary sweat from brow_ It sure was tough, and for a while there I thought I'd never make it through, but I done did figgered it out in the end!<Sidenote>_Narrator:_ He had not figured it out. He had googled around until he found someone else who had figured it out, and then copied their solution.</Sidenote>
## The Suboptimal Solution: Absolute Positioning
I'm naturally lazy, so I wanted the authoring experience to be as low-friction as possible so that I wouldn't end up foregoing sidenotes just because they were too much of a pain to put in. Since I had already settled on [mdsvex](https://mdsvex.pngwn.io/docs) for authoring my posts, I wanted sidenotes to be just another component that I could throw in mid-stream whenever I had an ancillary thought to express. This meant that DOM-wise, the sidenotes were going to be mixed right in with the main body text. Since I was also hoping to do this in pure CSS,<Sidenote>Because as much as I claim not to care, I secretly fear the Hacker News anti-Javascript brigade and desperately crave their approval.</Sidenote> meant that I was going to have to do something that removed the sidenote from the normal document flow, such as `position: absolute`.
My first approach was something like this:
```css
.sidenote {
position: absolute;
/* 50vw takes us to the midpoint of the page,
half of content-width gets out out to the gutter,
and the extra 1rem gives us some breathing room. */
left: calc(50vw + var(--content-width) / 2 + 1rem);
max-width: 12rem;
font-size: 0.75rem;
}
```
And it worked! Sort of. Here's an example.<span class="counter"></span><span class="sidenote-absolute">My initial take on sidenotes. Seems to be working, right?</span> Unfortunately it has a couple of flaws. For one, it will overflow the screen as soon as the viewport gets too narow, which is easy enough to solve (just a matter of a sufficiently complex `calc()` expression) but definitely needs doing. More importantly, however, there's no facility for dealing with overlaps. So if you have multiple sidenotes\*<span class="sidenote-absolute">Like this one.</span> too close\*<span class="sidenote-absolute" style="transform: translateY(0.2rem)">And this one, which I've moved down just a smidge to make the overlap more apparent.</span> together, they will overlap because absolute positioning Just Doesn't Care.
https://scripter.co/sidenotes-using-only-css/