Bootstrap 3 导航栏动态折叠

11

我正在寻找一个解决Bootstrap导航栏调整大小问题的方案。

目前,导航栏在变得紧凑之前会产生一种“重叠”的效果。(我知道这是由于媒体查询造成的)

bootstraps官网的例子

这里使用媒体查询来指示何时要缩小,但我正在寻找一种解决方案,仅当'.navbar-nav'和'.navbar-right'之间没有剩余空间时,导航栏才会调整大小。

这很重要,因为'.navbar-nav'和'.navbar-right'的宽度是动态的。(换句话说,有时'.navbar-nav'将包含1个列表项到5个列表项。'.navbar-right'类似于一个文本字符串,可能长达3个字符甚至更长。

输入图像说明

下面是一个plunker示例,通过调整预览窗格的大小,您可以看到意外的“重叠”(因为它等待满足max-width媒体查询)。

http://plnkr.co/edit/7r5fNX2JyJUuT0PvVPDf?p=preview

如何使它仅在'.navbar-nav'和'.navbar-right'之间没有空余空间(例如..两者之间有5像素的空间或类似的空间)时变成紧凑形式?

(请注意,调整断点并不能足以实现此目的)


JavaScript 是一个选项吗? - Markus Kottländer
4个回答

14

您应该在导航栏上添加自定义类,并在其高度增加时更改样式:

<nav id="autocollapse" class="navbar navbar-default" role="navigation">
    ...
</nav>
function autocollapse() {
    var navbar = $('#autocollapse');
    navbar.removeClass('collapsed'); // set standart view
    if(navbar.innerHeight() > 50) // check if we've got 2 lines
        navbar.addClass('collapsed'); // force collapse mode
}

$(document).on('ready', autocollapse);
$(window).on('resize', autocollapse);
#autocollapse.collapsed .navbar-header {
    float: none;
}
#autocollapse.collapsed .navbar-toggle {
    display: block;
}
#autocollapse.collapsed .navbar-collapse {
    border-top: 1px solid transparent;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
#autocollapse.collapsed .navbar-collapse.collapse {
    display: none!important;
}
#autocollapse.collapsed .navbar-nav {
    float: none!important;
    margin: 7.5px -15px;
}
#autocollapse.collapsed .navbar-nav>li {
    float: none;
}
#autocollapse.collapsed .navbar-nav>li>a {
    padding-top: 10px;
    padding-bottom: 10px;
}

Bootply
Forked Plunker


简单明了!谢谢,老板! - captainrad
快速而有点“肮脏”,我想说。嗯,导航栏的预期高度为50px不会经常改变,但为了完美,我会与菜单元素的高度进行比较,而不是硬编码的50px。 :) - Markus Kottländer
@burebistaruler 它仍然可以在BT 3.1.1上运行:Bootply。你可能有其他问题。 - zessx
@zessx 你的例子只在Chrome浏览器上有效,在Firefox和IE10上不起作用 :| - BurebistaRuler
1
当我在Google Chrome中尝试上面的bootply链接(120904),并将窗口缩小以使其折叠时,当我单击获取菜单时,它会再次消失。因此,由于无法选择菜单项,因此它不起作用。在iPad上表现相同,在iPhone上没有。有什么想法是错的吗? - Marc Jonkers
显示剩余2条评论

4

也许可以尝试使用jQuery:

$(document).ready(function() {
    var width_full = $('.navbar-collapse').innerWidth();
    var width_left = $('.navbar-nav').outerWidth(true);
    var width_right = $('.navbar-right').outerWidth(true);
    if (width_full - (width_left + width_right) < 0)
    {
        // trigger collapse, you have to figure out what css changes
        // exactly are needed, for example:
        $('.navbar-toggle').css('display', 'inline');
    }
});

抱歉...显然应该是 < 0 而不是 >= 0,我已经修改了。 - Markus Kottländer
是的,如果菜单项是动态的,并且您真的希望调整大小是动态的,那么这个jQuery示例可能是最简单的解决方案。 - akalucas

1

对于Bootstrap 3.3.5,zessx的答案中缺少一些样式。请使用以下样式代替:

    #autocollapse.collapsed .navbar-header {
        float: none;
    }
    #autocollapse.collapsed .navbar-left,.navbar-right {
        float: none !important;
    }
    #autocollapse.collapsed .navbar-toggle {
        display: block;
    }       
    #autocollapse.collapsed .navbar-fixed-top {
        top: 0;
        border-width: 0 0 1px;
    }       
    #autocollapse.collapsed .navbar-collapse.collapse {
        display: none!important;
    }
    #autocollapse.collapsed .navbar-nav {
        float: none!important;
        margin-top: 7.5px;
    }
    #autocollapse.collapsed .navbar-nav>li {
        float: none;
    }
    #autocollapse.collapsed .navbar-nav>li>a {
        padding-top: 10px;
        padding-bottom: 10px;
    }
    #autocollapse.collapsed .collapse.in{
        display:block !important;
    }

还有一件事。zessx在折叠时使用了50像素。当你对浏览器应用缩放时,会出现一个圆形问题。导航栏高度可能为53像素,然后菜单就会折叠。我建议将50像素的值更改为70像素。因此,这是我的建议:

function autocollapse() {
            var navbar = $('#autocollapse');
            navbar.removeClass('collapsed'); // set standart view
            if (navbar.innerHeight() > 70) // check if we've got 2 lines
                navbar.addClass('collapsed'); // force collapse mode
        }

1
CSS不能自己检测换行,因此您需要重新定义特定媒体宽度的样式。您的换行似乎发生在910px左右;Twitter Bootstrap (3)默认将.collapse应用display:none,然后再使用媒体查询将display:block值重新应用于大于或等于768px宽度的视口宽度:
/* beginning at line 4412 in bootstrap.css,  v3.0.2 */  
@media (min-width: 768px) {

    ... /*other declarations ommitted here */

    .navbar-collapse.collapse {
        display: block !important;
        height: auto !important;
        padding-bottom: 0;
        overflow: visible !important;
    }

    ... /*other declarations ommitted here */
}

因此,您可以使用几个更具体的媒体查询来覆盖导航栏的范围,以隐藏它(在768px和910px之间的值范围内):

@media (min-width: 768px)  and max-width (max-width: 910px){

    #bs-example-navbar-collapse-1{

        display:none !important;
    }

有一个更简单的答案。在BS3菜单中,min-width:768px接管了几个位置,包括小条,因此您可以使用less并编辑variables.less文件,或者使用自定义程序并插入任何宽度以使其切换到切换。 - Christina
3
但这将重新定义每一个可能的使用行为。我通常建议不要直接编辑库CSS(LESS)文件本身,因为这会在升级到新版本时带来麻烦,并且在追踪所做的更改时也会有困难(源代码有数千行)。 - Faust
我现在明白了。永远不要使用自定义器,只是认为那会是最快的方法。在我看来,导航栏的断点应该分开。 - Christina
1
这不是媒体查询的问题,正如captainrad两次提到的那样。我认为您需要使用JavaScript进行调整。 - Markus Kottländer

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