Logic and Language
Load the menuLoad the menu

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

Note: Full functionality of this website requires JavaScript to be enabled in your browser.

Easy Footnotes for Web Pages (Accessibility friendly)

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 (Note: You need to have some knowledge of HTML, CSS and JavaScript).

Side Box

Footnotes (Footnote: A footnote is a note that is inserted at the end of a page, after the main material. For more information, see http://www.​plagiarism.org/​citing-sources/​what-are-footnotes. ) can be a very useful adjunct to written material, allowing a reader to skip past details, but at the same time allowing the reader to view those details (Footnote: The details are such as to be not of sufficient interest to most readers that it should be an integral part of the text. ) if they wish. Traditionally, footnotes are indicated by a number enclosed in square brackets, (Footnote: We refer in this page to these as “footnote references”. ) with the actual footnotes appearing at the bottom of the page. The references to the footnotes are numbered in the order in which they appear in a page, and the footnotes themselves at the bottom of the page also follow the same order.

section divider



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.


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, Creating footnotes - HTML anchors, 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: The JavaScript now does not utilize jQuery, although a polyfill is required for IE9, see below. ) 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.


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, no jQuery required.
  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. (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.
  8. Even if JavaScript and/or CSS is disabled, the correct footnote content is nevertheless present and is semantically correct (but see note below re IE8 and lower).

The system has been tested and found to work in modern browsers, IE9 and above. 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.


No attempt has been made to make the system work in the obsolete IE8 and below. However, if you require that the footnotes must appear on the page in IE8, then see the notes below regarding the JavaScript code.

section divider


section divider

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. You can also download a zipped copy of the essential files at footnotes-demo.zip.


The HTML code

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

Note that generally you will not want a space between the character immediately before the footnote reference - for this, there should be no space between the footnote reference number and the <span class=“footnote”> that is the start of the footnote span. Note that since the footnote content is within a span element, in theory only inline elements should be used within the footnote content (in HTML5 such elements are now referred to as phrasing content elements). (Footnote: If for example, you want to include indented sections within a footnote, you can do so by using <br> and a span with display:inline-block and padding-left rather than display:block, viz:
Like this short line of text.
And this longer section of text. Though having said that in theory only inline elements should be used within the footnote content, in practice, if you include block level elements inside inline tags it doesn’t produce invalid HTML, and it seems to display correctly in all browsers.

And you can follow that text by non-indented text like this.
But if you want a blank line that you specify to be a different height (as above), you have to use a display:block span, followed by <br>.


And for location of the actual footnotes, the HTML code for the div 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 div where the footnotes are to be located.


For example, on this page, I used the basic class "footnote" for the footnote span and the basic id "Footnotes" of the Footnotes div for the first group of footnotes, and I used the class "footnoteCode" of the footnote span and the id "FootnotesCode" of the Footnotes div for the bottom group of footnotes, and I used the class "footnoteSide" of the footnote span and the id "FootnotesSide" of the Footnotes div for the Side Box group of footnotes. 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. )


The CSS code

Very little CSS is required for the basic functionality:

And for basic functionality for printing the following 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. Elements with the hide” class will not be visible, nor seen by a screen reader.
  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.

An example of formatting the footnotes and the footnote reference numbers is:


The JavaScript Code

The JavaScript 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 standalone. However, while most current browsers work with the JavaScript as is, on some browsers such as IE9, there is not inherent support for the classList method, so a polyfill for the classList method is required, to be inserted before the Easy Footnotes script. You can find one at classList polyfill.


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.


Note: If you copy the JavaScript code below and the footnotes do not work, it may be because there is a problem with the copying of the JavaScript. If this is the case, please download a zipped copy of the essential files at footnotes-demo.zip.

// ############## 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.
document.addEventListener("DOMContentLoaded", function () {
//Note that this does not work in IE8.
// ############## end of document ready function ####################
// ###### Tooltips function which includes setup of footnotes #######
function SetupTips() {
//	the tooltip applies to tags with the "tt_*" class.
//	This preloads often used tooltips.
//	NB: Quotation marks within the variable definition
//	MUST be written as HTML character entities!
//	For straight quote marks, use the codes:
//	&apos; or &#39; or \' (using a preceding backslash) gives straight single quote/apostrophe: '
//	&quot; or &#34; gives straight doublequotes: "
//	Or for curly quotes, use the codes:
//	&lsquo; or &#8216; gives left single curly quote: ‘
//	&rsquo; or &#8217; gives right single curly quote/apostrophe: ’ 
//	&ldquo; or &#8220; gives left double curly quote: “
//	&rdquo; or &#8221; gives right double curly quote: ”
var fnNumber = 0;
var myid = '';
var clsStart, clsEnd;
var myClassList, myClass;
var baseHide, baseFn;
var myFn, i = 0, j = 0, len, clL;
	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];
				clsEnd = myClass.substr(8);
				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('tipContent'); // add class for styling the tooltip
					myFn.insertAdjacentHTML('beforebegin', '[Footnote ' + fnNumber + ']');
					// add the footnote reference to the text
					document.getElementById('Footnotes' + clsEnd).innerHTML += '

[Footnote ' + fnNumber + '] ' + myFn.innerHTML + '

'; // insert footnote number and the footnote where the footnotes are required to appear myFn.classList.remove(myClass); // remove extraneous stuff from the footnote tooltip myFn.getElementsByClassName('fnHide')[0].insertAdjacentHTML('afterend', fnNumber + ': '); // add the footnote number to the tooltip baseFn = document.getElementById(myid + 'Base'); baseHide = baseFn.getElementsByClassName('fnHide'); while (baseHide[0]) { baseFn.removeChild(baseHide[0]); } // remove the "hidden" (Footnote: and ) opening and closing tags of the page bottom footnote . } } } // Make the appropriate parts of the footnotes invisible except to screen readers var fnHides = document.getElementsByClassName('fnHide'); [].forEach.call(fnHides, function (el) { el.classList.add('hide'); }); } // 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')) { myDiv.classList.remove('hideTip'); myDiv.classList.add('unhideTip'); if (divID.substr(0, 3) === 'Fn_') { // For if tip is a footnote replace number with an x document.getElementById(divID + 'a').innerHTML = '[&#215;]'; } } else { myDiv.classList.remove('unhideTip'); myDiv.classList.add('hideTip'); if (divID.substr(0, 3) === 'Fn_') { // For if tip is a footnote, restore the reference number document.getElementById(divID + 'a').innerHTML = '[Footnote ' + divID.substr(3).split('_')[0] + ']'; } } } catch (e) { // alert(e); } } // ######## End of function to set up showing or hiding of text #######


If JavaScript is not enabled, there will be no footnotes at the foot of the page. However, they will appear within the text, 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:


… blah blah blah blah blah blah blah blah … preceding text here
the following text here … blah blah blah blah blah blah …


However, 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 “tipContent”. ) will not display provided the <html> tag has the class "hasJS", hence these tags will not display as the page loads.


In IE8, however, this will cause the footnotes not to appear at all, since IE8 will not process the JavaScript correctly. If it is required that the footnotes must show in IE8 and below, (Footnote: In this case the footnotes will only appear within the text. ) then you need to add an extra line which negates the previous line:

section divider


section divider

Formatting your footnotes

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?

Citing electronic sources



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. That author considered that the footnote references should be accessible via the keyboard. I considered this and rejected it, as that means that the footnote references have to be ploughed through to get to the other links on the page, which are the links of principal interest to the reader - the footnotes are of peripheral interest and are viewable anyway.


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.

section divider



Diverse opinions and criticisms are welcome, but messages that are frivolous, irrelevant or devoid of logical basis will be blocked. Difficulties in understanding the site content are usually best addressed by contacting me by e-mail. Note: you will be asked to provide an e-mail address - any address will do, it does not require verification. Your e-mail will only be used to notify you of replies to your comments - it will never be used for any other purpose and will not be displayed. If you cannot see any comments below, see Why isn’t the comment box loading?.

section divider

Copyright   James R Meyer    2012 - 2020