Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <section>
    <div class="accordion">
        <div class="accordion-header"><span>+</span>First Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae expedita dolor commodi illum impedit veritatis deleniti facere consectetur repudiandae provident libero molestias, tempora qui? Non ab consectetur maxime dolore tempora.</p>
        </div>
        <div class="accordion-header"><span>+</span>Second Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iusto quidem odio quibusdam inventore itaque voluptatibus unde quod. In officiis veniam eius tempore eveniet? Nihil esse facere illum voluptate quia accusamus.</p>
        </div>
        <div class="accordion-header"><span>+</span>Third Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum voluptatum hic facilis obcaecati eligendi voluptas atque porro. Magnam aliquam voluptas, vel accusantium explicabo, commodi eveniet, voluptatibus itaque nobis tempore cupiditate.</p>
        </div>
        <div class="accordion-header"><span>+</span>Fourth Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Facere fugiat soluta, adipisci corporis rerum distinctio rem veniam vel omnis fuga eveniet eaque saepe earum, repudiandae id laborum cumque eum molestias.</p>
        </div>
    </div>
    <div class="accordion">
        <div class="accordion-header"><span>+</span>Fifth Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Minus, magnam magni voluptas quasi temporibus maiores tempore repudiandae vero veniam provident harum? Quasi placeat voluptates laudantium, iusto qui facilis ratione et?</p>
        </div>
        <div class="accordion-header"><span>+</span>Sixth Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, similique deleniti. Sunt sit modi tempora quis reprehenderit dolor, ducimus, sed quaerat consectetur nostrum hic dolores, provident voluptates debitis eius dolore?</p>
        </div>
        <div class="accordion-header"><span>+</span>Seventh Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad ut molestiae sit repellat iste distinctio repellendus, dolorem recusandae consequatur debitis, doloremque tempore veniam ullam saepe quidem eligendi, eos dignissimos qui.</p>
        </div>
        <div class="accordion-header"><span>+</span>Eight Topic</div>
        <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus dolorem at sed beatae nostrum ducimus quibusdam. Esse at repudiandae possimus numquam. Expedita porro, quos optio consequatur iste eligendi aliquam fugiat?</p>
        </div>
    </div>
</section>
              
            
!

CSS

              
                @import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');

section {
    display: flex;
    justify-content: space-around;
    margin: 0 auto;
    width: 900px;
}

section > * {
    width: 400px;
}

.accordion {
    font-family: 'Open Sans';
    margin-bottom: 10px;
    margin-top: 10px;
}

.accordion-header {
    border: 1px solid #cad2d8;
    border-radius: 30px;
    color: #8f9cab;
    cursor: pointer;
    font-size: 22px;
    font-weight: bold;
    padding: 10px 30px;
    transition: 0.12s ease-in-out;
}

.accordion-header > span {
    color: #14cdeb;
    margin-right: 10px;
}

.accordion-header.expanded-bottom {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.accordion-header.expanded-top {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.accordion-header:hover {
    background-color: #f8f8f8;
}

.accordion-content {
    background-color: #f2f5f5;
    border-left: 1px solid #cad2d8;
    border-right: 1px solid #cad2d8;
    opacity: 1;
    padding: 10px 30px;
}

.accordion-content.transition {
    transition: 0.24s ease-in-out;
}

.accordion-content.invisible {
    opacity: 0;
    padding: 5px;
    visibility: hidden;
}

.accordion-content.invisible > * {
    display: none;
}

.accordion-content.last-of-block {
    border-bottom: 1px solid #cad2d8;
    border-bottom-left-radius: 25px;
    border-bottom-right-radius: 25px;
}

              
            
!

JS

              
                const accordionContentHeights = []

const toggleAccordion = (accordion, headerIndex) => {
    const currentAccordion = document.getElementsByClassName('accordion')[accordion]
    const accordionHeaders = currentAccordion.getElementsByClassName('accordion-header')
    const currentHeader = accordionHeaders[headerIndex]
    const nextHeader = accordionHeaders[headerIndex + 1]
    const accordionContent = currentAccordion.getElementsByClassName('accordion-content')[headerIndex]

    currentHeader.classList.toggle('expanded-top')

    if (nextHeader) {
        nextHeader.classList.toggle('expanded-bottom')
    } else {
        accordionContent.classList.toggle('last-of-block')
    }

    if (accordionContent.classList.contains('invisible')) {
        currentHeader.firstElementChild.innerText = '–'

        // Set accordion content height to the stored scrollHeight so that the transition plays.
        accordionContent.style.height = accordionContentHeights[accordion][headerIndex] + 'px'

        // Set accordion content height to auto after 100ms in order to make it responsive.
        setTimeout(() => accordionContent.style.height = 'auto', 100)
    } else {
        // Store the scrollHeight of the accordion content.
        accordionContentHeights[accordion][headerIndex] = accordionContent.scrollHeight
        currentHeader.firstElementChild.innerText = '+'

        // Set the accordion content height to the current scrollHeight as it's set to auto when this happens. Transitions won't play if the height is auto.
        accordionContent.style.height = accordionContentHeights[accordion][headerIndex] + 'px'

        // Set accordion content height to 0 after 10ms. The delay is necessary for the previous height change to take effect (otherwise it would still be auto and the transition wouldn't play).
        setTimeout(() => accordionContent.style.height = '0', 10);
    }

    accordionContent.classList.toggle('invisible')
}

// Add event listeners to accordion headers
const accordions = document.getElementsByClassName('accordion')

for (let i = 0; i < accordions.length; i++) {
    accordionContentHeights.push([])
    const accordionHeaders = accordions[i].getElementsByClassName('accordion-header')
    const accordionContents = accordions[i].getElementsByClassName('accordion-content')

    for (let j = 0; j < accordionHeaders.length; j++) {
        // Store all accordion content heights for later use (necessary for animating the height).
        accordionContentHeights[i].push(accordionContents[j].scrollHeight)

        accordionHeaders[j].addEventListener('click', () => {
            toggleAccordion(i, j)
        })

        // Make the contents invisible.
        accordionContents[j].style.height = '0px'
        accordionContents[j].classList.add('invisible')
    }

    // Add the transition class to the contents after 100ms so that the transition doesn't play when they are initially hidden.
    setTimeout(function() {
        for (let j = 0; j < accordionContents.length; j++) {
            accordionContents[j].classList.add('transition')
        }
    }, 100)
}

              
            
!
999px

Console