向动态 ul li 添加滚动条

8
我在许多帖子和论坛中搜索,因为我认为这可能是基本的东西,但是没有找到,所以在这里询问。我要做的就是在高度超过某个限制时添加滚动条,比如说如果菜单项超过3个。
我创建了一个jsfiddle http://jsfiddle.net/euSWB/ 如果您无法访问它,那么这里是HTML和CSS:
<ul id="mnav">

<li><a><b>Home</b></a>
</li>
<li><a><b>SQL Server vs Oracle</b></a>
 <ul>

<li><a>Basic SQL : Declare variables and assign values</a></li>

<li><a>Basic SQL : Inner Join, Outer Join and Cross Join</a></li>

<li><a>Basic SQL : Padding and Trimming</a></li>

<li><a>Basic SQL : Union,Except/Minus,Intersect</a></li>

<li><a style="border-bottom-color: currentColor; border-bottom-width: 0px; border-bottom-style: none;">Update from Select</a></li>

</ul>
</li>

<li><a href="#"><b>SSIS</b></a>
 <ul>
<li><a>Coalesce in SSIS</a></li>
<li><a >Universal CSV Generator</a></li>
<li><a >Parsing a row into multiple in CSV</a></li>


<li><a style="border-bottom-color: currentColor; border-bottom-width: 0px; border-bottom-style: none;" >XML Task in SSIS</a></li>
</ul>
 </li></ul>

CSS

#mnav {
margin-left: -30px;
margin-right: -30px;
}
#mnav li {
float: left;
list-style: none;
}
#mnav li a, #mnav li a:link, #mnav li a:visited {
text-decoration: none;
}
#mnav li a:hover, #mnav li a:active {
text-decoration: none;
}
#mnav li:hover, #mnav li.sfhover {
position: static;
}
#mnav li ul {
display: block;
z-index: 9999;
position: absolute;
left: -999em;
width: 400px;
margin: 0px;
border: 1px solid #ddd;
}
#mnav li:hover ul, #mnav li.sfhover ul {
left: auto;
}
#mnav li ul li a, #mnav li ul li a:link, #mnav li ul li a:visited {
display: block;
margin: 0;
text-decoration: none;
z-index: 9999;
border-bottom: 1px dotted #ccc;
width: 500px;
}
#mnav li ul li a:hover, #mnav li ul li a:active {
display: block;
margin: 0;
text-decoration: none;
}
3个回答

22

我对原始样式表进行了一些调整,现在它将显示滚动条,但仅当它的高度超过3个列表项时(在这种情况下为63像素)。以下是最终的CSS代码:

#mnav {
    margin-left: -30px;
    margin-right: -30px;
}
#mnav li {
    float: left;
    list-style: none;
    margin:0 10px;/*Keeping 10px space between each nav element*/
}
#mnav li a,/*These can all be merged into a single style*/
#mnav li a:link,
#mnav li a:visited,
#mnav li a:hover,
#mnav li a:active {
    text-decoration: none;
}
#mnav li ul {
    display: none;/*This is the default state.*/
    z-index: 9999;
    position: absolute;
    width: 400px;
    max-height:63px;/*The important part*/
    overflow-y:auto;/*Also...*/
    overflow-x:hidden;/*And the end of the important part*/
    margin: 0px;
    padding-left:5px;/*Removing the large whitespace to the left of list items*/
    border: 1px solid #ddd;
}
#mnav li:hover ul, #mnav li.sfhover ul {
    display:block;/*This is the hovered state*/
}
#mnav li ul li a, #mnav li ul li a:link, #mnav li ul li a:visited {
    display: block;
    margin: 0;
    text-decoration: none;
    z-index: 9999;
    border-bottom: 1px dotted #ccc;
    width:400px;
}
#mnav li ul li a:hover, #mnav li ul li a:active {
    display: block;
    margin: 0;
    text-decoration: none;
}

这是示例演示。为了演示目的,我还在主页SQL Server vs Oracle项目中插入了2个额外的<li>元素。 主页项目将展示如果少于3个列表项,弹出窗口会如何显示。

要解释每个更改的部分,首先是实际执行操作的代码:

  • max-height定义为63将使ul在保持低于63px高度的情况下以正常方式工作,但如果超过这个高度,它将溢出并显示滚动条。如果您想显示更多项目,请将max-height增加到所需的高度。目前每个项目的高度为21px,因此我使用它来获取3个项目的63px。
  • 由于溢出应仅在垂直方向上显示滚动条,因此只应该有overflow-y:auto;,并且overflow-x:hidden可以防止水平方向上的滚动条。

然后是我所做的其他一般更改:

  • 我在项目之间添加了20px的边距(元素两侧各10px),以使列表在此处看起来更好。但你可能想应用自己的样式,这只是为了演示目的。
  • 我将您的隐藏技术从“将其推到左侧的-999em”更改为通过display:none隐藏。这更容易处理,因为display:none的元素不会在搜索引擎中呈现,因此在这些情况下会有所帮助。通常,我认为使用display:none隐藏事物比将其推到屏幕边缘还要好,因为它实际上仍然存在。
  • 我删除了ul左侧的填充,因为它看起来相当糟糕。如果您不使用它进行点状/编号列表,则不需要默认填充。

考虑到您对Zachary Carter的回答的评论,这也应该可行,因为如果将max-height定义为210px(10个项目),它不会显示巨大的白色框。


当我发布这个问题时,我在想肯定有类似于最大高度的东西,这正是我在寻找的,我相信这个答案会帮助很多像我一样的人。谢谢。 - sam

5
如果您的列表项高度是可预测的,那么这就相当简单。考虑以下示例:
<ul class="sub-menu">
    <li>This is option one.</li>
    <li>This is a second option.</li>
    <li>We'll need three.</li>
    <li>And now these are out of view.</li>
    <li>I'm the last option.</li>
</ul>

这里有一个包含五个项目的列表。我将指示每个列表项自身具有font-sizeline-height1em,并在上下各添加.25em的填充:

.sub-menu li {
    font-size: 1em;
    padding: .25em 1em;
    line-height: 1em;
}

现在我们知道每个列表项的高度是1.5em。因此,我们现在可以在父元素上设置max-height,以便一次仅显示三个列表项:

.sub-menu {
    padding: 0;
    max-height: 4.5em; /* 1.5 x 3 */
    overflow-y: auto;
}

结果如下:

结果:

图片描述

在线演示:http://jsfiddle.net/euSWB/16/


从我的fiddle中可以看出,我有多个菜单项和子类别,请问您能否为多层ul li实现上述功能? - sam
@sam 当你说“多个级别”时,你是指子菜单中的子菜单吗?我在你的示例中没有看到这一点。 - Sampson
我在谈论具有子菜单的多个主菜单,但只有当我们悬停在主菜单上时才会打开子菜单。这就是我如何在我的代码中尝试实现您的代码http://jsfiddle.net/euSWB/17/,但它会产生额外的水平滚动条,所以希望您能帮助我在我的li ul中实现您的代码。 - sam
@sam 我在视口上看到了一个额外的滚动条;这就是你所说的,对吗? - Sampson
是的,那是正确的,请重新编写CSS,如果有其他方法的话。顺便说一下,如果我从“#mnav li ul li a,#mnav li ul li a:link,#mnav li ul li”中删除width: 500px;,垂直滚动条就会消失,但是SSIS选项卡(第三个选项卡)将具有子菜单项并排而不是堆叠。 - sam

1

有几件事情...

首先,您没有为无序列表指定高度。如果您不为元素定义高度,则永远不会看到滚动条。该元素将根据其内容调整大小。

此外,如果要防止UL的内容在水平方向上溢出元素,请将overflow-x CSS3属性设置为hidden。

我认为您需要的是:

#mnav li ul {
    display: block;
    z-index: 9999;
    position: absolute;
    left: -999em;
    width: 400px;
    margin: 0px;
    border: 1px solid #ddd;
    overflow-x:hidden;
    height:50px;
}

http://jsfiddle.net/euSWB/9/

希望这能帮到您!

我只是以3为例,但我真的想要10个项目然后滚动,我尝试实现高度,但它没有起作用,因为如果一个选项卡中只有几个项目,那么它会为该选项卡创建一个大的空白框,这看起来不太好看。 - sam
我不确定为什么你要给我的答案点踩,因为它看起来不够漂亮。在你的问题中并没有要求如何让它看起来漂亮。你问的是如何让元素显示滚动条,而我给出了一个完全可行的解决方案。如果你想让它看起来漂亮,请在将来的问题中明确说明。 - Zachary Carter
FYI,有人降低了你的回答。 - sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接