Я создал простое гамбургер-меню. Базовый макет веб-сайта должен использовать сетку. Меню работает нормально, но когда вы уменьшаете размер окна браузера и появляется значок гамбургера, нажатие на него приводит к тому, что меню перекрывает нижнюю половину значка гамбургера.
"use strict";
// Hamburger navigation
const menuToggle = document.querySelector(".menu-toggle");
const nav = menuToggle.parentElement;
menuToggle.addEventListener("click", event => {
event.preventDefault();
nav.classList.toggle("open");
});
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
.grid-container {
display: grid;
grid-gap: 10px;
grid-template-areas:
"header"
"nav"
}
header {
grid-area: header;
}
.nav {
grid-area: nav;
position: relative;
}
/* Hamburger icon */
.menu-toggle {
position: absolute;
right: 0;
top: 50%;
width: 80px;
height: 80px;
cursor: pointer;
transform: translateY(-50%);
}
.hamburger {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hamburger,
.hamburger::before,
.hamburger::after {
position: absolute;
content: "";
height: 3px;
width: 30px;
background: #0c0c0c;
border-radius: 0.5626em;
transition: all .4s ease-in-out;
}
.hamburger::before {
top: -8px;
}
.hamburger::after {
top: 8px;
}
/* Hamburger animation */
.nav.open .hamburger {
background: rgba(0, 0, 0, 0);
}
.nav.open .hamburger::before {
top: 0;
transform: rotate(45deg);
}
.nav.open .hamburger::after {
top: 0;
transform: rotate(135deg);
}
/* Dropdown */
.menu-dropdown {
position: absolute;
max-height: 0;
top: 100%;
width: 100%;
background: #fff;
overflow: hidden;
transition: max-height 0.6s ease-in-out;
}
.nav-menu {
white-space: nowrap;
list-style: none;
padding: 0;
margin: 0;
}
.nav-menu > li + li {
margin-top: 0;
border-top: 1px solid #ccc;
}
.nav-menu > li > a {
display: block;
font-size: 1.3rem;
padding: .8em .5em;
text-decoration: none;
text-transform: uppercase;
}
.nav.open .menu-dropdown {
max-height: 100vh;
}
@media (min-width: 52em) {
.grid-container {
grid-template-columns: minmax(300px, 800px);
justify-content: center;
}
.tags {
grid-template-columns: repeat(3, 1fr);
}
.menu-toggle {
display: none;
}
.menu-dropdown {
position: initial;
overflow: initial;
max-height: initial;
}
.nav-menu {
display: flex;
justify-content: center;
}
.nav-menu > li + li {
margin-left: 2.3em;
border-top: initial;
}
}
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link rel = "stylesheet" href = "style.css">
<script src = "script.js" defer></script>
<title>Menu</title>
</head>
<body>
<div class = "grid-container">
<header>
Header
</header>
<nav class = "nav">
<div class = "menu-toggle">
<div class = "hamburger"></div>
</div>
<div class = "menu-dropdown">
<ul class = "nav-menu">
<li><a href = "#">Home</a></li>
<li><a href = "#">About Us</a></li>
<li><a href = "#">Services</a></li>
<li><a href = "#">Prices</a></li>
<li><a href = "#">Contact</a></li>
</ul>
</div> <!-- / .menu-dropdown -->
</nav> <!-- / .nav -->
</div>
</body>
</html>
Есть идеи, что может быть причиной того, что меню закрывает половину значка гамбургера? Я потратил больше получаса, пробуя разные варианты, но так и не смог разобраться. Меню должно открыться прямо под значком гамбургера.
Вот еще одна версия, которая работает:
"use strict";
// Hamburger navigation
const menuToggle = document.querySelector(".menu-toggle");
const nav = menuToggle.parentElement;
menuToggle.addEventListener("click", event => {
event.preventDefault();
nav.classList.toggle("open");
});
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
.header {
height: 100px;
background: #fff;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
}
.header-container {
position: relative;
height: 100%;
max-width: 1200px;
margin: 0 auto;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Hamburger icon */
.menu-toggle {
position: absolute;
right: 0;
top: 50%;
width: 80px;
height: 80px;
cursor: pointer;
transform: translateY(-50%);
}
.hamburger {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hamburger,
.hamburger::before,
.hamburger::after {
position: absolute;
content: "";
height: 3px;
width: 30px;
background: #0c0c0c;
border-radius: 0.5626em;
transition: all .4s ease-in-out;
}
.hamburger::before {
top: -8px;
}
.hamburger::after {
top: 8px;
}
/* Hamburger animation */
.nav.open .hamburger {
background: rgba(0, 0, 0, 0);
}
.nav.open .hamburger::before {
top: 0;
transform: rotate(45deg);
}
.nav.open .hamburger::after {
top: 0;
transform: rotate(135deg);
}
/* Dropdown */
.menu-dropdown {
position: absolute;
max-height: 0;
top: 100%;
width: 100%;
background: #fff;
overflow: hidden;
transition: max-height 0.6s ease-in-out;
}
.nav-menu {
white-space: nowrap;
list-style: none;
padding: 0;
margin: 0;
}
.nav-menu > li + li {
margin-top: 0;
border-top: 1px solid #ccc;
}
.nav-menu > li > a {
display: block;
font-size: 1.3rem;
padding: .8em .5em;
text-decoration: none;
text-transform: uppercase;
}
.nav.open .menu-dropdown {
max-height: 100vh;
}
@media (min-width: 52em) {
.menu-toggle {
display: none;
}
.header-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
position: initial;
transform: initial;
}
.menu-dropdown {
position: initial;
overflow: initial;
max-height: initial;
}
.nav-menu {
display: flex;
justify-content: center;
}
.nav-menu > li + li {
margin-left: 2.3em;
border-top: initial;
}
}
<!DOCTYPE html>
<html lang = "en-US">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link rel = "stylesheet" href = "nav-simple.css">
<title>Hamburger Navigation</title>
</head>
<body>
<header class = "header">
<div class = "header-container">
<!-- Site logo -->
<div class = "logo">
<a href = "#">
<img src = "logo.png" alt = "logo">
</a>
</div>
<!-- Site navigation -->
<nav class = "nav">
<div class = "menu-toggle">
<div class = "hamburger"></div>
</div>
<div class = "menu-dropdown">
<ul class = "nav-menu">
<li><a href = "#">Home</a></li>
<li><a href = "#">About Us</a></li>
<li><a href = "#">Services</a></li>
<li><a href = "#">Prices</a></li>
<li><a href = "#">Contact</a></li>
</ul>
</div> <!-- / .menu-dropdown -->
</nav> <!-- / .nav -->
</div> <!-- / .header-container -->
</header>
<script src = "nav-simple.js"></script>
</body>
</html>
Учитывая, что вторая версия работает, может ли она быть связана с сеткой в первом коде?
Не меняя текущий макет, его можно исправить, добавив свойство z-index
в файл .menu-toggle
.
.menu-toggle {
z-index: 50;
}
"use strict";
// Hamburger navigation
const menuToggle = document.querySelector(".menu-toggle");
const nav = menuToggle.parentElement;
menuToggle.addEventListener("click", event => {
event.preventDefault();
nav.classList.toggle("open");
});
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
.grid-container {
display: grid;
grid-gap: 10px;
grid-template-areas:
"header"
"nav";
}
header {
grid-area: header;
}
.nav {
grid-area: nav;
position: relative;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.menu-toggle {
width: 50px;
height: 50px;
cursor: pointer;
position: relative;
z-index: 100;
}
.hamburger,
.hamburger::before,
.hamburger::after {
position: absolute;
content: "";
height: 3px;
width: 30px;
background: #0c0c0c;
border-radius: 0.5626em;
transition: all 0.4s ease-in-out;
}
.hamburger {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hamburger::before {
top: -8px;
}
.hamburger::after {
top: 8px;
}
.nav.open .hamburger {
background: rgba(0, 0, 0, 0);
}
.nav.open .hamburger::before {
top: 0;
transform: rotate(45deg);
}
.nav.open .hamburger::after {
top: 0;
transform: rotate(135deg);
}
.menu-dropdown {
position: absolute;
top: 100%;
right: 0;
width: 100%;
background: #fff;
overflow: hidden;
max-height: 0;
transition: max-height 0.6s ease-in-out;
}
.nav-menu {
white-space: nowrap;
list-style: none;
padding: 0;
margin: 0;
}
.nav-menu > li + li {
margin-top: 0;
border-top: 1px solid #ccc;
}
.nav-menu > li > a {
display: block;
font-size: 1.3rem;
padding: 0.8em 0.5em;
text-decoration: none;
text-transform: uppercase;
}
.nav.open .menu-dropdown {
max-height: 300px;
}
@media (min-width: 52em) {
.grid-container {
grid-template-columns: minmax(300px, 800px);
justify-content: center;
}
.tags {
grid-template-columns: repeat(3, 1fr);
}
.menu-toggle {
display: none;
}
.menu-dropdown {
position: initial;
overflow: initial;
max-height: initial;
}
.nav-menu {
display: flex;
justify-content: center;
}
.nav-menu > li + li {
margin-left: 2.3em;
border-top: initial;
}
}
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link rel = "stylesheet" href = "style.css">
<script src = "script.js" defer></script>
<title>Menu</title>
</head>
<body>
<div class = "grid-container">
<header>
Header
</header>
<nav class = "nav">
<div class = "menu-toggle">
<div class = "hamburger"></div>
</div>
<div class = "menu-dropdown">
<ul class = "nav-menu">
<li><a href = "#">Home</a></li>
<li><a href = "#">About Us</a></li>
<li><a href = "#">Services</a></li>
<li><a href = "#">Prices</a></li>
<li><a href = "#">Contact</a></li>
</ul>
</div> <!-- / .menu-dropdown -->
</nav> <!-- / .nav -->
</div>
</body>
</html>
Привет. Спасибо. Я ценю ваше время. Пожалуйста, ознакомьтесь со второй версией. Я обновил исходный пост. Почему этого не происходит в этом? И у меня нет запаса или z-индекса?
Во втором примере вместо сетки используется flexbox. Работает ли он так, как вы хотите?
Второй работает, но мне нужен первый для работы с сеткой.
Большое спасибо. Я ценю вашу помощь. Я проверю код завтра, так как сейчас уже поздняя ночь, и отмечу ваш ответ как лучший.
Попробуйте добавить что-то вроде margin-top: 20px;
в свой класс раскрывающегося меню.
Чтобы ответить на ваш новый вопрос, вы изменили высоту элемента, содержащего кнопку гамбургера (никогда не формулировал это так. Это умно). Изменение высоты сдвинуло элемент меню вниз.
Привет. Спасибо. Я ценю ваше время. Пожалуйста, ознакомьтесь со второй версией. Я обновил исходный пост. Почему этого не происходит в этом? А у меня нет понижения?
Да, здесь отображается значок гамбургера, но список меню должен находиться под значком.