Logic and
Load the menuLoad the menu

Copyright   James R Meyer    2012 - 2024 https://www.jamesrmeyer.com

Easy Footnotes for Web Pages (Accessibility friendly)

Major update 31 Mar 2024


Minor update 21 Apr 2024


This page shows you how to make footnotes for web pages for your website that are very simple to insert and really easy to maintain. If you need to edit, add or delete a footnote, or move the position of its reference in the text, it is easy with this system.


Maybe you would like to include footnotes in your web-pages, but find that the hassle involved in ensuring that the numbering is always correct is more bother than it is worth. If so, then this page is for you - it shows you how to easily add footnotes to your web-pages without having to worry about the numbering at all.


You need to have some basic knowledge of HTML. The JavaScript file can be used as it is. The CSS file can be used as it is, or you can make your own modifications to it if you wish. There are some excellent tutorials online, (Footnote: For example W3 Schools have a beginner’s HTML tutorial, a beginner’s CSS tutorial and a beginner’s JavaScript tutorial. ) and if you have problems incorporating this footnote system, I will try to help you sort them out.


The problem with footnotes in general arises from the fact that they are numbered sequentially. This means that if you make a change such as adding or deleting a footnote you have to re-number all subsequent footnote references and the footnotes also.


And, furthermore, in a web-page, if you have clickable links from the footnote reference numbers (Footnote: Like this ! This is simply a long footnote which has been put here to demonstrate this footnote system. Please understand that many of the footnotes have been inserted on this page principally for demonstration purposes !) in the text to the actual footnote, you then have three numbers in the reference (a numbered id for returning to the reference from the footnote, a link href to the numbered id of the footnote and the number that is visible to the reader), and similarly there are also three such numbers for the footnote itself. Traditionally, all these numbers are written in manually as part of the HTML of the web-page. This means that adding, deleting, or moving a footnote can involve numerous changes to subsequent references and footnotes, and besides that being a major pain, mistakes can easily be made.


I searched on the web for a ready-made solution but didn’t find anything suitable. I found details of how to do footnotes by the laborious method described above, such as Footnotes, endnotes, and sidenotes on Web pages, Web Experience Toolkit, Accessible Footnotes with CSS, How to Create Footnotes in HTML, Handling footnotes and references in HTML and JavaScript enhanced footnotes and references. Some of them gave me ideas, but none gave me what I wanted.


For this reason I decided to implement a very simple method (Footnote: As a single person I don’t have the resources such as big operators like Wikipedia might have.) whereby each footnote is simply written into the HTML code at the place where you want the reference number to appear. The footnote is enclosed by a span with a class name that identifies that span as a footnote. JavaScript then does all the tedious work for you. (Footnote: Only plain JavaScript is used and no additional library is required.) When the page loads, JavaScript goes through all the footnote spans, inserts a reference to each footnote, then hides the footnote span, and inserts the text (Footnote: The footnotes are not restricted to just plain text, for example hyper-links can be included, e.g. my home page.) of the footnote in a div that has an id that identifies it as the correct div for the footnotes. The script enables the footnotes to appear as tooltips when a footnote reference number is clicked, as well as appearing in the desired location such as the foot of the page. The footnotes and their references are all automatically assigned the correct consecutive numbers. Hence there is no need to assign any number at all to the footnotes when writing the web-page. Readers who are familiar with Latex will recognize this as the same method that Latex uses for footnotes.


Note that this footnote system allows for multiple groups of footnotes for different sections of a web-page; this is detailed below. This page is itself divided into two sections and uses three different footnote groups. Note that the footnote references and footnotes can be styled differently for different groups, as seen in the Side Box here. Of course, for demonstration purposes, there is an overuse of footnotes on this page - such overuse should be avoided.



The system is set up so as to try to make it nicely accessible for screen readers. Unfortunately, there is no specific ARIA accessibility protocol as such for footnotes for HTML documents, but each footnote has the ARIA role set to “note”. (Footnote: There is a protocol for footnotes in ePub documents, see Digital Publishing Roles and Accessible Publishing Knowledge Base - Notes; ePubs essentially consist of a collection of HTML files, so perhaps this will sometime be extended to HTML files in general.) There is an ARIA role of “contentinfo” which one might imagine would be appropriate for the footnote sections, but the problem is that the ARIA specification is that this can only be used once within a web-page, which rules its use out for this system, since there may be multiple footnote sections.


The system used here uses other methods to facilitate users with screen readers, as follows. The footnote references in the text have the hidden text "Footnote" preceding the footnote number in the link to the footnote, and the footnotes also have the hidden text "Footnote" preceding the text of the footnote. The hidden text is not visible on screen, but will be read by a screen reader. In the Footnotes sections where the footnotes are collectively displayed, there is a hidden link to skip past the section, and each footnote number which is a link to the text position to which the footnote applies have the hidden text "Footnote location" preceding the number.


Update: In the previous implementation, a reader had pointed out that pressing the Enter key on the keyboard did not work to show the footnote text, as it did for a mouse click. I had previously not implemented this as it means that the footnote references have to be plowed through to get to the other links on the page, which are the links of principal interest to the reader, and the footnotes are viewable anyway. However, this makes the footnotes technically not keyboard accessible, and not as keyboard users might expect, since the behavior of the links is different for a keyboard user. So I have now changed the JavaScript code, and the footnote reference links now operate as for a mouse click, so that when a footnote reference link is the focused link, and the Enter key is pressed, the appropriate footnote will appear immediately below the footnote reference link, and will disappear again if the Enter key is pressed again.


Summary of advantages of the Easy Footnote system

  1. Easy to insert, add, move or delete footnotes, or the references thereto.
  2. Very little JavaScript and CSS required for essential functionality.
  3. Appearance easily modified with CSS.
  4. Hyperlinks can be included in the footnotes. (Footnote: For example, this footnote includes a hyper-link to My Home Page. )
  5. Tooltips can be included in the footnotes. (Footnote: For example, this footnote includes a tooltip for function. )
  6. Multiple groups of footnotes can be used, with sections for each group where all the footnotes for that group are displayed. (Footnote: In this setup, the footnotes are all numbered consecutively. If it is desired that each group of footnotes starts at “1” then the JavaScript code could be modified for this purpose. My thoughts are that different footnotes with the same number, albeit in different sections, could be confusing.)
  7. The footnotes and the references are accessible and give the correct content and semantics to a screen reader. Each footnote is tagged with the ARIA role “note” and each footnote and each link to a footnote are prefaced with a hidden term “Footnote” which is not visible on screen.
  8. Even if JavaScript and/or CSS is disabled, the correct footnote content is nevertheless present and is semantically correct.

The system has been tested and found to work in modern browsers; no attempt is made to make it work in the obsolete Internet Explorer. A quirk of some non-current browsers is that when the footnote tooltip is closed (by clicking on the x), the browser creates a line break after the footnote reference. This does not affect the readability of the material.


Details of the Code

Very little code is required to provide the essential functionality of the system, as described below. Note that double-clicking inside a code box will select the code for copying. You can see a demo of the essential files at Basic Footnotes Demo Page.


Note to anyone who has used a previous version: the current code may not be compatible with the previous version. If you have any problems updating your footnotes to the current version, please contact me.


You can download copies of the demo files here:


The HTML code

The HTML code for the footnotes consists of a tiny bit of code that encloses the footnote content. It is identical for all footnotes which means that it can be saved as a code snippet for repeated use:

Generally you will not want a space between the text and the footnote reference number. To achieve this, there should be no space between the text and the <span class="footnote"> that is the start of the footnote wrapper. (Footnote: Previously I used initial zero-space non-breaking character &#8288; before the footnote wrapper to prevent unwanted line-breaks, this is now achieved more easily by the CSS, see the CSS notes below.)


When I have two consecutive footnote references, I like to put a space between them to make it easier for the user to select the right one. Since normally I do not want a line break between any two, I use the non-breaking space &nbsp; between the end of one footnote span and the start of the next. (Footnote: Like this footnote referenced by the first of two immediately consecutive footnote reference numbers.)  (Footnote: And this footnote as the second of two immediately consecutive footnote reference numbers.)


And for the location of the actual footnotes, the HTML code is a single line which can be saved as a code snippet:


Note that there can be several different footnote groups in different locations on the web-page. To enable this, simply add a unique suffix to the class name "footnote" of each relevant footnote span and add the same suffix to the id "Footnotes" of the Footnotes <article> where the footnotes are to be located.


For example, on this page, for the first group of footnotes in the main text, I used the basic class "footnote" for the footnote span and the basic id "Footnotes" for the Footnotes <article>; for the coding section I used the class "footnoteCode" for the footnote span and the id "FootnotesCode" for the Footnotes <article>; for the Side Box group of footnotes I used the class "footnoteSide" for the footnote span and the id "FootnotesSide" for the Footnotes <article>; and for the formatting section I used the class "footnoteFormat" for the footnote span and the id "FootnotesFormat" for the Footnotes <article>. Note that this means that in the code snippets shown above the suffixes will need to be added manually. (Footnote: Alternatively, if the same method is being used often, additional code snippets could be made.)


Optimizing for Browser Reader mode

With the original code, I found that the Reader mode on various browsers produced rather messy results with the footnotes. One problem was that the footnotes appeared in line with the text, without any line break between the surrounding text and the footnote, making for confusion for a user; the other problem was that the footnotes did not appear at all at the end of the preceding text.


I found that the best solution for this was to use the HTML attribute hidden on the span that contains the text of the footnote, like this: <span hidden class="tipContent" role="note">. In normal viewing of the web-page, the CSS display property always overrides this HTML attribute, while in the Reader modes I tested the text for the footnote is usually prevented from showing at the reference point for the footnote. The Footnotes section tag is now <article> rather than <div>, and this usually enables the footnotes to appear as expected at the end of the relevant text in Reader mode. I say ‘usually’ in the above because the browser Reader modes can be rather inconsistent in their application.


The CSS code

Very little CSS is required for the basic functionality. For users not wanting to write any CSS code, the downloadable CSS file can be used as it is by adding this line inside the <head> of your HTML file: (Footnote: You can rename the CSS file if you wish; if you do so, you must also change the name in the reference.)

<link rel="stylesheet" media="all" href="YOUR PATH/footnotes-demo-pretty.css">

where YOUR PATH is the path to the CSS file; if the file is in the same folder as the HTML file, you can leave it blank, otherwise you need set the path correctly, for basic guidance see W3 Schools: HTML File Paths or Code Academy: File Paths.


For those wanting an overview of how the CSS operates, the CSS for basic functionality is:

And for basic functionality for printing the following additional code is required:



  1. The footnote “display:block” property is used to ensure that the footnotes appear in an acceptable format in the text if JavaScript is not enabled.
  2. The purpose of the invis class is to hide the text visually, but it will be read by a screen reader; this means that the content and the semantics will be correct for a screen reader. So elements with the fnHide class will not be visible, nor seen by a screen reader (unless JavaScript is disabled).
  3. The purpose of the hasJS spans is to prevent the footnotes showing briefly and causing a flicker if JavaScript is enabled; see the notes on the JavaScript code.
  4. The \200B in the pseudo before element of fnNum is a zero-width prevent-break character which prevents any unwanted line-break between the text and the footnote reference number. It can happen that the reference number can sometimes get pushed by a line break onto the next line by itself, which spoils the look somewhat. It seems to happen after symbols such as a colon, semi-colon, question mark, etc. The zero-width prevent-break character seems to prevent this happening, and so I now use this method for all footnotes. Of course, if for some reason you want a line break before the footnote reference number just close the paragraph before the reference number, or insert a <br> before it.

An example of additional CSS for pretty formatting of the footnotes and the footnote reference numbers is:


The JavaScript Code

The JavaScript code can be used as it is, no modification is required, you need to add the following line at the end of your HTML file, just before the body closing </body> tag. (Footnote: You can rename the JavaScript file if you wish; if you do so, you must also change the name in the reference.)

<script src="YOUR PATH/footnotes-demo.js"></script>

where YOUR PATH is the path to the file; if the file is in the same folder as the HTML file, you can leave it blank, otherwise you need set the path correctly, for basic guidance see W3 Schools: HTML File Paths or Code Academy: File Paths.


To prevent page flicker on load, you also should put the following line inside the <head> of your HTML file:

<script>document.documentElement.className = 'hasJS';</script>


If JavaScript is not enabled by anyone reading the page, there will be no footnotes at the foot of the page. However, they will appear within the text, and they are marked as being footnotes, so the content and the meaning is still present. Each footnote will appear in the text, but separated from the main text by line breaks, viz:


Lorem ipsum dolor sit amet, consectetur … preceding text here
the following text here … lorem ipsum dolor sit amet …



For those wanting an overview of how the JavaScript operates, the code consists of two functions:

  1. a function which initially sets up the footnotes and the footnote references once the DOM is loaded, and
  2. a function which is called by the user and which either shows the footnotes as tooltips or hides the tooltip.

Note that the resultant entire footnote reference number together with its two square end brackets is a clickable link, which makes it easier to select than the number on its own.


The script is plain JavaScript. The code below includes a document ready function which calls the SetupTips function once the page is loaded; if your JavaScript code already has a document ready function, then you do not need the one included here, and you can simply call the SetupTips() function from your document ready function.


If JavaScript is enabled, unless steps are taken to prevent it, the page loads the footnotes as visible within the text, and after that the JavaScript hides the footnotes that are within the text, which means that on slow systems, the page may flicker briefly with the footnotes visible within the text before the JavaScript hides them. To prevent this I use a line of JavaScript which must be within the head and which adds the class "hasJS" to the <html> tag:

The CSS defines that the tags with the appropriate classes (Footnote: Classes beginning with “footnote”, and the class “fnWrapper”.) will not display provided the <html> tag has the class "hasJS", hence these tags will not display as the page loads.


Note: The JavaScript code shown below may not copy properly, it is advised that instead you download the essential files by the download links given above (Download links).

// ############## start of document ready function ###################
// This function is to run the JavaScript code once the page is loaded.
// If you already have such a function just call the SetupTips function
// from your document ready function.

// Revised Aug 2023

document.addEventListener("DOMContentLoaded", function () {



// ############## End of document ready function ####################

// ###### Tooltips function which includes setup of footnotes #######

function SetupTips() {

	var fnNumber = 0;
	var myid = '';
	var clsStart, clsEnd;
	var myClassList, myClass;
	var baseHide, baseFn;
	var myFn, i = 0, j = 0, len, clL;
	var fnContent;
	try {

		var fnotes = document.querySelectorAll('span[class^=footnote]');
		// The footnotes = all spans which include a class name that begins with "footnote"

		for (i = 0, len = fnotes.length; i < len; i++) {
			myFn = fnotes[i];
			myClassList = myFn.classList;
			for (j = 0, clL = myClassList.length; j < clL; j++) {
				myClass = myClassList[j];

					if (clsEnd !== myClass.substr(8)) { // Then we have a new footnotes section
						clsEnd = myClass.substr(8); // This identifies the section
						// Add a hidden link to skip the section
						document.getElementById('Footnotes' + clsEnd).insertAdjacentHTML('beforebegin', '<a href="#Footnotes' + clsEnd + '-End"><span class="invis">Skip footnote section</span></a>');
						// Add the hidden div to where that link goes to
						document.getElementById('Footnotes' + clsEnd).insertAdjacentHTML('afterend', '<article class="invis" id="Footnotes' + clsEnd + '-End"></article>');

				// Now do the footnotes
				clsStart = myClass.substr(0, 8);
				if (clsStart === 'footnote') { // We have a footnote
					fnNumber = i + 1; // Array starts with 0; we want notes to start with 1
					myid = 'Fn_' + fnNumber + '_' + clsEnd; // Unique footnote reference

					myFn.id = myid; // Set the id of the footnote
					myFn.classList.add('hideTip'); // Hide the footnote in the text
					myFn.classList.add('fnWrapper'); // Add class for wrapping the tooltip
					myFn.setAttribute('role', 'presentation'); // Add ARIA attribute for accessibility
					fnContent = myFn.innerHTML; // Copy all footnote content that is inside the footnote tag
					// Add the footnote reference to the text
					// Note that the %20 in the href inserts spaces so the link appears nicely in browser status bar as "# Show Footnote 1", though there is no actual link.
					myFn.insertAdjacentHTML('beforebegin', '<a class="fnNum" href="#%20Show%20Footnote%20' + fnNumber + ' " title="Show/Hide footnote ' + fnNumber + ' " id="' + myid + 'a" onclick="showHide("' + myid + '");return false;">[<span class="invis">Footnote </span><span class="fnNumIn">' + fnNumber + '</span>]</a>');
					// Surround the footnote content with an inner div that will display as table-cell
					myFn.innerHTML = '<span hidden class="tipContent" role="note">' + fnContent + '</span>';
					// Insert footnote number and the footnote where the footnotes are required to appear

					document.getElementById('Footnotes' + clsEnd).innerHTML += '<p><a class="fnNumBase" href="#' + myid + 'a" title="Footnote location">[<span class="invis">Location of footnote </span><span class="fnNumIn">' + fnNumber + '</span>]</a> <span role="note" id="' + myid + 'Base" class="fnTextBase">' + fnContent + '</span></p>';

					myFn.classList.remove(myClass); // Remove extraneous stuff from the footnote tooltip
					// Uncomment this next line if you want the footnote number to show in the pop-up, I prefer it not to show (but it shows in the end footnotes)
					// myFn.getElementsByClassName('fnHide')[0].insertAdjacentHTML('afterend', `${fnNumber}: `);

					// Remove the "hidden" (Footnote: and ) opening and closing tags of the footnotes in the collective section
					baseFn = document.getElementById(myid + 'Base');
					baseHide = baseFn.getElementsByClassName('fnHide');
					while (baseHide[0]) {

		// Make the appropriate parts of the footnotes invisible except to screen readers
		var fnHides = document.getElementsByClassName('fnHide');
		[].forEach.call(fnHides, function (el) {

	} // End of try
	catch (e) {
		// Catch and just suppress error
		// alert("fn: " + e);
// ################# End of Tooltips function ######################

// ############## Function to set up showing or hiding of text #######
function showHide(divID) {
	var myDiv = document.getElementById(divID);
	try {
		if (myDiv.classList.contains('hideTip')) {
				if (divID.substr(0, 3) === 'Fn_') {
					// For if tip is a footnote replace number with an x
					document.getElementById(divID + 'a').innerHTML = '[<span class="fnNumIn">✖</span>]';
		} else {

				if (divID.substr(0, 3) === 'Fn_') {
					// For if tip is a footnote, restore the reference number
					document.getElementById(divID + 'a').innerHTML = '[<span class="invis">Footnote </span><span class="fnNumIn">' + divID.substr(3).split('_')[0] + '</span>]';
	catch (e) {
		// alert(e);
// ######## End of function to set up showing or hiding of text #######



Formatting your footnotes

Note that since the footnote content is within a span element, in theory only in-line elements should be used within the footnote content (in HTML5 such elements are now referred to as phrasing content elements), but in practice you can use block elements and it is still valid HTML. This footnote gives examples of how to format a footnote with indentations and differing line spacings. (Footnote: For a line break in a footnote, use <br>. If you want to include indented sections within a footnote, you can do so by using a span with display:inline-block and padding-left, e.g:
<span style="display:inline-block;padding-left:2em;"> viz:
Like this short line of text.
And this longer section of text. Though having said that in theory only in-line elements should be used within the footnote content, in practice, if you include elements inside in-line tags that have CSS that specifies them as display:block, it doesn’t produce invalid HTML, and it seems to display correctly in all browsers.

And you can follow those indented lines by non-indented text like this.
If you want a different spacing between two lines, you can use a span with, for example: style="margin-bottom:1em;display:inline-block", setting the top or bottom margins as you wish to give a different space between this line and
this one (Previously I suggested inserting blank lines using a display:block span enclosing only &nbsp; and specifying the desired line-height, I no longer recommend this method).)


If you are using your footnotes to cite sources for reference, then you should keep to a set style. There are common standard styles such as in MLA or Chicago style. You can find useful information on some standard styles here:

How to reference a Website using the Chicago Manual of Style

Chicago/Turabian Basics: Footnotes

How to cite a Website in Harvard style

and information on citing web sources:

How Do I Cite Electronic Sources?


Tips on formatting the reference numbers

A reader asked for help in setting up the appearance of the footnote reference numbers, and I thought the following might be useful for others.


Your web-page normally has a default overall initial font size on the <body> tag. The footnote reference number wrapper <a class="fnNum">…</a>, has its font-size set as a default to be less than the text around it. I set the attribute font-size: 80%; in the class fnNum to get the size I want. If you want to change this set the % to what you want.


Also, you might want to change the line-height of the overall text to prevent the footnote reference numbers pushing up the line above, which takes away from the appearance of the paragraph. I think that it is better to increase the line-height of the text all around the footnote reference numbers so that line spacing throughout the entire paragraph is the same. You can do this by setting the line height of your paragraph/section/body etc as line-height: x where x is a number where 1 gives the same line height as it would otherwise have been. I set the line-height to 1.0 in my class fnNum and I use a line-height: 1.45 on my body tag which gives the default line spacing throughout the text, so that it is 36% taller than it would be otherwise.


The vertical position of the footnote reference number is set to be higher than the surrounding text by setting the top attribute of the class fnNum , and you can change this if required, e.g: top: -3px. Note that the top attribute requires position: relative.



Finally, I must thank Alex Gorbatchev for his SyntaxHighlighter system for displaying HTML, CSS, and JS code.


Note: Since writing the above my attention was drawn to a web-page entitled “Footnotes with JavaScript & CSS”, which was written as long ago as 2006 on a site brandspankingnew.net that is now no longer online. It used essentially the same method as my own, although it did not use the more advanced capabilities of modern browsers. It did not implement the footnotes as in-line pop-ups, and it required an extra script line at the end of the page for each section that requires separate footnotes.


If you have any comments, suggestions, or questions about the Easy Footnotes system, or require help in implementing the system, please feel free to contact me.


Previous issues

Quirk in Chrome on Android, noticed in Oct 2020, now appears fixed, so no longer an issue.

Previous text:

Noticed a strange quirk where the first footnote in the Footnotes section sometimes displays at an incorrect font size, that is, not the defined font-size. My footnotes are defined to be a slightly smaller size than the main text - I have checked my code, and have checked that the Chrome web developer confirms the definition, but nevertheless calculates a font-size that is different to the actual calculation. I have found that this seems to happen when a link occurs after the first word of the footnote, and inserting a white space (either a space or new line) between the Footnote: </span> and the content of the footnote, along with a non-breaking space after the first word appears to cancel out this quirky behavior (This white space does not display at the beginning of the footnote).

Interested in supporting this site?

You can help by sharing the site with others. You can also donate at Go Get Funding: Logic and Language where there are full details.



As site owner I reserve the right to keep my comments sections as I deem appropriate. I do not use that right to unfairly censor valid criticism. My reasons for deleting or editing comments do not include deleting a comment because it disagrees with what is on my website. Reasons for exclusion include:
Frivolous, irrelevant comments.
Comments devoid of logical basis.
Derogatory comments.
Long-winded comments.
Comments with excessive number of different points.
Questions about matters that do not relate to the page they post on. Such posts are not comments.
Comments with a substantial amount of mathematical terms not properly formatted will not be published unless a file (such as doc, tex, pdf) is simultaneously emailed to me, and where the mathematical terms are correctly formatted.

Reasons for deleting comments of certain users:
Bulk posting of comments in a short space of time, often on several different pages, and which are not simply part of an ongoing discussion. Multiple anonymous user names for one person.
Users, who, when shown their point is wrong, immediately claim that they just wrote it incorrectly and rewrite it again - still erroneously, or else attack something else on my site - erroneously. After the first few instances, further posts are deleted.
Users who make persistent erroneous attacks in a scatter-gun attempt to try to find some error in what I write on this site. After the first few instances, further posts are deleted.

Difficulties in understanding the site content are usually best addressed by contacting me by e-mail.


Based on HashOver Comment System by Jacob Barkdull

Copyright   James R Meyer   2012 - 2024