Notes on the web, take 1

I decided to definitively solve the problem of notes on the web in the context of my Thidrekssaga side project. What I offer today is not that definitive solution, but just my first take. I’m looking for feedback.

So let’s talk notes.

First we should ask ourselves how notes should work on the web. Then we’ll look at the technical details of my first take.

Please open my first, as-yet insufficient, version in a new tab or something; I’ll refer to it from time to time. Today’s question is whether this is a good (the best?) way of visually displaying notes.

The user experience

My purpose with this side project is to transfer the user experience of footnotes in books to the web. So let’s first be clear on what we want to achieve.

Take a look at this page from the Quedlinburger Annals in the historical source collection MGH. It uses traditional footnotes, and this is the effect I’m after.

The purpose of such traditional footnotes is to allow the reader to rapidly scan both main text and notes, or to even go through the notes first and then find the main text sections they apply to. The crucial part is that both main text and footnotes are on the same page; above the fold, in web terms. By moving their eyes readers can quickly scan both of them.

Footnotes should also allow the reader to scan the notes first and then find the main text they apply to. This is a valuable method of reading, since you may find unexpected material in the notes that is not mentioned in the main text.

On the MGH example page, the notes contain clarifications as well as references to the Liber Pontificalis, another source. By reading main text and notes at the same time, the reader can view the clarifications in the context of the main text, and can find out exactly which bits of the Annals use the Liber Pontificalis as a source.

The other option is to place all these notes at the end of the book; to make them endnotes. I dislike books with endnotes because the user experience is just wrong: it is hard to find the note you want, and it is impossible to go back from a note to the main text it refers back to.

When we port footnotes to the web, the worst thing we can do is place them at the end of the document. It is likely the reader will be unable to see main text and notes at the same time: they have effectively become endnotes. What we should do instead on the web is place the notes to the side of the main text.

Footnotes in book => side notes on web
Endnotes in book => footnotes on web

So that’s what I’m aiming at with this first take. The notes are to the right of the main text, and the reader can scan both of them at the same time. This is the proper user experience.

There’s one practical technical advantage to using side notes as well: you don’t need backlinks.

If you use footnotes on the web (i.e. what would be endnotes in a book) each saparate note must refer back to the note market in the main text, like Wikipedia does. If we use side notes such links are not necessary, since the user will be able to see both texts at the same time.

HTML

With our purpose clear in our minds, let’s start coding.

Here is an example of HTML with notes from the example. This is how I, as an author, would like to write the main text plus notes. (You can see this code example as XML instead of HTML if it helps you; it is not quite the code the browser works with.)

<p>Thus king Hertnit gathered a great army. And his wife Ostacia went out
and moved her hand<note><span lang="non">hrærði sinn gand</span>; Google 
Translate gives "stirred her hand". Von der Hagen says "<span lang="de">
rief ihre Götter an</span>", which is unhelpful.</note>, which is 
what[...]</p>

Then a script (JavaScript in the example page, but PHP in the main application) adds two spans and a tabindex to each note:

<p>Thus king Hertnit gathered a great army. And his wife Ostacia went out 
and moved her hand<span class="note ref" tabindex="0"></span><note>
<span class="note"></span> <span lang="non">hrærði sinn gand</span>; Google 
Translate gives "stirred her hand". Von der Hagen says "<span lang="de">rief 
ihre Götter an</span>", which is unhelpful.</note>, which is what[...]</p>

Once the main note has been lifted out of the text flow the first span remains in place as the container for the note marker, which is a simple CSS counter.

span.note:before {
	content: counter(notes);
}

The tabindex is for keyboard accessibility: users can ow tab through notes. In itself this is worthless without a highlight functionality, which we’ll get back to later.

A few more remarks about this HTML structure:

  1. The note text comes directly after the text it refers to. As an author I find this the easiest way to write notes. A possible downside would be that screen readers read the note text as part of the main text. Right now I assume they do; the question is whether we can solve that problem. If we can, I feel that this is the best way of authoring notes. If we can’t we have to revise this somewhere; for instance by moving the notes to their own paragraph or something.
  2. I currently use a <note> tag even in the rendered HTML. This is wholly my own invention, non-standard, and non-validating, and will eventually be replaced by whichever HTML element turns out to be the correct one. (But which one is correct turns out to be a fairly tricky question.) So for now I’ll stick with <note>.
    There’s no problem for CSS and JavaScript: they always work on all elements, whether they’re officially HTML or not, so I can style and script the <note>.

Moving the notes to the side

Now it’s time to create a visual side note. The <note> element itself is taken out of the main flow and positioned to its right. There’s a slight trick here not everyone may know: We give the note an absolute position, but do not set the top, which effectively means top: auto. Now the note will stay at the original top it had as a static element, and thus on the same line as its marker in the main text. This has always worked in all browsers. (Of course left: auto works the same, but horizontally.)

note {
	position: absolute;
	left: calc(100% + 1em);
	/* implied top: auto */
	width: 15em;
	padding: 1px calc(1em + 1px);
}

There is one huge drawback to this technique: if there are two notes on the same line they end up in the same position on the side, and the last one is on top of all earlier ones — the effect occurs in the example page.

What to do? First, we need to highlight individual notes when the user interacts with them (see below). But even if that works brilliantly, it would be useful to give a visual hint that a note is hidden under another one.

For a brief moment I hoped the CSS counters I already use could be used to do this, but no such luck. I hoped for something like this:

note {
	margin-top: calc(--var(counter(notes)) * 1 )em; /* nah */
}

Take the counter, re-interpret it as an em value, and set the margin-top to that value — but that doesn’t work yet. It turns out that using counters in variables is being discussed but not yet operational. If anyone needs another use case, this is one.

For now I’ll do nothing, but I’ll have to revisit this question in the future.

Highlighting

Now we need a highlighting function. If the user mouses over (or tabs to) a note marker it is helpful if the note itself is highlighted. We could do this with pure CSS:

span.ref:hover + note,span.ref:focus + note {
	/* highlight styles */
}

The problem is that I also want a reverse highlight. If the user mouses over notes, I want to highlight the note marker in the main text. This is not possible by CSS alone, we must use JavaScript.

For now I decided to implement both highlights in JavaScript because I do not like mixing two layers for the same effect.

document.addEventListener('mouseenter',addHighlight,true);
document.addEventListener('mouseleave',removeHighlight,true);
document.addEventListener('focus',addHighlight,true);
document.addEventListener('blur',removeHighlight,true);
/* and make sure they're executed only on notes and note markers */

(Remember, in the bubbling phase, with false as the last argument, focus and blur events never end up at the document level. But in the capturing phase, with true as last argument, they do. So that’s what we use.)

The mouseenter/mouseleave pair also gives us a first approximation of a touchscreen solution. When the user touches a note marker or note, eventually the mouseenter event is fired and does its thing. When the user touches something else the mouseleave event fires. This is not yet a perfect touchscreen solution, since the dreaded 300 millisecond delay is operational, but for this primitive version it’s good enough.

So far I like the highlight effect a lot; it’s that bit of usability that makes the notes easier to use. The only question is if I should still split off the marker-to-note highlighting and inplement it in CSS after all. Right now I’m not sure.

Questions

So this is where we stand, and here are the questions we should solve:

  1. Is the current version the best way to visually render side notes? Or is the overlap effect a show-stopper?
  2. What HTML element are we going to use for the note text? I’ll eventually have to replace <note>, but with what?
  3. What accessibility problems do we encounter when the source code leaves the note texts embedded in the main text? Are these problems solvable by, for instance, an ARIA attribute? (I don’t know ARIA well enough to answer that last question.)
  4. Should we implement the marker-to-note highlighting in CSS, even though note-to-marker must remain JavaScript? The benefit would be that the highlighting even sort-of works without JavaScript, the drawback is more complicated code.
  5. Do we need a radically different highlighting user experience for touchscreen, or is the current version kind-of good enough? (I’d like to get rid of the delay in any case.)

For now I’ll await feedback and continue summarising the saga, which gives me a larger corpus of notes to play with. Once enough feedback has come in I’ll create take 2.

This is the blog of Peter-Paul Koch, web developer, consultant, and trainer. You can also follow him on Twitter or Mastodon.
Atom RSS

If you like this blog, why not donate a little bit of money to help me pay my bills?

Categories: