首页 > 解决方案 > 使用焦点内的 CSS 显示嵌套列表

问题描述

我正在尝试使用 CSS 的伪类创建一个 HTML 列表,其中嵌套ul元素仅在聚焦时显示。focus-within

这个想法是,仅使用键盘选项卡(暂时忽略鼠标交互)您应该能够沿着列表项从一个到下一个焦点,并且当您关注按钮元素时,它会显示下一级列表项。那部分工作正常。但是,当您离开按钮元素时,它应该保持下一个ul可见,因为焦点应该在嵌套的第一个a元素上ul,所以嵌套ul 应该被确定为集中在其中。

ol我有它,所以当我在s上设置背景颜色时,它可以作为演示。自然状态是白色背景,但“开放”状态由红色背景显示。这工作正常:

.menu ul ul {
                background: #fff;
            }
            .menu button:focus + ul,
            .menu ul ul:focus-within {
                background: #f00;
            }
<nav class="menu">
            <ul>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li class="has-children">
                    <a href="#">Level 1</a>
                    <button>Show sub-menu for ‘Level 1’&lt;/button>
                    <ul>
                        <li class="has-children">
                            <a href="#">Level 2</a>
                            <button>Show sub-menu for ‘Level 2’&lt;/button>
                            <ul>
                                <li class="has-children">
                                    <a href="#">Level 3</a>
                                    <button>Show sub-menu for ‘Level 3’&lt;/button>
                                    <ul>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="#">Level 2</a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li class="has-children">
                    <a href="#">Level 1</a>
                    <button>Show sub-menu for ‘Level 1’&lt;/button>
                    <ul>
                        <li class="has-children">
                            <a href="#">Level 2</a>
                            <button>Show sub-menu for ‘Level 2’&lt;/button>
                            <ul>
                                <li class="has-children">
                                    <a href="#">Level 3</a>
                                    <button>Show sub-menu for ‘Level 3’&lt;/button>
                                    <ul>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="#">Level 2</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </nav>

因此,当嵌套列表变为红色时,它们是可见的,否则它们是不可见的。

但是,当我用它替换背景颜色时display: blockdisplay: none不起作用:

.menu ul ul {
                display: none;
            }
            .menu button:focus + ul,
            .menu ul ul:focus-within {
                display: block;
            }
<nav class="menu">
            <ul>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li class="has-children">
                    <a href="#">Level 1</a>
                    <button>Show sub-menu for ‘Level 1’&lt;/button>
                    <ul>
                        <li class="has-children">
                            <a href="#">Level 2</a>
                            <button>Show sub-menu for ‘Level 2’&lt;/button>
                            <ul>
                                <li class="has-children">
                                    <a href="#">Level 3</a>
                                    <button>Show sub-menu for ‘Level 3’&lt;/button>
                                    <ul>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="#">Level 2</a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li>
                    <a href="#">Level 1</a>
                </li>
                <li class="has-children">
                    <a href="#">Level 1</a>
                    <button>Show sub-menu for ‘Level 1’&lt;/button>
                    <ul>
                        <li class="has-children">
                            <a href="#">Level 2</a>
                            <button>Show sub-menu for ‘Level 2’&lt;/button>
                            <ul>
                                <li class="has-children">
                                    <a href="#">Level 3</a>
                                    <button>Show sub-menu for ‘Level 3’&lt;/button>
                                    <ul>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                        <li>
                                            <a href="#">Level 4</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="#">Level 2</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </nav>

就好像在display: none焦点可以移动到嵌套链接之前状态开始了。任何人都可以确认我在这里吠叫一棵不可能的树,或者是否有办法让它工作?

编辑:要注意的另一件事是,如果您继续使用制表符,它会在第一级列表项中保持正确的位置,因此确实感觉焦点在嵌套列表的第一个锚元素上,但它只是没有'不承认嵌套ol在其中有一个焦点。

标签: cssfocus-within

解决方案


focus-within设法使用li元素而不是元素来解决它ul

    .menu ul li ul {
        display:none;
    }
    .menu button:focus + ul,
    .menu ul li:focus-within > ul {
        display: block;
    }
    .menu ul li:focus-within a:focus ~ ul {
        display: none;
    }

仍然不是 100% 理解为什么原始场景不起作用,但这是一个可行的解决方案。


推荐阅读