具有严格要求的可点击、可切换 css 菜单(无 js)
Clickable, toggle-able css menu with strict requirments (no js)
出于好奇,我正在尝试提供带有子菜单(无 js)的纯 css 菜单。
要求是:
- 应该能够折叠所有子菜单
- 同一时间只能显示一个子菜单
- 不使用悬停:子菜单在鼠标点击时触发
- 没有javascript
这是我到目前为止所做的:
Link 到 jsfiddle 和下面的代码片段:
// no javascript
label {
cursor: pointer;
user-select: none;
}
label:hover {
text-decoration: underline;
}
ul > li > ul {
display: none;
}
#example1,
#example2,
#example3,
#example4 {
background: #eee;
display: inline-block;
}
#example1 > li > input,
#example2 > li > input {
/*display: none;*/
}
#example1 > li > input:checked + ul,
#example2 > li > input:checked + ul {
display: block;
}
#example3 > li > input[type="radio"]:checked + input[type="checkbox"]:checked + ul {
display: block;
}
#example4:hover > li > input[type="radio"]:checked + ul {
display: block;
}
<h3>Can collapse all, <u>BUT</u> can't display a sigle submenu at the time</h3>
<ul id="example1">
<li>
<label for="categories">Category</label>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings">Settings</label>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time, <u>BUT</u> can't collapse all</h3>
<ul id="example2">
<li>
<label for="categories2">Category</label>
<input id="categories2" type="radio" name="menu">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings2">Settings</label>
<input id="settings2" type="radio" name="menu">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time <u>and</u> can collapse all, <u>BUT</u> requires more then 1 click</h3>
<ul id="example3">
<li>
<label for="categories3check">Category</label>
<input id="categories3radio" type="radio" name="menu">
<input id="categories3check" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings3check">Settings</label>
<input id="settings3radio" type="radio" name="menu">
<input id="settings3check" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time <u>and</u> can collapse all, <u>BUT</u> uses hover and if radio is selected it opens submenu on hover</h3>
<ul id="example4">
<li>
<label for="categories4radio">Category</label>
<input id="categories4radio" type="radio" name="menu">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings4radio">Settings</label>
<input id="settings4radio" type="radio" name="menu">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
我试图跳出框框思考,但 运行 没有选择。
它应该是这样的:
Link 到 jsfiddle 和下面的代码片段,其中包含大量 jQuery:
$("span").click(function() {
var display = $(this).next()[0].style.display;
$("ul > li > ul").hide();
if (display == "" || display == "none")
$(this).next().show();
else if (display == "block")
$(this).next().hide();
});
ul > li > ul {
display: none;
}
span {
user-select: none;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<span>Category</span>
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<span>Settings</span>
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
这样的子菜单功能不用js能实现吗?如果是,如何。如果不是,为什么不呢?只要只使用 html/css 且不使用 js,任何顺序的任何数量的 hack 都是可以接受的。
您可以在 label
上使用 :focus
事件来实现 切换 - 请注意,这仅在您具有 tabindex
属性时有效设置为 label
.
参见下面的演示:
label {
cursor: pointer;
user-select: none;
}
label:hover {
text-decoration: underline;
}
ul>li>ul {
display: none;
}
#example1 {
background: #eee;
display: inline-block;
}
#example1>li>input {
display: none;
}
#example1>li>label:focus~ul {
display: block;
}
label:focus {
outline: none;
}
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
这个答案建立在@kuzkuz 使用 :focus
的答案之上。非常感谢@kuzkuz。
ides 将有另一个透明的 "hider" 跨度,它显示在 :focus
上并位于菜单 link 的顶部。单击 "hider" 跨度将导致出现 "unfocus" 菜单项。
// no javascript
label {
cursor: pointer;
user-select: none;
text-decoration: underline;
}
ul>li>ul {
display: none;
position: relative;
top: -20px;
margin-top: 0;
}
#example1 {
display: inline-block;
}
#example1>li>input {
display: none;
}
#example1>li>label:focus~ul {
display: block;
}
label:focus {
outline: none;
}
label:focus + .hider {
width: 60px;
height: 20px;
display: block;
position: relative;
top: -20px;
cursor: pointer;
/* background: rgba(255,0,0,0.2); */
}
.visible {
background: rgba(255,0,0,0.2);
<h3>Invisible hider</h3>
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<span class="hider"></span>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<span class="hider"></span>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Visible hider for demonstation purposes</h3>
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<span class="hider visible"></span>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<span class="hider visible"></span>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
编辑:这里是基于这个愚蠢的概念的样式,更好看的版本:codepen
出于好奇,我正在尝试提供带有子菜单(无 js)的纯 css 菜单。
要求是:
- 应该能够折叠所有子菜单
- 同一时间只能显示一个子菜单
- 不使用悬停:子菜单在鼠标点击时触发
- 没有javascript
这是我到目前为止所做的:
Link 到 jsfiddle 和下面的代码片段:
// no javascript
label {
cursor: pointer;
user-select: none;
}
label:hover {
text-decoration: underline;
}
ul > li > ul {
display: none;
}
#example1,
#example2,
#example3,
#example4 {
background: #eee;
display: inline-block;
}
#example1 > li > input,
#example2 > li > input {
/*display: none;*/
}
#example1 > li > input:checked + ul,
#example2 > li > input:checked + ul {
display: block;
}
#example3 > li > input[type="radio"]:checked + input[type="checkbox"]:checked + ul {
display: block;
}
#example4:hover > li > input[type="radio"]:checked + ul {
display: block;
}
<h3>Can collapse all, <u>BUT</u> can't display a sigle submenu at the time</h3>
<ul id="example1">
<li>
<label for="categories">Category</label>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings">Settings</label>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time, <u>BUT</u> can't collapse all</h3>
<ul id="example2">
<li>
<label for="categories2">Category</label>
<input id="categories2" type="radio" name="menu">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings2">Settings</label>
<input id="settings2" type="radio" name="menu">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time <u>and</u> can collapse all, <u>BUT</u> requires more then 1 click</h3>
<ul id="example3">
<li>
<label for="categories3check">Category</label>
<input id="categories3radio" type="radio" name="menu">
<input id="categories3check" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings3check">Settings</label>
<input id="settings3radio" type="radio" name="menu">
<input id="settings3check" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Can display a sigle submenu at the time <u>and</u> can collapse all, <u>BUT</u> uses hover and if radio is selected it opens submenu on hover</h3>
<ul id="example4">
<li>
<label for="categories4radio">Category</label>
<input id="categories4radio" type="radio" name="menu">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label for="settings4radio">Settings</label>
<input id="settings4radio" type="radio" name="menu">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
我试图跳出框框思考,但 运行 没有选择。
它应该是这样的:
Link 到 jsfiddle 和下面的代码片段,其中包含大量 jQuery:
$("span").click(function() {
var display = $(this).next()[0].style.display;
$("ul > li > ul").hide();
if (display == "" || display == "none")
$(this).next().show();
else if (display == "block")
$(this).next().hide();
});
ul > li > ul {
display: none;
}
span {
user-select: none;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<span>Category</span>
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<span>Settings</span>
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
这样的子菜单功能不用js能实现吗?如果是,如何。如果不是,为什么不呢?只要只使用 html/css 且不使用 js,任何顺序的任何数量的 hack 都是可以接受的。
您可以在 label
上使用 :focus
事件来实现 切换 - 请注意,这仅在您具有 tabindex
属性时有效设置为 label
.
参见下面的演示:
label {
cursor: pointer;
user-select: none;
}
label:hover {
text-decoration: underline;
}
ul>li>ul {
display: none;
}
#example1 {
background: #eee;
display: inline-block;
}
#example1>li>input {
display: none;
}
#example1>li>label:focus~ul {
display: block;
}
label:focus {
outline: none;
}
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
这个答案建立在@kuzkuz 使用 :focus
的答案之上。非常感谢@kuzkuz。
ides 将有另一个透明的 "hider" 跨度,它显示在 :focus
上并位于菜单 link 的顶部。单击 "hider" 跨度将导致出现 "unfocus" 菜单项。
// no javascript
label {
cursor: pointer;
user-select: none;
text-decoration: underline;
}
ul>li>ul {
display: none;
position: relative;
top: -20px;
margin-top: 0;
}
#example1 {
display: inline-block;
}
#example1>li>input {
display: none;
}
#example1>li>label:focus~ul {
display: block;
}
label:focus {
outline: none;
}
label:focus + .hider {
width: 60px;
height: 20px;
display: block;
position: relative;
top: -20px;
cursor: pointer;
/* background: rgba(255,0,0,0.2); */
}
.visible {
background: rgba(255,0,0,0.2);
<h3>Invisible hider</h3>
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<span class="hider"></span>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<span class="hider"></span>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
<h3>Visible hider for demonstation purposes</h3>
<ul id="example1">
<li>
<label tabindex='-1' for="categories">Category</label>
<span class="hider visible"></span>
<input id="categories" type="checkbox">
<ul>
<li>cars</li>
<li>animals</li>
</ul>
</li>
<li>
<label tabindex='-1' for="settings">Settings</label>
<span class="hider visible"></span>
<input id="settings" type="checkbox">
<ul>
<li>general</li>
<li>notifications</li>
</ul>
</li>
</ul>
编辑:这里是基于这个愚蠢的概念的样式,更好看的版本:codepen