Tips for Designing a Menu with Sliding List Animation

I’m looking to design a unique menu that functions in a specific way: as I hover over each menu item, a corresponding list should appear at the bottom of that item. Additionally, when I transition to another element, the list should smoothly slide to that new location and update its content.

https://i.sstatic.net/WAVIYWwX.png

.wrapper {
  position: relative;
}

.menu {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, min-content);
  column-gap: 30px;
  cursor: pointer;
}

.content {
  position: absolute;
  border: 1px solid grey;
}

.content-item {
  padding: 10px 12px;
  cursor: pointer;
}
<div class="wrapper">
  
  <ul class="menu">
    <li class="menu-item">ItemA</li>
    <li class="menu-item">ItemB</li>
    <li class="menu-item">ItemC</li>
  </ul>
  
  <div class="content">
    <div class="content-item">item1</div>
    <div class="content-item">item2</div>
    <div class="content-item">item3</div>
  </div>
</div>

Answer №1

For this specific menu, I chose to utilize JavaScript as it is a necessity for its functionality. Take a look at the code snippet below:

// script.js
document.addEventListener('DOMContentLoaded', () => {
    const menuItems = document.querySelectorAll('.menu li');
    const dropdown = document.getElementById('dropdown');
    
    const dropdownContent = {
        item1: ['Option A1', 'Option B1', 'Option C1'],
        item2: ['Option A2', 'Option B2', 'Option C2'],
        item3: ['Option A3', 'Option B3', 'Option C3']
    };

    menuItems.forEach(item => {
        item.addEventListener('mouseenter', (e) => {
            const dropdownList = dropdown.querySelector('ul');
            dropdownList.innerHTML = '';
            const data = dropdownContent[item.getAttribute('data-dropdown')];
            data.forEach(option => {
                const li = document.createElement('li');
                li.textContent = option;
                dropdownList.appendChild(li);
            });

            dropdown.style.display = 'block';
            const rect = item.getBoundingClientRect();
            dropdown.style.left = `${rect.left}px`;
        });

        item.addEventListener('mouseleave', () => {
            dropdown.style.display = 'none';
        });
    });

    dropdown.addEventListener('mouseenter', () => {
        dropdown.style.display = 'block';
    });

    dropdown.addEventListener('mouseleave', () => {
        dropdown.style.display = 'none';
    });
});
/* styles.css */
body {
    font-family: Arial, sans-serif;
}

.menu {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
}

.menu ul {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
}

.menu li {
    padding: 10px 20px;
    cursor: pointer;
    position: relative;
}

.dropdown {
    position: absolute;

    left: 0;
    display: none;
    width: 200px;
    background: #f9f9f9;
    border: 1px solid #ddd;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    transition: left 0.3s ease;
}

.dropdown ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.dropdown ul li {
    padding: 10px;
    cursor: pointer;
}

.dropdown ul li:hover {
    background: #f1f1f1;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <div class="wrapper">
  
    <nav class="menu">
        <ul>
            <li data-dropdown="item1" class="menu-item">Item1</li>
            <li data-dropdown="item2" class="menu-item">Item2</li>
            <li data-dropdown="item3" class="menu-item">Item3</li>
        </ul>
    </nav>
    

    <div class="dropdown" id="dropdown">
        <ul class="content">
            <li class="content-item">Option A1</li>
            <li class="content-item">Option B1</li>
            <li class="content-item">Option C1</li>
        </ul>
    </div>
</div>
</body>
</html>

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

How can CSS image hover affect the layout of other elements on the page?

When I hover over the image and it grows to 350px, it causes everything around it to shift. The code is functioning as expected, but the issue arises when the enlarged image pushes nearby elements downward. Is there a way to prevent this behavior? #disp ...

Is Chrome Facing an Autofill Glitch?

Can someone explain this strange behavior? When using Chrome, clicking on an input field triggers autocomplete for "country." However, if you change "country" to "city," the autocomplete shifts to that field instead. This issue seems to be isolated to thi ...

Change from one value to another using a decaying sinusoidal wave

Can someone help me come up with a formula that will smoothly transition from a starting value to an end value over a specified time using a Sin or Cos wave? I'm attempting to replicate a bouncing effect like the one shown in my sample using CSS and ...

I'm encountering a "confirm" error within the data table. Any suggestions on how to resolve this issue?

When I try to use two datatables columns in confirm, an error occurs when the text 'do you want cancel?' is displayed. The issue seems to be with the text itself and not the code. How should we go about fixing this problem? This is my current cod ...

Updating inner text content dynamically can be accomplished without relying on the use of the eval() function

I am faced with a situation where I have multiple batches of code structured like this: 1 <div id="backgrounds" class="centery">Backgrounds 2 <div id="bk1" class="attr">Background 1 3 <div class="container"> 4 ...

Attempting to create a discord bot using Selenium in Python for seamless integration

I am currently attempting to create a Discord bot using Selenium in Python. I have been working on the script to connect the bot to my discord account. Below are the required imports: from selenium import webdriver from selenium.webdriver.common.keys imp ...

Display of Navigation Bar in Angular is Not Proper

Currently diving into the world of Angular, I've encountered an issue with a material menu that isn't displaying correctly. The expected outcome based on my code should resemble this image: https://i.stack.imgur.com/z70Aq.png This snippet showc ...

Maintain the fixed position of the horizontal scroll bar

I'm facing an issue with a popup window that displays a frameset. Within one of the frames, I'm using jQuery tabs to show some text. The problem arises when trying to display long text or when resizing the window, causing the horizontal scroll t ...

Adjust the alignment and floating of text within an iframe on the same domain

Is it possible to align text on the right side of an iframe that contains a width and text inside? The iframe's src is from the same domain. If so, how can this be achieved through JavaScript? ...

Is there a space added after applying overflow:hidden to a div?

.d1 { height: 10px; } .dd { display: inline-block; overflow: hidden; } .dd1 { display: inline-block; } <div class="d1"> <div class="dd"></div> <div class="dd1"></div> </div> To adjust the layout so that th ...

What is the best method for adding a line break in the body of an email when we include the recipient, subject, and message?

Do you have a requirement where information needs to be sent to an end user via Gmail (preferred) and they need to click on a button in the email body to respond? The button response is set up with predefined to, subject, and body fields, but there are dif ...

Obtaining data from an external ng-repeat element

My list contains items that are being repeated using ng-repeat details. I want to be able to hover over one of the li elements and have the background of a div called background (which is outside of the ng-repeat) change to the url of the corresponding d ...

What is the process to set a Woocommerce checkout field as optional when a checkbox is marked?

I need assistance with customizing the checkout page on Wordpress Woocommerce. Specifically, I want to make the field 'billing_name' not required if the checkbox 'buy_on_company' is checked. Currently, I have successfully hidden ' ...

What could be causing the unexpected gap between the first two elements and the third in my flexbox layout?

I am facing an issue with the layout of my third child element. Instead of appearing below the first two children, it is wrapping around to the bottom of the container. Can anyone explain why this is happening and suggest a solution? Even though I have se ...

Safari browser is experiencing issues with the custom file upload script

My custom upload script allows users to easily select images for upload by clicking or dragging them into the designated box. A preview of the chosen image should appear, and this functionality works smoothly in Firefox and Chrome. However, I've encou ...

What is the best method for creating a distinctive identifier in HTML and jQuery?

Coding in HTML: @foreach($permission->childs as $subMenu) <tr> <td>{{$subMenu -> id}}</td> <td> &nbsp; &nbsp;{{$subMenu -> display_name}}</td> <td ...

Unable to Toggle the 'Checked' Prop on Selection with React Bootstrap CheckBox

As a newcomer to React Bootstrap, I've been encountering an irritating problem with checkboxes in a form I'm developing. After updating the state, the checkboxes don't remain checked when selected. However, if I check them again, they stay ...

What is the reason behind the functionality of inline-block?

As a beginner in html and css, I am facing an issue with displaying two h3 elements on the same line. I have tried using display:inline-block, but it's not working as expected. You can check out an example on jsfiddle here. I have provided 4 different ...

Utilize Angular to initiate the transmission of attribute values upon a click event

My question may be simple, but I've been struggling to find an answer. How can I send attributes or item property bindings of an item through a click event in the best way? For example: <item class="item" [attr.data-itemid]="item.id ...

What is the best way to deactivate the second selection option?

<select id="title0"> <option value="0">--- disable</option> <option value="1"> books</option> </select> <button id="save" type="submit">Save</button> <select id="title1"> <option value="0"& ...