Logic and Language
Load the menuLoad the menu

Copyright   James R Meyer    2012 - 2022 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)

Page last updated 18 Nov 2022


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 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: 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.

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:

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.


Update: I have added the initial character code &#8288; since 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. I have found that putting the character code &#8288; (a zero-width prevent-break character) immediately before the <span class="footnote"> seems to prevent this happening, and so I now use this method for all footnotes. Note that if you are copying the code from the box above, you should check that it copies the &#8288; correctly. 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; if I do not want a line break between any two, I use the code &#8288;&nbsp;&#8288; between the end of one footnote span and the start of the next.


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: 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 rather than display:block, 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 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 line-height (as the blank line above), you have to use a display:block span enclosing a &nbsp; and specify the desired line-height, e.g:
<span style="line-height:0.3; display:block">&nbsp;</span>)


And for the 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" for the footnote span and the id "FootnotesCode" for the Footnotes div for the bottom group of footnotes, and I used the class "footnoteSide" for the footnote span and the id "FootnotesSide" for 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. 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.

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 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.


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 () {


// ############## 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;

	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', 'Skip footnote section');
						// add the hidden div to where that link goes to
						document.getElementById('Footnotes' + clsEnd).insertAdjacentHTML('afterend', '
'); } // 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('tipContent'); // add class for styling the tooltip myFn.setAttribute('role', 'note'); //add ARIA attribute for accessibility // add the footnote reference to the text myFn.insertAdjacentHTML('beforebegin', '[Footnote ' + fnNumber + ']'); // insert footnote number and the footnote where the footnotes are required to appear document.getElementById('Footnotes' + clsEnd).innerHTML += '

[Location of footnote ' + fnNumber + '] ' + myFn.innerHTML + '

'; 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 // 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]) { baseFn.removeChild(baseHide[0]); } } } } // 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('invis'); }); } // 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 = '[]'; } } 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:


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


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.

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?



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).

section divider

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.


HashOver logoBased on HashOver Comment System by Jacob BarkdullHashOver logo

Copyright   James R Meyer   2012 - 2022