Tips for arranging accordion buttons side by side so they all expand into a single element

I'm currently working on a unique accordion design where multiple buttons expand into individual areas below when clicked. The standard accordion layout isn't quite what I'm aiming for. I envision the buttons all in a row, and when clicked, they should expand into separate sections below, creating a design like this:

 _   _   _   _
|_| |_| |_| |_|  (unclicked)
 _   _   _   _
|x|_|_|_|_|_|_|  (clicked)
| text of     |  
| accordion   |
|_____________|

(please excuse the ASCII art.)

Currently, the behavior I'm experiencing is more like this:

 _  
|x|___________   (clicked)
| text of     |  
| accordion   |
|_____________|
|_| |_| |_|      <-- other accordion buttons

I'm having trouble figuring out how to achieve the desired layout. I've experimented with various accordion styles, like expandable tables, but haven't been successful. I haven't come across any examples of this specific accordion style either. Is it possible to achieve this using a similar code structure to what I already have?

Here's a Fiddle link to my current progress: https://jsfiddle.net/zeuyhtpw/3/

::edit additional code:

HTML:

<button class="accordion">Button 1</button>
<div class="story">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute iruredolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscingelit,
    sed do eiusmod tempor incididunt ut labore et dolore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<button class="accordion">Button 2</button>
<div class="story">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut at aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<button class="accordion">Button 3</button>
<div class="story">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut at aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in algae culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<button class="accordion">Button 4</button>
<div class="story">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex pooja commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

CSS:

.story {
  display: none;
}

.accordion {
  background-color: black;
  color: white;
  padding: 5px;
}

JS:

var acc = document.getElementsByClassName("accordion");
for (var i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    story = this.nextElementSibling;

    if (story.style.display === "block") {
      story.style.display = "none";
    } else {
      story.style.display = "block";
    }
  });
}

Answer №1

I made a few adjustments to your example https://jsfiddle.net/7szxorcq/17/

Markup

<button class="accordion">Button 1</button>
<button class="accordion">Button 2</button>
<button class="accordion">Button 3</button>
<button class="accordion">Button 4</button>
<div class="story">
  <p>1 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscingelit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="story">
  <p>2 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="story">
  <p>3 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="story">
  <p>4 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

JavaScript

const acc = document.getElementsByClassName("accordion");
const stories = document.getElementsByClassName("story");

for (let i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", () => {

    // Display the selected story
    for (let j = 0; j < stories.length; j++) {
        stories[j].style.display = i === j
        ? 'block'
        : 'none';
    }

  });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the solution to fixing the error "TypeError: Cannot read properties of undefined (reading 'map') in Next.js"?

As a newcomer looking to create a blog using the Notion API, Next.js, and Tailwind CSS, I came across this code snippet on this website. Although the code functions correctly in /post/index.js, I encounter an error when trying to use it in /components/Pos ...

Navbar not responding correctly to Bootstrap5 scrollspy feature

I'm currently working on implementing a scrollspy feature using Bootstrap 5.3. I've been referring to the Bootstrap 5 example to create my HTML page, which you can view at the following link: https://stackblitz.com/edit/web-platform-phnijx?file= ...

Ways to pass scope between the same controller multiple times

There is a unique scenario in which I have a controller appearing in 2 different locations on a page. This arrangement is necessary for specific reasons. To illustrate, the simplified HTML structure is as follows: <aside ng-if="aside.on" ng-controller ...

Display a div element on the page after 10 seconds of loading

Recently, I managed to get this script working successfully where it fades out within 20 seconds. However, I am looking to modify it so that it takes only 10 seconds to display after the page loads. Any suggestions on what I should change in the code? jQu ...

How to display a modal within a router-link in Vue 3?

Below are buttons with router-links. However, I only want the calculator button to open a modal. When I execute the code provided, all buttons trigger the modal instead of just the calculator button. Output: https://i.sstatic.net/layQ1.png Router-link C ...

Convert time display to a 24-hour format using JavaScript

I managed to convert the time format from GMT to my browser's local time using the following JavaScript code: var newDate = new Date(timeFromat); timeFormat = newDate.toLocaleString(); Now, I want to change the time format to a 24-hour clock format ...

The form in ReactJs is not functioning properly as it is not properly connected, despite containing only a

When attempting to create a form to add a new item into an array, I encountered the error message: Form submission cancelled because form is not connected. Despite finding some suggestions to change the submit button type from "submit" to "button", it did ...

Problems with implementing JavaScript code in a WebView

I am currently working on an android WebView project where I have managed to change the background color to orange with this code snippet. @Override public void onPageFinished(WebView view, String url) { wv.loadUrl("jav ...

The issue arises with getInitialProps as it fails to pass data to the page component while attempting to retrieve initial information and subsequently modify it using a button

I am currently working on a component located at app\page.tsx in Next.js v13.4.12, and it includes a button. My goal is to have the button trigger the handleClick function when clicked. The issue I'm facing is that the getInitialProps function ...

Troubleshooting problem with CSS layout when adjusting the height of a section

I recently delved into creating a simple website using HTML5 and have successfully set up the site structure. Everything has been smooth sailing so far. However, I've encountered a section of the site that seems to have a mind of its own. When I ass ...

Separate string by using a regular expression pattern

Looking to parse a dynamic string with varying combinations of Code, Name, and EffectDate. It could be in the format below with all three properties or just pairs like Code-Name, Code-EffectDate, or Name-EffectDate. {"Code":{"value":"1"},"Name":{"value": ...

Utilizing Jquery to wrap HTML content with div elements within a secure Content Management System

Despite my best efforts, I have hit a roadblock and need some help. I want to utilize Javascript/Jquery within this restrictive cms to wrap two lists in their own div. Take a look at the current code snippet below. Unfortunately, the closed cms is set in ...

Navigating with VueRouter in your Chrome Extension is a breeze

I have been working on a Chrome extension using Vue 3 + VueRouter. One issue I encountered was trying to change the router-view content to display a different component, essentially showing users a different UI. Despite my efforts and various methods use ...

Discover the process of creating a dynamic mailto link using AJAX and HTML

One of my tasks involves extracting email addresses from an XML document using AJAX, and then displaying them on a webpage as clickable links for sending emails. Here is a snippet of JavaScript code I am working with: emailobj = listings[i].getElementsBy ...

Tips for refreshing a GET request within a Vue.js application

I am receiving data from my Rails API backend and I would like to automatically refresh that GET request every 15 seconds. This way, if there are any changes on the backend (for example, if a POST request is made to another route), it will reload and retri ...

Issue with mobile browser validation for text field functionality not functioning properly

Issue with text box validation on mobile browsers for my Angular application Mobile Browsers: Chrome, Samsung Browser (not working in both) Expected Input: Numbers 0-9 and Alphabets A-Z only in the text field My Approach : 1. Initial Attempt: I attempted ...

What is the purpose behind webpack compiling global.js?

As I dive into the world of webpack, my initial build unearthed an unexpected default file in the output (index 1): build.js 222 kB 0 [emitted] main [1] (webpack)/buildin/global.js 509 bytes {0} [built] [2] ./source/scripts/main.js 105 byte ...

JavaScript Password Form Submission - Enter your password in the form

I need assistance with setting up a password for a form. Users should be able to enter a password into a specified field, click submit, and if the password is correct, they will be redirected to buybutton.php in the same window. If the password is incorr ...

Maintain the color of a Bootstrap 4 dropdown link even when it is open by incorporating hover

Currently, I am utilizing bootstrap 4 to create a menu that includes dropdown items. The issue I am facing is that when hovering over a dropdown link, the background color changes and the dropdown opens. However, as soon as I move the mouse to select one o ...

What is the best way to design a webpage that adapts to different screen heights instead of widths?

I'm in the process of designing a basic webpage for a game that will be embedded using an iframe. The game and text should always adjust to fit the height of your screen, so when the window is small, only the game is displayed. The game will be e ...