Как создать меню с анимацией скольжения списка

Мне нужно создать меню, которое работает следующим образом: при наведении курсора на пункт меню в нижней части пункта меню появляется список. Когда я подвожу указатель мыши к другому элементу, список плавно перемещается к этому элементу и меняет элементы внутри.

.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">Item1</li>
    <li class = "menu-item">Item2</li>
    <li class = "menu-item">Item3</li>
  </ul>
  
  <div class = "content">
    <div class = "content-item">thing1</div>
    <div class = "content-item">thing1</div>
    <div class = "content-item">thing1</div>
  </div>
</div>

Поскольку списки могут иметь разную длину, а также разный текст, не могли бы вы более подробно описать, как именно должен выглядеть переход? В какой момент берется новая высота и в какой момент меняется текст. Должно ли это происходить постепенно по мере перемещения курсора к новому пункту меню, что-то вроде эффекта постепенного появления и исчезновения, или же это должно происходить внезапно, когда курсор достигает нового пункта меню?

A Haworth 12.06.2024 08:58

Я попробую объяснить. При наведении курсора на пункт меню внизу появляется список. Он выравнивается по левому краю пункта меню. Когда я перемещаю курсор на другой пункт меню, список не исчезает, а перемещается под меню к элементу, на котором находится курсор. И при этом содержимое списка плавно исчезает, а на его месте появляется новый контент. Сам контейнер списка перемещается, и его содержимое плавно меняется. Когда я выхожу из меню, список исчезает.

uiHellen 12.06.2024 10:37
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
2
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я использовал JavaScript для этого типа меню, потому что его невозможно реализовать без JavaScript. Пожалуйста, проверьте мой пример ниже:

// 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>

Спасибо. Но это не работает так, как мне нужно. Я не хочу, чтобы блок контента исчезал при наведении курсора на другой пункт меню, я хочу, чтобы он сдвигался вправо.

uiHellen 12.06.2024 08:13

@uiHellen Большое спасибо за ваше мнение. Я обновил свой ответ, пожалуйста, проверьте этот и дайте мне знать. Я думаю, это решит вашу проблему. Спасибо

Tanbir Ahmod 12.06.2024 13:46

Другие вопросы по теме