Expandable menu featuring visual icons and a toggle symbol

I am in need of assistance to implement an accordion menu with unique picture icons for each item on the left and a toggle icon (such as + or a chevron) on the right side.

Visually, I would like it to resemble this design (https://codepen.io/kathykato/pen/MoZJom), but with the addition of a custom icon on the left of each item to represent its content.

I am using SquareSpace, however, since SquareSpace does not offer an accordion menu block/widget, I plan to manually input the code. Despite spending hours experimenting with different code snippets and trying to modify existing examples, this is my first attempt at creating an accordion menu and I am facing difficulties.

Your help would be greatly appreciated!

Below is the example code structure that I aim to achieve, but with the inclusion of a unique picture icon on the left:

HTML:

<div class="container">
  <h2>Frequently Asked Questions</h2>

  <div class="accordion">
    <div class="accordion-item">
      <a>Why is the moon sometimes out during the day?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
    <div class="accordion-item">
      <a>Why is the sky blue?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
    <div class="accordion-item">
      <a>Will we ever discover aliens?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
    <div class="accordion-item">
      <a>How much does the Earth weigh?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
    <div class="accordion-item">
      <a>How do airplanes stay up?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
  </div>

</div>

CSS:

@import url('https://fonts.googleapis.com/css?family=Hind:300,400');

*, *:before, *:after {
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
}

html {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  font-family: 'Hind', sans-serif;
  background: #fff;
  color: #4d5974;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  min-height: 100vh;
}

.container {
  margin: 0 auto;
  padding: 4rem;
  width: 48rem;
}

h3 {
  font-size: 1.75rem;
  color: #373d51;
  padding: 1.3rem;
  margin: 0;
}

.accordion a {
  position: relative;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  width: 100%;
  padding: 1rem 3rem 1rem 1rem;
  color: #7288a2;
  font-size: 1.15rem;
  font-weight: 400;
  border-bottom: 1px solid #e5e5e5;
}

.accordion a:hover,
.accordion a:hover::after {
  cursor: pointer;
  color: #03b5d2;
}

.accordion a:hover::after {
  border: 1px solid #03b5d2;
}

.accordion a.active {
  color: #03b5d2;
  border-bottom: 1px solid #03b5d2;
}

.accordion a::after {
  font-family: 'Ionicons';
  content: '\f218';
  position: absolute;
  float: right;
  right: 1rem;
  font-size: 1rem;
  color: #7288a2;
  padding: 5px;
  width: 30px;
  height: 30px;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  border: 1px solid #7288a2;
  text-align: center;
}

.accordion a.active::after {
  font-family: 'Ionicons';
  content: '\f209';
  color: #03b5d2;
  border: 1px solid #03b5d2;
}

.accordion .content {
  opacity: 0;
  padding: 0 1rem;
  max-height: 0;
  border-bottom: 1px solid #e5e5e5;
  overflow: hidden;
  clear: both;
  -webkit-transition: all 0.2s ease 0.15s;
  -o-transition: all 0.2s ease 0.15s;
  transition: all 0.2s ease 0.15s;
}

.accordion .content p {
  font-size: 1rem;
  font-weight: 300;
}

.accordion .content.active {
  opacity: 1;
  padding: 1rem;
  max-height: 100%;
  -webkit-transition: all 0.35s ease 0.15s;
  -o-transition: all 0.35s ease 0.15s;
  transition: all 0.35s ease 0.15s;
}

JS:

const items = document.querySelectorAll(".accordion a");

function toggleAccordion(){
  this.classList.toggle('active');
  this.nextElementSibling.classList.toggle('active');
}

items.forEach(item => item.addEventListener('click', toggleAccordion));

Answer №1

When you insert the code below into a code block, you'll notice several benefits:

  1. It ensures the module functions properly.
  2. All code for the module is consolidated in one place (the code block), making it easier to edit compared to dispersing HTML, CSS, and JavaScript across different locations.
  3. An icon is added to the first item by applying a specific class in the HTML (.accordion-link-info) and corresponding CSS within the <style> element.

<div class="container">
  <h2>Frequently Asked Questions</h2>
  <div class="accordion">
    <div class="accordion-item">
      <a class="accordion-link-info">Why is the moon sometimes out during the day?</a>
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elementum sagittis vitae et leo duis ut. Ut tortor pretium viverra suspendisse potenti.</p>
      </div>
    </div>
    // Additional accordion items
  </div>
</div>
<style>
// CSS styles
</style>
<script>
// JavaScript functionality
</script>

The crucial CSS portion highlighted in the code snippet above focuses on using the before pseudo-element and assigning a specific image to each link. By adding a class to each link in the HTML and setting the background image in the CSS accordingly, you can customize icons for different links:

.accordion a:before {
  content: "";
  position: absolute;
  right: 100%;
  width: 30px;
  height: 30px;
  background-size: contain;
}

.accordion-link-info:before {
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/5/58/Info_icon.png");
}

Keep in mind that the module may not display correctly in edit-mode previews, so it's recommended to test it in a separate, non-logged-in browser window.

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

Angular form array inputs

Currently delving into the world of Angular.js, I have encountered a simple problem that has left me baffled. My objective is to generate form inputs with the value of "connectedTeams" in HTML: <input type="text" name="connectedTeam[]"> <input ...

Leveraging jQuery to automatically fill in a time field while excluding other buttons

I've been working on using jQuery to automatically fill in a time input field. The functionality is working properly, but the time is also being applied to my other button. How can I make sure it only gets assigned to the time input field? I would re ...

Set up dynamic restrictions for the length of an HTML paragraph with PHP

I am attempting to dynamically set the limit of content retrieved from a database in PHP. Specifically, I need to trim the input from the database before assigning it to an HTML paragraph. I attempted to use the substr function but was unsuccessful. Can y ...

"Upon choosing a file using the HTML input file multiple element, a triggered event

After selecting multiple files using the input type="file" HTML element, I am eager to start uploading them. Can you tell me which event I should use to execute code immediately after finalizing my file selection? This is what my HTML code looks like: &l ...

Box Pattern with Pop-Up Modal

Check out the grid of squares I've coded below: <div class='square-container'> <div class='square'></div> <div class='square'></div> <div class='square'></div& ...

When a specific item is selected from a drop-down menu, text boxes and drop-downs will dynamically appear and change

In the current version of my code, there is a single drop-down menu with three options for the user to select from. If "Complete" is chosen, a text box should appear. If "Abandon" or "Transfer" is selected, a separate drop-down menu needs to be displayed. ...

Is it possible to implement formvalidation.io in a React project that is using Materialize-css?

Can the formvalidation.io plugin be used with React and Materialize-css in a project? My project consists of multiple input components that may or may not be within a form. I want to utilize formvalidation for input validation. However, I am unable to find ...

Interested in creating a weather application that changes color based on the time of day

My attempt to create a weather app with a glowing effect has hit a roadblock. I want the app to glow "yellow" between 6 and 16 hours, and "purple" outside of those hours. I have assigned classes for AM and PM elements in HTML, and styled them accordingly i ...

Is there a way to obtain the coordinates of an SVG element by simply clicking on a specific point?

I'm still learning about SVG and I'm trying to trigger an event that captures the click coordinates when clicking on the SVG. I have a few questions: Since I'm using Angular, I'm unsure if it's possible to keep my function in th ...

Tips for perfectly centering a SPAN element within a DIV both vertically and horizontally

Here is an example of my HTML code: <div id="slideClick"> <div style="padding: 0; margin: 0 auto; width: 100%; height: 100%; text-align: center; border: 1px solid blue;"> <span class="sideMsg">MESSAGES</span> </d ...

The shadow is obscured by a block that has an 'overflow: scroll' property

One block on the left displays the list, while another shows detailed information with a shadow effect. The issue arises when the left block has 'overflow: scroll', causing elements' backgrounds to spill over the shadow. .div-left { flo ...

Attempting to deactivate the bootstrap-fullscreen-select feature using JavaScript

Currently, I am in the process of developing a Python Flask server to manage a project that I have undertaken. While exploring different options, I came across bootstrap-fullscreen-select which turned out to be exactly what I needed for my control page. H ...

Guide on connecting a URL with a generated ID to the <a href> element

I am currently working on building my own portfolio website using Django. The main idea behind this project is to create posts showcasing the websites that I have developed. These posts will be featured on a page titled "Projects," where viewers can click ...

Unable to access content from a dictionary in Django templates

Currently, I am attempting to retrieve the value of the class method that returns a dictionary. The function is structured as follows: class GetData: def __init__(self, api_key, ip, interface): self.api_key = api_key self.asa_ip = ip ...

Implement a default dropdown menu that displays the current month using Angular and TypeScript

I am looking to implement a dropdown that initially displays the current month. Here is the code snippet I have used: <p-dropdown [options]="months" [filter]="false" filterBy="nombre" [showClear] ...

JavaScript event/Rails app encounters surprising outcome

I have encountered a strange bug in my JavaScript code. When I translate the page to another language by clicking on "English | Русский" using simple I18n translation, my menu buttons stop working until I reload the page. I suspect that the issue ...

Setting the height of a child tag: A step-by-step guide

When trying to set the height of a child tag to 100%, I encountered an issue where the height would remain fixed after redirecting to another page, preventing the page from scrolling. Styling for Image 1 body{ background: url("Resources/Cash.jpeg&q ...

What are some ways to ensure that text can adapt to the size of a

I am looking to create dynamic text that adjusts based on the size of its parent container. As the parent container's size changes, I want the text to automatically adjust accordingly. Specifically, I want the text in a widget to resize when the widg ...

Is it possible for an ul to be displayed beneath a white section within an li

I am working on a JQuery carousel that is displaying correctly, but I want to make a small adjustment to the content: <li class="jcarousel-item jcarousel-item-horizontal jcarousel-item-1 jcarousel-item-1-horizontal" style="float: left; list-style: none ...

Using the 'onended' audio event emitter in Angular 2 along with a local member of the Component

I'm looking for assistance on how to utilize audio.onended() in order to play the next song in a playlist. I can successfully add songs to the playlist and play them using the above method with an audioObject. However, when audio.onended triggers, I ...