Turn an Ordered List on an HTML Page into a Collapsible FAQ List

Yihui Xie 2021-10-28

Last year my colleague Christophe suggested that I add a table of contents and anchor links on the FAQ page of tinytex (#94, #95), which were definitely good ideas. This week I took some time to reorganize my miscellaneous JavaScript code, learned a little bit about NPM, and published my scripts as a Node package.1

During this process, I wrote another little script to convert an ordered list on an HTML page into a collapsible FAQ list. Basically, all you need to do is load the script and stylesheet in your HTML or (R) Markdown document:

<link href="https://cdn.jsdelivr.net/npm/@xiee/utils/css/faq.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/@xiee/utils/js/faq.min.js" defer></script>


Below is a quick demo:

  1. What’s the answer to life, the universe, and everything?


  2. Who is Frida Gomam?

    This clever lady: https://www.reddit.com/r/funny/comments/9u22lb/frida_gomam/

  3. How to quit vim?

    But why?

You can click on each question to reveal or hide its answer. Or click on the ⊕ button at the top-right to expand/collapse all answers. When you mouse over a question, its anchor link (denoted by the # symbol) will become visible at the end. You can use the link to point to a specific FAQ item, e.g., https://yihui.org/tinytex/faq/#faq-3.

Selection of ordered lists

This JS program looks for all ordered lists (<ol>) on a page, and turns a list into an FAQ list if it satisfies the following conditions:

  1. It either has no class attribute, or contains an faq-list class;
  2. Each of its child element contains at least two child elements (the first one is the question, and the rest is the answer);
  3. It is a direct child of <div>, <main>, <section>, or <article>, and the container does not have the footnotes class (to avoid accidentally converting footnote items into FAQ lists).

For example, the above ordered list was ignored by this program because its child items only contain one child.


A class faq-list will be added onto the <ol> element, and you can style the list using CSS rules if you are not satisfied with the default minimal styling. For example, since it is Halloween, let’s make the list a little spooky:

<style type="text/css">
.faq-list > li {
  border-color: ghostwhite;
.faq-list > li > :first-child, .faq-button {
  background: darkorange;
  color: ghostwhite;
  font-family: Papyrus, fantasy;

Then you get an orange theme like this:

A spooky FAQ list

This JS application was inspired by Jiena’s awesome faq package, which is an HTML widget package that allows you to create an FAQ list from a data frame in R. You can use it in either R Markdown or Shiny apps. Thanks Jiena!2

Please feel free to let me know if you have any suggestions or feedback. You can either leave a comment below or file an issue to GitHub.

  1. This is not really a normal Node.js package. Most scripts are self-contained and are for side-effects in browser only. My motivation of publishing them anyway is to be able to use jsdelivr.com. ↩︎

  2. Please feel free to visit Omaha again, and I’m ready to cook at any time! ↩︎