如何让我的汉堡包菜单直接出现在我的汉堡包图标下方?
How do I make my hamburger menu appear directly under my hamburger icon?
我想单击汉堡菜单图标,然后在我的图标下方显示列表。我用这种风格设置了我的汉堡包菜单图标
.menu-btn div {
position: absolute;
left: 100%;
top: 64%;
padding-right: 8px;
margin-top: -0.50em;
line-height: 1.2;
font-size: 18px;
font-weight: 200;
vertical-align: middle;
z-index: 99;
}
.menu-btn span {
display: block;
width: 20px;
height: 2px;
margin: 4px 0;
background: #989da1;
z-index: 99;
}
点击汉堡菜单后应该出现的选项菜单是
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
但我不清楚如何设置汉堡菜单的样式,以便在您单击它时它直接出现在汉堡菜单下方。现在,它出现在屏幕顶部的中央——https://jsfiddle.net/wtp1k57b/1/。怎么设置这样的样式?
PS - 我正在寻找一种不依赖硬编码数字(例如顶部:27px)像素值的解决方案。在我的小 Fiddle 中让事情正常工作当然很好,但在我更广泛的应用程序中,我无法保证汉堡包菜单的大小。
使用 css
属性:top
和 right
设置图标下元素的位置。
#menu
{
position: absolute;
top: 48px;
right: 2px;
background: #ededed;
list-style-type: none;
}
将此 CSS 用于您的菜单 - 无边距,位置由 top
和 right
设置定义:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 50px;
right: 0;
}
https://jsfiddle.net/meuexde6/
我省略了测试的过渡,但您基本上应该将 right
参数从 -100px 设置为 0 以实现您似乎想要的效果。
评论后添加:
要定义菜单相对于按钮的位置,您必须将 position: relative
应用于它们的公共父元素 .mobile-nav
。具有 position: absolute
的元素的位置值始终与具有 position: relative
.
的第一个祖先相关
我根据这些更改了更新后 fiddle 中的值:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 40px;
right: -32px;
}
已更新 fiddle:https://jsfiddle.net/meuexde6/1/
如果您真的希望菜单直接贴在按钮上(很难说 - 它没有边框),只需根据需要调整 top
和 right
值即可。
那么,开始吧。我知道您正在寻求针对特定问题的解决方案,我很好地解决了它,但我不禁注意到您正在为自己的代码而苦苦挣扎。你必须简化你的思维方式,你的代码才会变得更精简。这个论坛的目的是帮助别人变得更好,对吧? :)
HTML
将菜单切换按钮保留在菜单外部是一种很好的做法 - 将解决很多问题 - 请查看下方内容。
除了 button
之外,使用其他任何东西作为切换功能在语义上都是不正确的,那么,为什么不在这里使用 button
呢?我还从您的代码中删除了不必要的混乱,例如一些 div
和 id
- id
可以与您的调用 class
进行交易。我还删除了 .mobile-nav
,因为根本不需要它。
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
CSS
我将 menu-btn
绝对定位在右上角,并给它一个 width
等于 #pageTitle
height
(我设置为 50px - a黄金标准)以保持矩形;根据经验,切换按钮是矩形的,并且始终与顶部导航栏的高度相同 - 在本例中为前面提到的 id
。我对 .responsive-menu
所做的也是如此。我绝对定位它如下所示。这些更改使我能够删除很多 css 样式 - 现在已过时 - 例如 ul
菜单在 .responsive-menu
中的绝对定位.
.menu-btn {
position:absolute;
display:block;
right:0;
top:0;
width:50px;
height:50px;
background:yellow;
border:none;
padding:16px;
}
.responsive-menu {
position: absolute;
top: 50px;
right: 0;
display: none;
}
Javascript
通过多年的实践,我意识到切换菜单而不是添加和删除 类 的最有效方法是在 body
标签上添加一个 class
;如果您想根据菜单是否打开来重新设置页面上其他任何内容的样式,这可以帮助解决问题。
$('.menu-btn').on('click', function() {
$('body').toggleClass('responsive-menu-open');
});
这是一个有效的 jsfiddle:https://jsfiddle.net/scooterlord/4atafhge/
我本可以做很多其他事情来进一步简化代码——删除不必要的 ID 和 类 因为大多数元素被认为是唯一的并且可以使用后代 类 来定位,例如 .responsive-menu ul
,等。经过大量练习,您将设法更简单地思考并生成占用空间更小的代码。
编辑:关于您不喜欢 绝对 像素对齐的事实,这是一个技巧。
为父容器提供一个固定的 height
,等于切换按钮的 - 在本例中为“#pageTitle”并将其位置设置为 relative
允许您使用 top:100%
将响应式菜单正确放置在按钮正下方(高度基本相同):
#pageTitle {
display: flex;
height: 50px;
position:relative;
}
.responsive-menu {
position: absolute;
top: 100%;
right: 0;
display: none;
}
这是更新后的 fiddle:https://jsfiddle.net/scooterlord/4atafhge/1/
编辑:娜塔莉亚,我想了想,这就是我的想法。我创建了一个绝对定位的 .menu-wrapper
,在其中我放置了带有 float:right
的按钮和响应菜单并且没有定位 - 即它们是静态定位的。没有更多的像素值!耶!
.menu-wrapper {
position:absolute;
top:0;
right:0;
}
.menu-btn {
float:right;
...
}
.responsive-menu {
float:right;
clear:both; // to clear the .menu-btn and sit exactly below it
...
}
这是一个有效的 fiddle:https://jsfiddle.net/scooterlord/4atafhge/2/
HTML5 个语义元素。
details > summary {
padding: 2px 6px;
width:12px;
border: none;
list-style: none;
}
details > summary::-webkit-details-marker {
display: none;
}
ul{
list-style: none;
margin-left:0;
padding-left:0;
}
<details>
<summary>☰</summary>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</details>
我想展示一种完全不同的方法而不使用 display: flex
。
HTML
在我看来,您的方法使用了太多包装器。你绝对可以减少 divs
的数量。此外,您应该始终尝试使用语义标签而不是 div
或 ul
等一般标签。考虑查看 this 文章。
因此,正如 已经提到的,您应该使用 button
作为汉堡包图标。此外,我建议使用 nav
而不是列表。
CSS
首先,为了提高清晰度,您应该将同一选择器的属性捆绑在同一位置。您不应该在应用通用选择器的地方分三个部分,而应该将它们合二为一。此外,不要将 box-sizing
设置为特定值,而是将其设置为 inherit
,因此您始终可以为特定元素覆盖此值,而不必为其所有子元素都这样做。此外,我不明白你想在所有元素上使用 margin: 0 auto
和 body
来实现什么。这对我来说没有任何意义。
既然你不想使用绝对定位,我强烈建议你避免使用像素作为测量单位。如果某些人因为视力不佳或其他原因而更改默认值 font-size
,他们就会表现得很糟糕。相反,请考虑应用 rem
、em
或 %
等相对单位。通过将根元素的 font-size
设置为 62.5%
,您仍然可以像使用像素一样进行计算 (1rem = 10px)。
正如我已经提到的,我避免将 display: flex
用于这种微不足道的事情。我不明白为什么此时要使用它。因此,我也不得不改变菜单按钮的位置。使用 top
和 left
.
的百分比可以轻松定位导航
附带说明:您真的应该尝试只 post 相关的 CSS 代码——对我来说,第一步是删除所有不相关的部分。
最终解决方案
这是我最终的解决方案,没有 Flexbox,没有固定大小,也没有使用 px
:
的绝对定位
$('.menu-btn').click(function() {
$('nav').toggleClass('nav-open');
});
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%;
}
body {
font: 1.6rem/1.4 Benton Sans, -apple-system, BlinkMacSystemFont, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
header {
width: 100%;
background-color: orange;
text-align: center;
padding: 1rem;
position: relative;
}
nav {
display: none;
width: 30rem;
padding: 5rem;
background-color: #ededed;
position: absolute;
right: 5%;
top: 100%;
}
.nav-open {
display: block;
}
nav a {
display: block;
width: 100%;
text-align: center;
padding: 1.4rem 1.6rem;
text-decoration: none;
cursor: pointer;
font-size: 2.2rem;
color: #000;
}
nav a:hover {
background-color: #111;
color: #fff;
}
.menu-btn {
position: absolute;
right: 5%;
top: 50%;
margin-top: -1.1rem;
display: inline-block;
cursor: pointer;
border: none;
outline: none;
background-color: transparent;
}
@media only screen and (min-width: 500px) {
.menu-btn, nav {
display: none !important;
}
}
.menu-btn span {
display: block;
width: 2rem;
height: 0.2rem;
margin: 0.4rem 0;
background: #989da1;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h2>Page Title</h2>
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<nav>
<a href="vote.html">Vote</a>
<a href="search.html">Search</a>
<a href="about.html">About</a>
<a href="login.html">Log In</a>
</nav>
</header>
或参见this fiddle。
我想单击汉堡菜单图标,然后在我的图标下方显示列表。我用这种风格设置了我的汉堡包菜单图标
.menu-btn div {
position: absolute;
left: 100%;
top: 64%;
padding-right: 8px;
margin-top: -0.50em;
line-height: 1.2;
font-size: 18px;
font-weight: 200;
vertical-align: middle;
z-index: 99;
}
.menu-btn span {
display: block;
width: 20px;
height: 2px;
margin: 4px 0;
background: #989da1;
z-index: 99;
}
点击汉堡菜单后应该出现的选项菜单是
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
但我不清楚如何设置汉堡菜单的样式,以便在您单击它时它直接出现在汉堡菜单下方。现在,它出现在屏幕顶部的中央——https://jsfiddle.net/wtp1k57b/1/。怎么设置这样的样式?
PS - 我正在寻找一种不依赖硬编码数字(例如顶部:27px)像素值的解决方案。在我的小 Fiddle 中让事情正常工作当然很好,但在我更广泛的应用程序中,我无法保证汉堡包菜单的大小。
使用 css
属性:top
和 right
设置图标下元素的位置。
#menu
{
position: absolute;
top: 48px;
right: 2px;
background: #ededed;
list-style-type: none;
}
将此 CSS 用于您的菜单 - 无边距,位置由 top
和 right
设置定义:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 50px;
right: 0;
}
https://jsfiddle.net/meuexde6/
我省略了测试的过渡,但您基本上应该将 right
参数从 -100px 设置为 0 以实现您似乎想要的效果。
评论后添加:
要定义菜单相对于按钮的位置,您必须将 position: relative
应用于它们的公共父元素 .mobile-nav
。具有 position: absolute
的元素的位置值始终与具有 position: relative
.
我根据这些更改了更新后 fiddle 中的值:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 40px;
right: -32px;
}
已更新 fiddle:https://jsfiddle.net/meuexde6/1/
如果您真的希望菜单直接贴在按钮上(很难说 - 它没有边框),只需根据需要调整 top
和 right
值即可。
那么,开始吧。我知道您正在寻求针对特定问题的解决方案,我很好地解决了它,但我不禁注意到您正在为自己的代码而苦苦挣扎。你必须简化你的思维方式,你的代码才会变得更精简。这个论坛的目的是帮助别人变得更好,对吧? :)
HTML
将菜单切换按钮保留在菜单外部是一种很好的做法 - 将解决很多问题 - 请查看下方内容。
除了 button
之外,使用其他任何东西作为切换功能在语义上都是不正确的,那么,为什么不在这里使用 button
呢?我还从您的代码中删除了不必要的混乱,例如一些 div
和 id
- id
可以与您的调用 class
进行交易。我还删除了 .mobile-nav
,因为根本不需要它。
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
CSS
我将 menu-btn
绝对定位在右上角,并给它一个 width
等于 #pageTitle
height
(我设置为 50px - a黄金标准)以保持矩形;根据经验,切换按钮是矩形的,并且始终与顶部导航栏的高度相同 - 在本例中为前面提到的 id
。我对 .responsive-menu
所做的也是如此。我绝对定位它如下所示。这些更改使我能够删除很多 css 样式 - 现在已过时 - 例如 ul
菜单在 .responsive-menu
中的绝对定位.
.menu-btn {
position:absolute;
display:block;
right:0;
top:0;
width:50px;
height:50px;
background:yellow;
border:none;
padding:16px;
}
.responsive-menu {
position: absolute;
top: 50px;
right: 0;
display: none;
}
Javascript
通过多年的实践,我意识到切换菜单而不是添加和删除 类 的最有效方法是在 body
标签上添加一个 class
;如果您想根据菜单是否打开来重新设置页面上其他任何内容的样式,这可以帮助解决问题。
$('.menu-btn').on('click', function() {
$('body').toggleClass('responsive-menu-open');
});
这是一个有效的 jsfiddle:https://jsfiddle.net/scooterlord/4atafhge/
我本可以做很多其他事情来进一步简化代码——删除不必要的 ID 和 类 因为大多数元素被认为是唯一的并且可以使用后代 类 来定位,例如 .responsive-menu ul
,等。经过大量练习,您将设法更简单地思考并生成占用空间更小的代码。
编辑:关于您不喜欢 绝对 像素对齐的事实,这是一个技巧。
为父容器提供一个固定的 height
,等于切换按钮的 - 在本例中为“#pageTitle”并将其位置设置为 relative
允许您使用 top:100%
将响应式菜单正确放置在按钮正下方(高度基本相同):
#pageTitle {
display: flex;
height: 50px;
position:relative;
}
.responsive-menu {
position: absolute;
top: 100%;
right: 0;
display: none;
}
这是更新后的 fiddle:https://jsfiddle.net/scooterlord/4atafhge/1/
编辑:娜塔莉亚,我想了想,这就是我的想法。我创建了一个绝对定位的 .menu-wrapper
,在其中我放置了带有 float:right
的按钮和响应菜单并且没有定位 - 即它们是静态定位的。没有更多的像素值!耶!
.menu-wrapper {
position:absolute;
top:0;
right:0;
}
.menu-btn {
float:right;
...
}
.responsive-menu {
float:right;
clear:both; // to clear the .menu-btn and sit exactly below it
...
}
这是一个有效的 fiddle:https://jsfiddle.net/scooterlord/4atafhge/2/
HTML5 个语义元素。
details > summary {
padding: 2px 6px;
width:12px;
border: none;
list-style: none;
}
details > summary::-webkit-details-marker {
display: none;
}
ul{
list-style: none;
margin-left:0;
padding-left:0;
}
<details>
<summary>☰</summary>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</details>
我想展示一种完全不同的方法而不使用 display: flex
。
HTML
在我看来,您的方法使用了太多包装器。你绝对可以减少 divs
的数量。此外,您应该始终尝试使用语义标签而不是 div
或 ul
等一般标签。考虑查看 this 文章。
因此,正如 button
作为汉堡包图标。此外,我建议使用 nav
而不是列表。
CSS
首先,为了提高清晰度,您应该将同一选择器的属性捆绑在同一位置。您不应该在应用通用选择器的地方分三个部分,而应该将它们合二为一。此外,不要将 box-sizing
设置为特定值,而是将其设置为 inherit
,因此您始终可以为特定元素覆盖此值,而不必为其所有子元素都这样做。此外,我不明白你想在所有元素上使用 margin: 0 auto
和 body
来实现什么。这对我来说没有任何意义。
既然你不想使用绝对定位,我强烈建议你避免使用像素作为测量单位。如果某些人因为视力不佳或其他原因而更改默认值 font-size
,他们就会表现得很糟糕。相反,请考虑应用 rem
、em
或 %
等相对单位。通过将根元素的 font-size
设置为 62.5%
,您仍然可以像使用像素一样进行计算 (1rem = 10px)。
正如我已经提到的,我避免将 display: flex
用于这种微不足道的事情。我不明白为什么此时要使用它。因此,我也不得不改变菜单按钮的位置。使用 top
和 left
.
附带说明:您真的应该尝试只 post 相关的 CSS 代码——对我来说,第一步是删除所有不相关的部分。
最终解决方案
这是我最终的解决方案,没有 Flexbox,没有固定大小,也没有使用 px
:
$('.menu-btn').click(function() {
$('nav').toggleClass('nav-open');
});
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%;
}
body {
font: 1.6rem/1.4 Benton Sans, -apple-system, BlinkMacSystemFont, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
header {
width: 100%;
background-color: orange;
text-align: center;
padding: 1rem;
position: relative;
}
nav {
display: none;
width: 30rem;
padding: 5rem;
background-color: #ededed;
position: absolute;
right: 5%;
top: 100%;
}
.nav-open {
display: block;
}
nav a {
display: block;
width: 100%;
text-align: center;
padding: 1.4rem 1.6rem;
text-decoration: none;
cursor: pointer;
font-size: 2.2rem;
color: #000;
}
nav a:hover {
background-color: #111;
color: #fff;
}
.menu-btn {
position: absolute;
right: 5%;
top: 50%;
margin-top: -1.1rem;
display: inline-block;
cursor: pointer;
border: none;
outline: none;
background-color: transparent;
}
@media only screen and (min-width: 500px) {
.menu-btn, nav {
display: none !important;
}
}
.menu-btn span {
display: block;
width: 2rem;
height: 0.2rem;
margin: 0.4rem 0;
background: #989da1;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h2>Page Title</h2>
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<nav>
<a href="vote.html">Vote</a>
<a href="search.html">Search</a>
<a href="about.html">About</a>
<a href="login.html">Log In</a>
</nav>
</header>
或参见this fiddle。