CSS — расположение раскрывающегося меню

Выпадающее меню (редактировать: есть -> было) выходило за пределы экрана (по ширине), после исправления я хотел бы знать, как лучше контролировать его положение и как сделать так, чтобы его положение не было 'не относительно div(.top-menu), а кнопки раскрывающегося списка.

Я в значительной степени новичок в CSS и HTML в целом, в основном я не понимаю значений позиции/отображения, но это не главное. По сути, я читал документацию W3School, я думаю? Я увидел страницу Горизонтальная панель навигации и решил изменить то, как я это делал раньше (используя 1 большой элемент div для всего меню, а затем маленькие элементы div внутри). После этого я попытался создать раскрывающееся меню, просто скопировав, как они это сделали, и заметил проблему: как было сказано ранее, раскрывающееся меню выходит за пределы ширины экрана, а также некоторые другие проблемы.

CSS:

.top-menu {
  height: 1lh;
  width: 100%;
  background-color: cadetblue;
  position: fixed;
  top: 0%;
  left: 0%;
  text-align: end;
  line-height: 6;
}

.top-menu a {
  padding-right: 25px;
  font-family: sans-serif;
}
ul.navbar {
  float: right;
  list-style-type: none;
  margin: 0;
  padding-right: 10px;
  width: auto;
}

li {
  display: inline;
  padding: 10px 12px;
  background-color: #dddddd;
}

.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #BBBBBB;
  min-width: 160px;
  max-width: 100vw;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  padding: 12px;
  z-index: 1;
  right: 0;
  top: 100%;
  box-sizing: border-box;
  transform: translateX(10%);
}

.dropdown:hover .dropdown-content {
  display: block;
  width: fit-content;
  text-align: center;
}

HTML

    <div id = "top-menu" class = "top-menu">
      <ul class = "navbar">
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
        <li>e</li>
        <li>
          <div class = "dropdown">
            <span>Mouse over me</span>
            <div class = "dropdown-content">
              <p>Hello World!</p>
            </div>
          </div>
        </li>
      </ul>
    </div>

Еще есть некоторый JS-код, который я скопировал из

Проблема переполнения (вроде как) исправлена, по сути вопрос в том, как мне контролировать его положение (кроме translateX(), потому что я хочу, чтобы оно было выровнено), ширину/высоту. Также я хотел бы знать; Я заметил top: 0%; и увидел, что меню на самом деле позиционируется относительно всей верхней панели, а не кнопки раскрывающегося списка. Есть ли какое-нибудь исправление?

«Раскрывающееся меню выходит за пределы экрана (по ширине)». Думаю, я не вижу этого здесь, я что-то упускаю?

Mark Schultheiss 22.08.2024 01:07

Да, извините, я исправляю проблему, пока пишу вопрос, а в итоге получается вот так.

user23546251 22.08.2024 01:08
Улучшение производительности загрузки с помощью 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
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Измените display: inline-block; на display: inline;. В результате div.dropdown будет занимать столько же места, сколько и его дети. Таким образом, раскрывающийся список появится у нижнего края «Наведите курсор мыши на меня».

<!DOCTYPE html>
<html>

<head>
    <style>
        .top-menu {
            height: 1lh;
            width: 100%;
            background-color: cadetblue;
            position: fixed;
            top: 0%;
            left: 0%;
            text-align: end;
            line-height: 6;
        }

        .top-menu a {
            padding-right: 25px;
            font-family: sans-serif;
        }

        .test {
            margin: auto;
            position: absolute;
            text-align: center;
            top: 40%;
            left: 40%;
            color: whitesmoke;
            background-color: blue;
            border: 1px solid black;
            width: 100px;
            padding: 20px 10px;
        }

        ul.navbar {
            float: right;
            list-style-type: none;
            margin: 0;
            padding-right: 10px;
            width: auto;
        }

        li {
            display: inline;
            padding: 10px 12px;
            background-color: #dddddd;
        }

        .dropdown {
            position: relative;
            display: inline;
        }

        .dropdown-content {
            display: none;
            position: absolute;
            background-color: #BBBBBB;
            min-width: 160px;
            max-width: 100vw;
            box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
            padding: 12px;
            z-index: 1;
            right: 0;
            top: 100%;
            box-sizing: border-box;
            transform: translateX(10%);

        }

        .dropdown:hover .dropdown-content {
            display: block;
            width: fit-content;
            text-align: center;
        }
    </style>
</head>

<body>
    <div id = "top-menu" class = "top-menu">
        <ul class = "navbar">
            <li>a</li>
            <li>b</li>
            <li>c</li>
            <li>d</li>
            <li>e</li>
            <li>
                <div class = "dropdown">
                    <span>Mouse over me</span>
                    <div class = "dropdown-content">
                        <p>Hello World!</p>
                    </div>
                </div>
            </li>
        </ul>
    </div>
</body>

</html>

Для меня это не работает. Полагаю, частично из-за минимальной ширины, но я не против ширины, она все равно совпадает с большим элементом div.

user23546251 22.08.2024 01:22

@user23546251 user23546251 Я только что добавил фрагмент кода, который вы опубликовали, с display: inline-block; измененным на display: inline;, и он работает по назначению. Возможно, на вашей странице есть конфликтующие стили.

EricFrancis12 22.08.2024 02:21

У меня это работает так после добавления поля: 0; и верх: 155%. imgur.com/a/angxBMS (и, конечно, встроенный). Кроме того, не могли бы вы объяснить, что делает это изменение? @EricFrancis12

user23546251 22.08.2024 02:26
Ответ принят как подходящий

Две вещи для обновления:

  • Отступы, добавляемые к элементам <li>, влияют на выравнивание/позиционирование элемента .dropdown-content. .dropdown-content необходимо учитывать это при позиционировании.
  • На дисплее .dropdown должно быть inline.

Рабочий пример:

Я изменил только блоки .dropdown и .dropdown-content:

.top-menu {
  height: 1lh;
  width: 100%;
  background-color: cadetblue;
  position: fixed;
  top: 0%;
  left: 0%;
  text-align: end;
  line-height: 6;
}

.top-menu a {
  padding-right: 25px;
  font-family: sans-serif;
}
ul.navbar {
  float: right;
  list-style-type: none;
  margin: 0;
  padding-right: 10px;
  width: auto;
}

li {
  display: inline;
  padding: 10px 12px;
  background-color: #dddddd;
  box-sizing: border-box;
}

.dropdown {
  position: relative;
  display: inline;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #BBBBBB;
  min-width: 160px;
  max-width: 100vw;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  padding: 12px;
  z-index: 1;
  right: -12px;
  top: calc(100% + 10px);
  box-sizing: border-box;
}

.dropdown:hover .dropdown-content {
  display: block;
  width: fit-content;
  text-align: center;
}
<div id = "top-menu" class = "top-menu">
    <ul class = "navbar">
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
        <li>e</li>
        <li>
            <div class = "dropdown">
                <span>Mouse over me</span>
                <div class = "dropdown-content">
                    <p>Hello World!</p>
                </div>
            </div>
        </li>
    </ul>
</div>

Лучший подход:

Лучше, если вы добавите отступы не к элементам <li>, а к дочерним элементам внутри <li> элементов. Тогда вам будет легче выровнять раскрывающийся список. См. пример ниже.

Примечание. Я обновил CSS, чтобы использовать flex-box (более современный подход). Вы можете просто сосредоточиться на том, как я изменил место применения отступов. Это все равно будет применяться к вашему исходному коду.

.top-menu {
  
  /* css variable to keep padding consistent */
  --navbar-item-padding: 10px 12px;

  height: 100px;
  
  /* align children to the right */
  display: flex;
  justify-content: end;
  
  /* make nav 'sticky' to top */
  position: fixed;
  top: 0;
  left: 0;
  
  width: 100%;
  background-color: cadetblue;
}

.top-menu a {
  text-decoration: none;
  padding: var(--navbar-item-padding);
}

ul.navbar {
  /* display children in a row (horizontally) */
  display: flex;
  flex-direction: row;
  align-items: center; /* remove if you want items to take full height */
  
  list-style-type: none;
  margin: 0;
}

li {
  /* vertically center content of li */
  display: flex;
  align-items: center;
  
  margin-right: 10px; /* use margin instead of padding so it does not modify the actual li's width */
  background-color: #dddddd;
}

.dropdown {
  position: relative; /* required for children to use absolute positioning */
}

.dropdown .dropdown-label {
  /* pad the label iteself so that we don't add padding to the parent, thus the .dropdown-content element can be positioned accurately */
  padding: var(--navbar-item-padding); 
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #BBBBBB;
  min-width: 160px;
  max-width: 100vw;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  padding: 12px;
  z-index: 1;
  top: 100%; /* move down an amount equal to 100% of the parent element's height */ 
  right: 0;  /* align right edge with right edge of parent */
  /* left: 0; /* align left edge with left edge of parent */
  box-sizing: border-box;
}

.dropdown:hover .dropdown-content {
  display: block;
  text-align: center;
}
 <div id = "top-menu" class = "top-menu">
      <ul class = "navbar">
        <li><a href = "#">a</a></li>
        <li><a href = "#">b</a></li>
        <li><a href = "#">c</a></li>
        <li><a href = "#">d</a></li>
        <li><a href = "#">e</a></li>
        <li>
          <div class = "dropdown">
            <div class = "dropdown-label">Mouse over me</div>
            <div class = "dropdown-content">
              <p>Hello World!</p>
            </div>
          </div>
        </li>
      </ul>
    </div>

Я бы сказал, что это работает лучше всего и полностью отвечает на вопрос. Я хотел бы отметить одну вещь: все символы li занимают всю высоту навигационной панели. Полагаю, это потому, что высота навигационной панели = 1lh; высота строки равна 6, поэтому она занимает всю строку. Как бы вы изменили это, чтобы у символов li было мало неокрашенного пространства (поля?) сверху и снизу? Также спасибо за ответ, очень признателен. Если мой английский слишком плох, вот это визуально.

user23546251 22.08.2024 15:47

Добавлена ​​определенная высота в .top-menu css и align-items: center в ul.navbar css. Теперь у .top-menu есть своя определенная высота (больше не зависящая от его дочерних элементов), и все дочерние элементы выровнены по вертикали. Если вы удалите align-items: center из .ul.navbar, элементы снова займут полную высоту.

Drew Harvey 22.08.2024 19:02

Работает как шарм. Большое спасибо! Я многому научился из этого поста, а еще он выглядит вот так сейчас. Я добавил некоторые отступы к элементам и установил содержимое раскрывающегося списка top: 151%; left: -49%, и теперь я бы сказал, что это идеально. Конечно, цифры немного странные (и я не понимаю почему), но, по крайней мере, это работает. Спасибо еще раз

user23546251 22.08.2024 23:23

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