我在不丢失功能的情况下将其归结为尽可能少的代码。你必须在 Firefox 中运行它,Chrome 已经报告并确认了涉及的错误。
如果您单击第二个项目(“首先单击此处”),您将打开一个子菜单,如果您单击其中一个未选中的项目,该菜单将自动关闭。
但是,如果您单击复选框的项目,它应该保持打开状态。对于复选框,这是可行的,但是单击标签不会选中该框并关闭子列表。谁能发现,为什么会这样?
两者都与 id 和 for 结合在一起,因此它们的行为应该相同。
:root {
--menu-padding:0.5em;
--menu-checkmargin:0.5em;
--menu-checksize:1em;
}
nav ul {
position:absolute; white-space:nowrap;
display:flex; width:fit-content;
list-style-type:none; margin:0; padding:0;
}
nav ul > li:has(> a) {
padding: 0;
}
nav ul > li:has(> a) > a {
display: inline-block;
padding: var(--menu-padding);
}
nav ul li:focus-within > ul {
display: flex;
}
nav ul li:focus-within > ul:focus {
height: 0 !important;
width: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
content-visibility: hidden;
}
nav li {
position: relative;
align-items: left;
display: flex;
box-sizing: border-box;
justify-content: space-between;
line-height: 1;
padding: var(--menu-padding);
}
ul.qm-tiled {
position: relative;
text-align: left;
flex-direction: column;
white-space-collapse: collapse;
left: 0;
}
ul.qm-tiled > li:focus-within:has(ul) {
flex-direction: column;
justify-content: space-between;
}
ul.qm-tiled > li:has(> ul:focus) {
flex-direction: row;
}
ul.qm-tiled > li {
display: flex;
}
ul.qm-tiled > li > ul {
bottom: calc(-1 * var(--menu-padding));
}
ul.qm-tiled ul {
position: relative;
margin: 0 calc(-1 * var(--menu-padding));
width: auto;
}
ul.qm-tiled li:not(:has(ul)):hover:focus {
visibility: hidden;
}
ul.qm-tiled:has(> li > label) > li:not(ul.qm-tiled:has(> li > label) > li:has(> label)) {
padding-left: calc(var(--menu-checkmargin) + var(--menu-checksize) + var(--menu-padding));
}
ul.qm-tiled:has(> li > label) > li label {
padding-left: var(--menu-checkmargin);
}
ul.qm-tiled > li {
width: 100%;
}
ul.qm-tiled ul {
display: none;
position: relative;
text-align: left;
flex-direction: column;
white-space-collapse: collapse;
}
ul.qm-tiled ul > li:focus-within:has(ul) {
flex-direction: column;
justify-content: space-between;
}
ul.qm-tiled ul > li:has(> ul:focus) {
flex-direction: row;
}
ul.qm-tiled ul > li {
display: flex;
}
ul.qm-tiled ul > li > ul {
bottom: calc(-1 * var(--menu-padding));
}
ul.qm-tiled ul ul {
position: relative;
margin: 0 calc(-1 * var(--menu-padding));
width: auto;
}
ul.qm-tiled ul li:not(:has(ul)):hover:focus {
visibility: hidden;
}
ul.qm-tiled ul:has(> li > label) > li:not(ul.qm-tiled ul:has(> li > label) > li:has(> label)) {
padding-left: calc(var(--menu-checkmargin) + var(--menu-checksize) + var(--menu-padding));
}
ul.qm-tiled ul:has(> li > label) > li label {
padding-left: var(--menu-checkmargin);
}
nav input[type=checkbox], nav input[type=radio] {
display: inline-flex;
line-height: 1;
font-size: 100%;
min-width: var(--menu-checksize);
height: 0.75em;
margin: 0;
padding: 0;
}
<nav>
<ul class="qm-tiled">
<li tabindex="0">[Item 1]</li>
<li tabindex="0">[click here first]
<ul tabindex="-1">
<li tabindex="0">[Subitem]</li>
<li><input type="checkbox" id="chk22a" name="chk22a" /><label for="chk22a">[LABEL]</label></li>
</ul>
<li tabindex="0">[Item 3]</li>
</ul>
</nav>
单击 LABEL 时,首先发生的事情是向标签发送焦点事件。由于标签不可聚焦,因此事件会传递到 LI,然后传递到 UL,因为它具有 tabindex,所以它成为聚焦元素。这会导致
content-visibility: hidden
应用,此时其内容均不存在,因此复选框无法接收激活操作。
单击复选框时,它会获得焦点,而 UL 则不会。并且
content-visibility: hidden
未应用,因此复选框接收激活操作。
您可以通过以下任一方式验证这一点
content-visibility: auto
代替 content-visibility: hidden