Accordion
Κώδικας έτοιμος για styling
Πολλαπλά accordions στην ίδια σελίδα, πολλαπλό ή μονό άνοιγμα κτλ

Δημοσιεύθηκε 13/06/2021

Στο παρόν άρθρο θα βρεις έτοιμο lightweight κώδικα για να δημιουργείς Accordion στις ιστοσελίδες.

Ο κώδικας έχει δημιουργηθεί για προσωπικές ανάγκες αλλά θεωρώ πως θα είναι χρήσιμος και για άλλους.

Το μόνο που χρειάζεται είναι να γράψουμε απευθείας το html markup για τα accordion, και να δημιουργήσουμε το σχετικό styling όπως το επιθυμούμε χωρίς να χρειάζεται να κάνουμε override styling καθώς έχω περάσει μόνο τον απολύτως απαραίτητο κώδικα. Έγραψα vanilla JavaScript ο οποίος είναι έτοιμος για χρήση χωρίς να χρειαστεί κάποια μετατροπή.

Accordion: ιδιαίτερα χαρακτηριστικά

  • Δυνατότητα χρήσης πολλαπλών accordion στην ίδια σελίδα.
  • Μέσω του data attribute: data-nb_accordion_open_only_one, δηλώνουμε να παραμένει ανοιχτό μόνο ένα accordion item την φορά. Αν δεν δηλώσουμε το data, η default λειτουργία είναι να ανοιγοκλείνουν τα accordion items κάθε φορά που πατάμε το ίδιο το item ανεξαρτήτως των υπολοίπων.

Accordion κώδικας με παράδειγμα για το html markup

Javascript

Το ενσωματώνουμε ως έχει στο project μας

const nb_accordions = document.querySelectorAll("[data-nb_accordion]");

if (nb_accordions) {
    nb_accordions.forEach((nb_accordion) => {
        let labels = nb_accordion.querySelectorAll("[data-nb_accordion_label]");

        labels.forEach((label) => {
            if (label.closest("[data-nb_accordion_item]").classList.contains("active")) label.nextElementSibling.style.maxHeight = `${label.nextElementSibling.scrollHeight}px`;

            label.addEventListener("click", () => {
                if (nb_accordion.hasAttribute("data-nb_accordion_open_only_one")) {
                    let all_active = nb_accordion.querySelectorAll("[data-nb_accordion_item].active");
                    all_active.forEach((e) => {
                        if (e != label.closest("[data-nb_accordion_item]")) {
                            e.classList.remove("active");
                            e.querySelector("[data-nb_accordion_label]").nextElementSibling.style.maxHeight = "0px";
                        }
                    });
                }

                let closest_accordion_item = label.closest("[data-nb_accordion_item]");
                if (closest_accordion_item.classList.contains("active")) {
                    closest_accordion_item.classList.remove("active");
                    label.nextElementSibling.style.maxHeight = "0px";
                } else {
                    closest_accordion_item.classList.add("active");
                    label.nextElementSibling.style.maxHeight = `${label.nextElementSibling.scrollHeight}px`;
                }
            });
        });
    });
}

CSS

[data-nb_accordion] [data-nb_accordion_item] {
    /* Custom */
    border-bottom: 2px solid #2c4679;
    padding-bottom: 10px;
}

[data-nb_accordion] [data-nb_accordion_item] [data-nb_accordion_label] {
    cursor: pointer;

    /* Custom */
    font-size: 20px;
    padding-top: 10px;
}

[data-nb_accordion] [data-nb_accordion_item] [data-nb_accordion_content] {
    max-height: 0;
    overflow-y: hidden;

    /* Custom */
    transition: all 0.7s ease-in-out;
}

[data-nb_accordion] [data-nb_accordion_item].active [data-nb_accordion_label] {
    /* Custom */
    color: #1263f6;
}

HTML

Είναι απαραίτητο να διατηρήσουμε όλα τα data attributes ως έχουν

  • data-nb_accordion_open_only_one: Είναι προαιρετικό.
  • Αν θέλουμε κάποιο accordion item να είναι ανοιχτό εξ αρχής προσθέτω στο data-nb_accordion_item την κλάση .active
<div data-nb_accordion data-nb_accordion_open_only_one>
	<div data-nb_accordion_item class="active">
		<div data-nb_accordion_label><h1>Title 1</h1></div>
		<div data-nb_accordion_content>
			<h2>Content of Title 1.</h2>
			<p>Curabitur non nulla sit amet nisl</p>
		</div>
	</div>
	<div data-nb_accordion_item>
		<div data-nb_accordion_label><h1>Title 2</h1></div>
		<div data-nb_accordion_content>
			<h2>Content of Title 2.</h2>
			<p>Curabitur non nulla sit amet nisl</p>
		</div>
	</div>
</div>

Ο παραπάνω κώδικας υπάρχει και στον Github λογαριασμό μου.