5

我有一个看起来像这样的菜单:

|Home|Options|Settings|Tools|Preferences|Edit|

当手机有很多水平空间时这很好,但是当具有狭窄视口的设备访问页面时,我希望菜单看起来像

|Home|Options|Settings|+MORE+|

单击“更多”菜单会在垂直下拉菜单中显示其他项目。

我不想设置手动断点,因为我不知道各个菜单项在显示时的宽度。

我的菜单目前只是一<li><ul>

水平布局的 CSS 是

#menu ul, #menu li { margin: 0; padding: 0; list-style: none; }
#menu ul { overflow: auto; }
#menu li { float: left; }
#menu  a { display: block; padding: 0.5em; text-decoration: none; border-right: 1px solid #fff; font-size: 110%; }

我不愿意使用像 jQuery 这样的东西——即使最小化,它对于旧的移动浏览器来说仍然是一个很大的开销。媒体查询对于某些手机也有问题,所以我想避免依赖这些。

关于 CSS 和(简单)JavaScript 根据浏览器的宽度自动隐藏元素的任何想法?

4

1 回答 1

7

实际上,您可以完全不使用 JavaScript,只需使用媒体查询(它确实具有出色的支持+ 我提出的这个解决方案是移动设备的第一个)和:nth-last-child(Opera Mini 甚至再次支持)。

演示

(调整大小以查看其工作原理)

你需要有这样的结构:

<nav id='menu'>
    <ul>
        <li><a href='#'>Home</a></li>
        <li><a href='#'>Options</a></li>
        <li><a href='#'>Settings</a></li>
        <li><a href='#'>Tools</a></li>
        <li><a href='#'>Preferences</a></li>
        <li><a href='#'>Edit</a></li>
        <li><a href='#'>+ MORE +</a></li>
    </ul>
</nav>

然后你需要选择ToolsPreferencesEdit并将它们设置displaynone

#menu li:nth-last-child(-n+4):not(:last-child) { display: none; }

li:nth-last-child(-n+4)仅选择最后的前四个列表项。您添加:not(:last-child)条件是因为您希望显示+ MORE +列表项。

为了更好地理解结构化伪类,您可以使用这个工具

最后,您需要使用媒体查询来更改大屏幕的显示设置:

@media (min-width: 30em) {
    #menu li:nth-last-child(-n+4):not(:last-child) { display: block; }
    #menu li:last-child { display: none; }
}

我使用em基于媒体查询而不是基于媒体查询的px原因有两个:

  • 一、本文
  • 二,我自己的网站在缩放上看起来像垃圾,因为我px在一年前使用了基于媒体的查询;

编辑:为了使菜单在单击时展开并使显示的菜单元素的数量随屏幕宽度而变化,我对结构进行了更多更改:

<nav id='menu'>
    <a tabindex=1 class='ctrl' href='#'>+ MORE +</a>
    <ul>
        <li><a href='#' class='menu-link'>Home</a></li>
        <li><a href='#' class='menu-link'>Options</a></li>
        <li><a href='#' class='menu-link'>Settings</a></li>
        <li><a href='#' class='menu-link'>Tools</a></li>
        <li><a href='#' class='menu-link'>Preferences</a></li>
        <li><a href='#' class='menu-link'>Edit</a></li>
    </ul>
</nav>

并且还稍微更改了 CSS:

#menu .ctrl { float: right; }
#menu ul, #menu li { margin: 0; padding: 0; list-style: none; }
#menu ul { overflow: auto; }
#menu li { float: left; }
#menu li:nth-last-child(-n+5) { display: none; }
#menu a {
    padding: 0.5em;
    text-decoration: none;
    border-right: 1px solid #fff;
    font-size: 110%;
}
#menu li a { display: block; }
#menu li:first-child a { border-left: 1px solid #fff; }
#menu .ctrl:focus, #menu .ctrl:active { display: none; outline: 0; }
#menu .ctrl:focus ~ ul li, #menu .ctrl:active ~ ul li { display: block; }

@media (min-width: 15em) {
    #menu li:nth-child(2) { display: block; }
}
@media (min-width: 20em) {
    #menu li:nth-child(3) { display: block; }
}
@media (min-width: 25em) {
    #menu li:nth-child(4) { display: block; }
}
@media (min-width: 30em) {
    #menu .ctrl ~ ul li { display: block; }
    #menu .ctrl { display: none; }
}

演示

(我还在每 5em 处添加了一个带有垂直线的背景,以便在调整浏览器窗口大小时清楚地显示屏幕的宽度)

此方法应该在没有 JavaScript 的情况下工作 - 在桌面浏览器、Opera Mobile、Android 浏览器和 iOS Safari 中进行了测试。不过,我不知道 Opera Mini - 我必须对其进行测试。

编辑#2:不,它在 Opera Mini 中对我不起作用(菜单已折叠,但单击+ MORE +链接不会展开它)。试图让它与 JavaScript(无库)一起使用,但这在 Opera Mini 中也不起作用(尽管它适用于桌面浏览器)。

编辑#3:也尝试使用 jQuery 做同样的事情。这次它也适用于 Opera Mini。真的很慢(至少对我来说),但它确实有效。这是我使用的:

$('.ctrl').click(function() {
    $(this).css({'display': 'none'}).next().children().css({'display': 'block'});
});

EDIT#4:现在尝试了该:target方法 -演示(也仅限 CSS)。在我使用 Chrome 的笔记本电脑上工作正常(尚未在其他桌面浏览器中测试),在 Opera Mini 中不起作用(菜单已折叠,单击+ MORE +链接不会展开它)。不过可以在 Opera Mobile 中使用。

于 2012-09-18T16:16:55.147 回答