Skip to main content
April 1, 2026Dan Rodney/11 min read

Simple Accordion with JavaScript

Master Interactive Web Elements with JavaScript

Core JavaScript Skills You'll Build

DOM Manipulation

Learn to target HTML elements and modify their properties using JavaScript's getElementById method and style properties.

Event Handling

Implement click events using the onclick attribute to create interactive user experiences on web pages.

Function Creation

Write reusable JavaScript functions that can be called when specific user interactions occur on your website.

Topics Covered in This JavaScript & JQuery Tutorial:

Master the fundamentals of dynamic web interfaces by learning to hide and show elements with JavaScript, then apply these skills to build a professional accordion component from scratch.

Exercise Preview

accordion preview

Exercise Overview

Accordions represent one of the most versatile UI patterns in modern web development, allowing you to present substantial amounts of information in an organized, space-efficient manner. By dynamically hiding and revealing content sections, accordions create intuitive user experiences that reduce cognitive load while maintaining easy access to information. In this hands-on exercise, you'll construct a fully functional accordion interface using vanilla JavaScript, mastering the core DOM manipulation techniques that power countless interactive web applications. This foundational knowledge will serve you whether you're building enterprise dashboards, content management systems, or responsive mobile interfaces.

What Makes Accordions Valuable

Accordions let you condense a lot of information into a small space by hiding some of it. One click reveals another section while hiding the previous one, creating an efficient content organization system.

Getting Started

Before diving into the code, let's set up your development environment and examine the project structure. This systematic approach ensures you understand both the starting point and the end goal.

  1. Launch your preferred code editor if it isn't already running.
  2. Close any currently open files to maintain a clean workspace.
  3. Navigate to the Simple-Accordion folder located in Desktop > Class Files > yourname-JavaScript jQuery Class. If your editor supports project folders (such as Visual Studio Code, Sublime Text, or Atom), open the entire folder for better file management and IntelliSense support.
  4. Open index.html from the Simple-Accordion folder to examine the base HTML structure.
  5. Preview the page in a modern browser (Chrome, Firefox, Safari, or Edge) to see the current state.
  6. Observe the accordion component on the right side of the page. Notice its three distinct panels, each containing an event category. Each panel consists of a clickable tab header and associated content below. Our goal is to implement the show/hide functionality that makes only one panel's content visible at a time.
  7. Test the current functionality by clicking on any tab (such as Coming Up). You'll notice that nothing happens yet—this is expected, as we haven't implemented the JavaScript logic.
  8. Keep the browser tab open for testing as we progress through the implementation.
  9. Return to your code editor to begin writing the JavaScript functionality.
  10. First, we'll create a script block in the document head. Add the following code before the closing </head> tag (around line 7):

    <link rel="stylesheet" href="css/main.css">
    <script>
    
    </script>
    </head>
  11. Now we'll implement our first piece of functionality: hiding specific content panels on page load. The accordion should initialize with only one panel visible, creating a clean starting state. Let's begin by targeting the comingUpContent div and hiding it programmatically.

    Inside the script tag, add the following code:

    <script>
       document.getElementById('comingUpContent');
    </script>
  12. The getElementById() method returns a reference to the DOM element, but we need to modify its visual properties. We'll access the element's CSS properties using JavaScript's dot notation syntax:

    <script>
       document.getElementById('comingUpContent').style;
    </script>
  13. Now we'll set the display property to completely hide the element from the layout:

    <script>
       document.getElementById('comingUpContent').style.display = 'none';
    </script>

    The HTMLElement.style property provides direct access to an element's inline CSS styles. Because inline styles have the highest specificity in the CSS cascade (excluding !important declarations), this approach reliably overrides any external stylesheet rules. This makes it ideal for dynamic show/hide functionality where you need guaranteed control over element visibility.

  14. Save the file, switch to your browser, and refresh index.html. You might be surprised that the Coming Up panel remains visible. This apparent failure actually illustrates a crucial concept in web development timing.

    The issue stems from how browsers parse and execute code. HTML documents are processed sequentially from top to bottom. When our JavaScript executes in the <head> section, it attempts to access the comingUpContent element before that element has been created in the DOM. This timing mismatch causes the script to fail silently. The solution is to move our JavaScript to the bottom of the document, ensuring all HTML elements exist before our code tries to manipulate them.

  15. Switch back to your code editor to relocate the script.
  16. Cut the entire <script> tag and its contents from the head section.
  17. Paste it just before the closing </body> tag (around line 86):

    </div>
    <script>
       document.getElementById('comingUpContent').style.display = 'none';
    </script>
    </body>

    This positioning ensures our JavaScript executes after all DOM elements have been created and are ready for manipulation.

  18. Save the file, return to your browser, and refresh index.html.
  19. Excellent! The Coming Up panel's content now disappears on page load, confirming our script is executing correctly.

    Note that our code runs immediately when the page loads because it's not wrapped in a function. This immediate execution is perfect for initialization tasks like setting up the accordion's default state.

  20. Return to your code editor to hide the second panel.
  21. Apply the same technique to hide the pastEventsContent div by adding this line to your script:

    <script>
       document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
    </script>
  22. Save and refresh to verify that both the Coming Up and Past Events panels are now hidden, leaving only Events This Week visible by default.

Project Setup Process

1

Open Your Development Environment

Launch your code editor and close any existing files to start fresh with this accordion exercise.

2

Navigate to Project Files

Access the Simple-Accordion folder in Desktop > Class Files > yourname-JavaScript jQuery Class directory.

3

Preview the Initial State

Open index.html in a browser to see the non-functional accordion with three panels before adding JavaScript functionality.

Critical JavaScript Placement

Browsers read code from top to bottom. JavaScript in the head section executes before HTML elements are created, causing failures. Always place JavaScript at the bottom of the HTML for proper execution.

Implementing Interactive Show/Hide Functionality

Now that we've established the accordion's default state, we'll implement the interactive behavior that makes accordions so useful. This involves creating functions that respond to user clicks and managing the visibility state of multiple panels.

  1. Return to your code editor to begin implementing the click-to-show functionality.
  2. We need to create a function that will execute when users click the Coming Up tab. Functions allow us to bundle code that runs on-demand rather than immediately. Add this function structure after your existing code:

    document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
    
       function showComingUp() {
    
       }
    </script>
  3. Inside this function, we'll make the Coming Up panel visible by setting its display property to 'block':

    document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
    
       function showComingUp() {
         document.getElementById('comingUpContent').style.display = 'block';
       }
    </script>

    The 'block' value restores the element to normal document flow, making it visible and allowing it to occupy its full width and natural height based on its content.

  4. Creating the function is only half the solution—we need to connect it to user interactions. Find the comingUpTab div (around line 39) and add an onclick event handler:

    <div class="accordionPanelTab" id="comingUpTab" onclick="showComingUp();"> Coming Up</div>

    The onclick attribute creates an event listener that executes our function whenever users click this element. This inline approach is perfect for simple interactions and keeps the HTML self-documenting.

  5. Save your changes, refresh the browser, and test the functionality.

  6. Click the Coming Up tab to see its content appear. This works, but notice a critical UX problem: multiple panels can now be open simultaneously, defeating the accordion's purpose of space conservation.

    Professional accordions typically allow only one panel to be open at a time. We need to hide all other panels whenever a user opens a new one.

  7. Switch back to your code editor to solve this issue.
  8. We'll create a reusable hidePanels() function that closes all accordion sections. This separation of concerns makes our code more maintainable and easier to debug:

    document.getElementById('comingUpContent').style.display = 'none';
    document.getElementById('pastEventsContent').style.display = 'none';
    
    function hidePanels() {
       document.getElementById('eventsWeekContent').style.display = 'none';
       document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
    }
    function showComingUp() {
       document.getElementById('comingUpContent').style.display = 'block';
    }

    By centralizing the hide logic, we ensure consistent behavior across all accordion interactions and make it easy to modify the hiding behavior later if needed.

  9. Now we'll integrate the hide functionality into our show function. Modify showComingUp() to call hidePanels() first:

    function hidePanels() {

    Code Omitted To Save Space

    }
    function showComingUp() {
       hidePanels();
       document.getElementById('comingUpContent').style.display = 'block';
    }

    This sequence ensures that clicking any tab first closes all panels, then opens the requested one—exactly how users expect accordions to behave.

  10. Save and test your changes in the browser.

  11. Click the Coming Up tab to verify that it now properly closes any open panel before displaying its own content. The remaining tabs still don't function, but we'll address that next.

Completing the Accordion Interface

With the core mechanism working for one panel, we can quickly replicate this pattern for the remaining tabs. This repetition will reinforce the concepts while completing our functional accordion.

  1. Return to your code editor to implement the remaining panel functions.
  2. Copy the entire showComingUp() function.
  3. Paste a duplicate directly above the original function.
  4. Modify the duplicate to handle the Events This Week panel:

    function hidePanels() {

    Code Omitted To Save Space

    }
    function showEventsWeek() {
       hidePanels();
       document.getElementById('eventsWeekContent').style.display = 'block';
    }
    function showComingUp() {
  5. Connect this function to its corresponding tab by adding an onclick handler to the eventsWeekTab div (around line 26):

    <div class="accordionPanelTab" id="eventsWeekTab" onclick="showEventsWeek();">Events This Week</div>
  6. Save your changes and test in the browser.
  7. Verify that both the Coming Up and Events This Week tabs now function correctly, with proper mutual exclusion behavior.
  8. Return to your editor to complete the final tab.
  9. Copy the showComingUp() function again.
  10. Paste this copy directly below the original function.
  11. Modify it for the Past Events panel:

    function showComingUp() {
          hidePanels();
          document.getElementById('comingUpContent').style.display = 'block';
       }
       function showPastEvents() {
          hidePanels();
          document.getElementById('pastEventsContent').style.display = 'block';
       }
    </script>
  12. Add the onclick handler to the pastEventsTab div (around line 52):

    <div class="accordionPanelTab" id="pastEventsTab" onclick="showPastEvents();">Past Events</div>
  13. Save and test the complete accordion functionality in your browser.

  14. Click through all three tabs to confirm that your accordion now works flawlessly, with smooth transitions between panels and proper state management.

Professional Enhancement: Visual Feedback for Active States

A polished accordion provides clear visual feedback about which panel is currently active. This enhancement transforms a functional component into a professional-grade interface element that guides users intuitively.

  1. Return to your code editor to examine the provided styling.

  2. Open main.css from the css folder and scroll to the bottom.

    Notice the pre-built .highlight CSS rule that modifies both text color and background color. This rule represents a common pattern in professional web development: preparing visual states in CSS and activating them programmatically with JavaScript.

  3. Return to index.html in your code editor.
  4. Locate the eventsWeekTab element around line 26.
  5. Observe that this element currently has only the accordionPanelTab class applied.

    CSS classes are not mutually exclusive—elements can have multiple classes separated by spaces. We'll leverage this to dynamically add and remove the highlight styling based on user interactions.

  6. Initialize the accordion with the first panel highlighted by adding this line to your script (around line 86). Pay careful attention to the space between class names:

    <script>
       document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
       document.getElementById('eventsWeekTab').className = 'accordionPanelTab highlight';

    The className property replaces the element's entire class attribute, so we must include both the base styling class and the highlight class.

  7. Save and refresh in your browser to see the Events This Week tab now displays with enhanced visual prominence.
  8. Switch back to your code editor to implement dynamic highlighting.
  9. Enhance each show function to highlight its corresponding tab when activated:

    function showEventsWeek() {
       hidePanels();
       document.getElementById('eventsWeekContent').style.display = 'block';
       document.getElementById('eventsWeekTab').className = 'accordionPanelTab highlight';
    }
    function showComingUp() {
       hidePanels();
       document.getElementById('comingUpContent').style.display = 'block';
       document.getElementById('comingUpTab').className = 'accordionPanelTab highlight';
    }
    function showPastEvents() {
       hidePanels();
       document.getElementById('pastEventsContent').style.display = 'block';
       document.getElementById('pastEventsTab').className = 'accordionPanelTab highlight';
    }
  10. Save and test the highlighting functionality.
  11. Click between tabs and notice that highlights are applied correctly, but they accumulate rather than switching properly. We need to clear all highlights before applying the new one.
  12. Return to your code editor to fix this issue.
  13. Find the hidePanels() function (around line 91).
  14. Since hidePanels() runs before every tab activation, it's the perfect place to reset all tab states to their unhighlighted appearance:

    function hidePanels() {
       document.getElementById('eventsWeekContent').style.display = 'none';
       document.getElementById('comingUpContent').style.display = 'none';
       document.getElementById('pastEventsContent').style.display = 'none';
       document.getElementById('eventsWeekTab').className = 'accordionPanelTab';
       document.getElementById('comingUpTab').className = 'accordionPanelTab';
       document.getElementById('pastEventsTab').className = 'accordionPanelTab';
    }

    This approach ensures clean state management: every interaction first resets all tabs to their default appearance, then applies the highlight to only the active tab.

  15. The complete interaction flow now works as follows:

    • User clicks any tab
    • All panel content gets hidden
    • All tab highlights are removed
    • The clicked panel's content becomes visible
    • The clicked tab receives visual highlighting
  16. Save your final changes and test thoroughly in the browser.

  17. Click through all tabs to confirm that both content switching and visual feedback work seamlessly together, creating a polished, professional accordion interface.

    If you want to compare your implementation with our reference solution, navigate to Desktop > Class Files > yourname-JavaScript jQuery Class > Done-Files > Simple-Accordion for the complete working example.

Key Takeaways

1JavaScript must be placed after HTML elements in the document to ensure proper execution and avoid targeting non-existent elements
2The document.getElementById() method is essential for targeting specific HTML elements by their ID attributes for manipulation
3CSS properties can be modified through JavaScript using the style property, with display values controlling element visibility
4Creating reusable functions like hidePanels() reduces code duplication and makes maintenance easier across multiple accordion panels
5Event handling through onclick attributes connects user interactions to JavaScript functions for dynamic web functionality
6Multiple CSS classes can be applied to elements using the className property to combine base styles with conditional styling
7Accordion interfaces provide an effective way to organize large amounts of content in limited space through progressive disclosure
8Visual feedback through highlighting active tabs improves user experience by clearly indicating the current state of the interface

RELATED ARTICLES