FAQ dropdown list

Page section: playground

Frequently Asked Questions

How do you use Font Awesome in your pages?

You need an account at fontawesome. But there is a free version. Create a set of icons on their website, save them which generates a script tag.

Add this to the head section of the page with a script tag.

To enable this add to the page's frontmatter: fontawesome: true

You can now add an icon anywhere with an italic element with typically 2 classes beginning with fa for your chosen icon

What are the drawbacks of Font Awesome?

The free version is limited to 10k page views per month. Fine for some things, but easily exceeded for many things. This page used up 3% of that total in just 8 days. Most of that would be for page testing since no one else visits the site.

The paid version is also said to be faster because you only load the icons a page needs.

Font Awesome seems like it can dramatically slow page speeds down.

You're dependent on an external service which could shut down at any time or change it's terms and conditions too.

What are the alternatives to Font Awesome?

Create an SVG sprite for yourself and host it yourself.

There are many alternative icon sites. See the list on blank try.

You're dependent on an external service which could shut down at any time or change it's terms and conditions too.

Where are you most likely to see a tenrec?

a tenrecThere are many species of tenrec and all are native to Madagascar. However most people will never go to Madagascar so are unlikely to see one, or any other creature, there.

So you're probably most likely to see one in a zoo in the country where they live.

How it works

There are two ways to make this work below. First the HTML:

The HTML

Each question and answer resides in an <article> like this. It contains 2 divs, one for the question and one for the answer. The question div contains a single <button> that has two icons: a plus (show) one and minus (hide) one. CSS and JS make sure only one is visible at any one time.

<article>
    <div class="question">
        <p>Do you prefer badgers or stoats?</p>
        <button class="question-btn">
            <span class="plus-icon">
                <i class="far fa-plus-square"></i>
            </span>
            <span class="minus-icon">
                <i class="far fa-minus-square"></i>
            </span>
        </button>
    </div>
    <div class="answer">
        <p>I don't really have a preference. It's not something I given much thought to.</p>
    </div>
</article>

Traversing the DOM

The first method uses a forEach array method on all the buttons and uses the event’s target to select the specific button.

A class is then added to or removed from the parent element (in the case it’s actually the parent of the parent).

const questionBtns = document.querySelectorAll('.question-btn');
const articles = document.querySelectorAll('.section-center article');

questionBtns.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    const parent = e.currentTarget.parentElement.parentElement;
    parent.classList.toggle('show-text');
  });
});

Using selectors inside the element

The alternative method loops over each question title div. It selects the buttons from inside the loop

const questions = document.querySelectorAll('.question');

questions.forEach((question) => {
    const btn = question.querySelector('.question-btn');

    btn.addEventListener('click', () => {
        question.parentElement.classList.toggle('show-text');
    });
});

Closing any open answer boxes

Although the above code open’s and closes each answer an optional bit of code is used to close any open answer boxes before opening a new answer so that only one anwser is visible at a time.

This uses a second forEach loop running inside the first so that it runs with each click of a button. This second loop goes through each article (item.parentElement) and if the answer is visible hides it.

const questions = document.querySelectorAll('.question');

questions.forEach((question) => {
    const btn = question.querySelector('.question-btn');
    btn.addEventListener('click', () => {
        
        questions.forEach((item) => {
            if (item.parentElement !== question.parentElement) {
                item.parentElement.classList.remove('show-text')
            };
        });

        question.parentElement.classList.toggle('show-text');
    });
})