手机端浏览器里的下拉菜单实现
在浏览器里, 试图实现一个下拉菜单。
利用hover弹出
<nav>
<a class="menu-bars" href="#">Menu</a>
<ul class="menu">
<li><a href="https://google.com/">Google</a></li>
<li><a href="https://bing.com/">Bing</a></li>
</ul>
</nav>
<style>
ul.menu {
display:none;
}
nav:hover ul.menu {
display: block;
}
</style>
这在桌面端浏览器上工作没问题。
- 鼠标放在"Menu"链接上时,触发
:hover
属性。 :hover
属性会向上传递给父元素。这点很重要。nav:hover ul.menu
触发菜单显示。- 菜单作为
<nav>
的子元素,确保了nav:hover
继续有效。 - 直到鼠标离开菜单区域,导致
nav:hover
失效,进而隐藏菜单。
但在iOS上(Safari or WebView):
- 触摸屏没有
hover
这个动作 - 点击(Tap)"Menu"时,菜单可以正常弹出
- 但却无法实现菜单隐藏
Double-Tap Link Issue on iOS
这里有两个很有意思的观察结论
- 点击(Tap)产生了一个hover动作
- 这个hover动作无法自动移除
参见 The Annoying Mobile Double-Tap Link Issue
""" This is where the people at Apple might have been a bit too smart. They realized that there was a lot of functionality on the web relying on hover states and so they figured out a way to deal with that in Safari for iOS. When you touch an item on a webpage, it first triggers a hover state and then triggers the “click”. The end result is that you end up seeing styles applied using :hover for a second before the click interaction happens. It’s a little startling, but it does work. So Safari on iOS very much cares about your styles that have :hover in the selector. They aren’t simply ignored. """
利用checkbox弹出和隐藏
有人想到一个很聪明的方案。
<nav>
<label for="menu-bars">Menu</label>
<input id="menu-bars" type="checkbox">
<ul class="menu">
<li><a href="https://google.com/">Google</a></li>
<li><a href="https://bing.com/">Bing</a></li>
</ul>
</nav>
<style>
ul.menu {
display:none;
}
input#menu-bars {
display:none;
}
input#menu-bars:checked + ul.menu {
display: block;
}
</style>
- 不再利用父元素实现对菜单的控制
- 利用兄弟节点(Sibling)实现对菜单的控制
- CSS选择器
A + B
表示紧跟在A后面的B - // 选择器
A ~ B
表示跟在A后面的B(不必紧跟)
- CSS选择器
- 利用checkbox的
:checked
属性保存菜单状态 - 利用label的
for
属性响应用户的点击(Tap)