折叠响应式设计的水平菜单

时间:2012-09-18 15:32:14

标签: javascript css user-interface drop-down-menu responsive-design

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

|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的想法,根据浏览器的宽度自动隐藏元素吗?

1 个答案:

答案 0 :(得分:7)

实际上,您可以完全不使用JavaScript,只需使用media queries(我真正提出的have excellent support +此解决方案是移动优先解决方案)和:nth-last-child(其中甚至是supported by Opera Mini)。

demo

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

你需要有这样的结构:

<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>

然后,您需要选择工具偏好设置修改,并将display设置为{{1} }:

none

#menu li:nth-last-child(-n+4):not(:last-child) { display: none; } 仅从末尾选择前四个列表项。您可以添加li:nth-last-child(-n+4)条件,因为您希望显示 + MORE + 列表项。

为了更好地理解结构伪类,您可以使用this tool

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

:not(:last-child)

我使用基于@media (min-width: 30em) { #menu li:nth-last-child(-n+4):not(:last-child) { display: block; } #menu li:last-child { display: none; } } 的媒体查询,而不是基于em的媒体查询,原因有两个:

  • one,this article;
  • 两个,我自己的网站看起来像废话缩放,因为我在一年前使用基于px的媒体查询;

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

px

并且还改变了CSS:

<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>

demo

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

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

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

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

#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; }
}

编辑#4 :现在尝试使用$('.ctrl').click(function() { $(this).css({'display': 'none'}).next().children().css({'display': 'block'}); }); 方法 - demo(仅限CSS)。使用Chrome在我的笔记本电脑上正常工作(未在其他桌面浏览器中测试过),在Opera Mini中不起作用(菜单已折叠,单击 + MORE + 链接不会展开它)。适用于Opera Mobile。