When reading paper books, it makes sense for footnotes to be at the bottom of the page. Footnotes are parenthetical asides, after all, so they should live outside the main flow of the text; furthermore, it’s not onerous for the reader to look down at the bottom of the page, read the footnote, and then follow the superscripted number back up to where they were previously.

When reading online articles, however, following tradition and putting footnotes at the foot of the page is generally annoying. Go ahead and click on this footnote. That was a terrible experience, right? Let’s figure out a way to keep that from ever happening again.

While there are many potential solutions to the “footnotes at the foot of an online article are annoying” problem, let’s simply have the footnote text pop up when desktop users hover over (or mobile users click on) a footnote like this.

Since interactive text boxes are a common piece of web functionality, let’s avoid reinventing the wheel and use Bootstrap, an open-source HTML, CSS, and JS framework that makes it easy to add buttons, navigation bars, carousels, and other common features to websites.

Our recipe for interactive footnotes:

  1. Counting the Footnotes: Use a CSS Counter to insert the correct number into each footnote
  2. Incorporating Bootstrap: Insert CSS and JS to display text boxes on hover
  3. Allowing HTML in Footnotes: Adjust JS to allow markup inside footnotes
  4. Keeping Footnotes Visible: Prevent the text box from fading away when users hover over it

Counting the Footnotes

No writer wants to have to manually number their footnotes. Fortunately, CSS counters can go through our document and insert the numbers for us. Here’s the CSS for doing that, assuming the footnotes are all inside the body tag and each footnote in contained in a span element with a class of footnote:

body {
    counter-reset: footnotecounter;

span.footnote:before {
  counter-increment: footnotecounter;
  content: counter(footnotecounter);
  position: relative;
  top: -0.4em;

span.footnote {
    color: #24B1E6;

Breaking this down:

  • The counter-reset property creates a CSS counter called footnotecounter within the body tags of the HTML document, initializing the value of the counter to 0.
  • counter-increment: footnotecounter adds one to the value of the counter each time a span element with the class of footnote is encountered.
  • content: counter(footnotecounter) inserts the current value of footnotecounter (i.e., the correct footnote number) before any other contents in the span element. (We won’t otherwise put content inside the span element.)
  • The other properties set here are chosen to make the footnotes appear superscripted and match the color of links on this site, cueing users to try to click/hover on them.

Here’s what a footnote span element looks like:

<span class='footnote'></span>

Note how there’s no content inside the span tags, as we’re generating the content with the :before CSS selector. Given the CSS above, these span elements will generate sequentially numbered footnotes like this: .

To actually display our desired text when users hover over the footnote, though, we’ll need to incorporate Bootstrap.

Incorporating Bootstrap

Bootstrap has two main methods for interactively adding text to pages: Tooltips and Popovers. Popovers are essentially beefier versions of tooltips that allow for titles in the text box that pops up. Since footnotes don’t require that much styling, we’re going to go with tooltips here, but most of the configuration details below apply to popovers as well.

The easiest way to get Bootstrap on your site is to include the entire minified CSS and JS files from Bootstrap; you could select out the .tooltip class CSS from the CSS file and use tooltip.js if you only want to load the CSS and JS that your site is using.

Once the Bootstrap CSS and JS is on the page, we’ll need to adjust our span elements to include a data-toggle attribute that will allow the Bootstrap JS to target them as well as a title attribute with the text we want to include in our footnote (in this example, some “artisinal filler” generated by Hipster Ipsum):

<span class='footnote' data-toggle="tooltip" title="Affogato bushwick irony tacos, kitsch etsy tousled distillery intelligentsia tattooed photo booth trust fund synth letterpress hashtag 8-bit."></span>

To make this text display on hover, we’ll simply need to run the following JS after the Bootstrap JS script has run:

jQuery(document).ready(function() {

And, voilà: we have a working footnote!

Allowing HTML in Footnotes

Looking pretty good! But to take our footnote chockablock with hipster buzzwords to the next level, let’s make “intelligentsia” link to Intelligentsia Coffee in case our readers need a caffeine buzz after eating all of those irony tacos.

Adding a link to the title text (making sure to use single quotes for the href attribute since the title attribute is in double quotes) seems like a workable approach:

<span class='footnote' data-toggle="tooltip" title="Affogato bushwick irony tacos, kitsch etsy tousled distillery <a href='http://www.intelligentsiacoffee.com/'>intelligentsia</a> tattooed photo booth trust fund synth letterpress hashtag 8-bit."></span>

However, that generates this scorn-worthy footnote: .

It turns out that Bootstrap won’t parse any HTML in the title attribute unless we explicitly tell it to do so by changing our JavaScript to include the key-value pair html:true.

jQuery(document).ready(function() {

Now our readers can easily impulse purchase some fair trade coffee!

Keeping Footnotes Visible

Or can they? As you likely noticed, the footnote is only visible when the number is being hovered-over; if you move your mouse over to where the footnote text is–a critical part of clicking on a link in a footnote–the footnote vanishes. Go ahead and try to click on the link: you can’t move quickly enough! (Unless you’re on a mobile device, in which case, congratulations! You can already click your way to Intelligentsia’s website.)

As usual, StackOverflow comes to the rescue: the container option of tooltips can save the day. The official tooltip documentation notes that container “is particularly useful in that it allows you to position the tooltip in the flow of the document near the triggering element – which will prevent the tooltip from floating away from the triggering element during a window resize.” What they don’t add is that it also prevents the tooltip from floating away when you mouseover the tooltip.

Before you continue reading, it’s imperative that you were sufficiently annoyed by the traditional bottom-of-the-page footnote; otherwise, you won’t truly understand why we’re creating hover-over footnotes with Bootstrap.

Were you adequately annoyed?

Who’s chuckling now? Are you sufficiently annoyed yet and ready to rejoin the article?

Here’s the JavaScript to set the container option and make one tweak to the delay option that we’ll discuss below:

jQuery(document).ready(function() {
    jQuery('[data-toggle="tooltip"]').each(function() {
        var $elem = jQuery(this);
            container: $elem,
            delay: {hide:400}

Rather than calling the .tooltip() method once, we use the .each() method to loop over each of the span elements with data-toggle="tooltip", store the element with jQuery(this) (or, if you’re using the common jQuery alias $, $(this)), and then call .tooltip(), passing it a JavaScript object with three key-value pairs:

  • html:true, which works as above.
  • container: $elem, which sets the container to be the span element that contains the footnote, which will prevent a mouseout event from being logged when the user moves from the footnote number to the footnote text.
  • delay: {hide:400}, which prevents the text box from hiding for 400 milliseconds after a mouseout. This prevents the tooltip from vanishing if the user moves their mouse from the footnote number to the tooltip via a path that’s outside either element, momentarily mousing out.

That’s it! You can now add footnotes to articles without disrupting the flow of your readers.

Stray Observations

  • Rather than setting tooltip options with JavaScript as we did here, you could alternatively use HTML attributes by prefixing data- to the option name, e.g., data-html="true".
  • On WordPress, including links inside my title attribute didn’t initially work because WordPress kept converting one double quote into a “smart quote” that was adorably curvy but completely powerless to close an HTML attribute. If you run into this problem, simply add the following to your functions.php file, which will prevent nice text enhancements (e.g., smart quotes, em dashes (—)) within span tags (where these footnotes are) only:
add_filter( 'no_texturize_tags', 'my_no_texturize_tags' );
function my_no_texturize_tags( $tags ) {

    $tags[] = 'span';
    return $tags;
  • I’m aware that “hover-over footnote” sounds like an oxymoron–footnotes should be at the foot of the page, right? But I just can’t bring myself to use the generic-sounding, if technically accurate, “hover-over note.”
  • Header image of a tree near Ludlow, CA, c/o Juliet Verni.

  1. Mwahaha! You’re all the way down here now. What’s that? You want to go back up to where you were and continue reading? Okay, fine. Here’s a link to help you out: up, up, and away!