ChatGPT解决这个技术问题 Extra ChatGPT

How to change navbar collapse threshold using Twitter bootstrap-responsive?

I'm using Twitter Bootstrap 2.0.1 in a Rails 3.1.2 project, implemented with bootstrap-sass. I'm loading both the bootstrap.css and the bootstrap-responsive.css files, as well as the bootstrap-collapse.js Javascript.

I have a fluid layout with a navbar similar to the example. This follows the navbar "responsive variation" instructions here. It works fine: if the page is narrower than about 940px, the navbar collapses and displays a "button" that I can click on to expand.

However my navbar looks good down to about 550px wide, i.e. it doesn't need to be collapsed unless the screen is very narrow.

How do I tell Bootstrap to only collapse the navbar if the screen is less than 550px wide?

Note that at this point I do not want to modify the other responsive behaviors, e.g. stacking elements instead of displaying them side by side.

Great question! From the info you gave in your question I was able to implement a collapsable navbar starting from nothing. Thanks!

B
Brad

Bootstrap > 2.1 && < 3

Use the less version of bootstrap

Change the @navbarCollapseWidth variable in variables.less

Recompile.

Update 2013: The easy way

Visit http://getbootstrap.com/customize/#less-variables

Change @navbarCollapseWidth in the formfield

Click "Compile and Download".

(THX to Archonic via comment)

Update 2014: Bootstrap 3.1.1 and 3.2 (they even added it to the documentation)

If you're customizing or overriding/editing .less variables, you're looking for:

//** Point at which the navbar becomes uncollapsed.
@grid-float-breakpoint:     @screen-sm-min;
//** Point at which the navbar begins collapsing.
@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);

You can visit twitter.github.com/bootstrap/customize.html#variables and change the width and download. No compiling necessary.
Link and button text updated: getbootstrap.com/customize/#less-variables & "Compile and Download"
This works with the twitter-bootstrap-rails gem too if you put something like @navbarCollapseWidth: 600px; in boostrap_and_overrides.css.less.
This seems to no longer be a thing in Bootstrap 3. :(
What about for Bootstrap 4?
J
Justin Morgan

You are looking for line 239 of bootstrap-responsive.css

@media (max-width: 979px) {...}

Where the max-width value triggers the responsive nav. Change it to 550px or so and it should resize fine.


Thanks. bootstrap-responsive.css is buried in the bootstrap-sass gem. Yes I could edit it but then when the gem is updated, I'd have to do it again. Is there a way to override the @media query, similar to overriding other CSS elements?
I can't think of any way to achieve the overriding without restating all the CSS declarations.
Okay thanks. I tried this approach, overriding that line in the gem code, and it kinda works but I get extra horizontal padding in the navbar below 767px width, presumably because of the CSS in the @media (max-width: 767px) block. Looks like I will have to do a more extensive override as suggested in Andres Ilich's answer.
As mentioned in my comment on @Andres Ilich's answer, directly updating source code seems the lesser of two evils when it comes to maintainability, so I will accept this solution for now. I can live with 767px as the minimum threshold, though I could probably reduce that further by creating a custom container for the navbar that was not affected by @media (max-width: 767px). Hopefully Bootstrap (or bootstrap-sass) will one day include a means to use variables to set the thresholds, but I think that will require interpolation in media selectors.
The navbar breakpoint override CSS has changed for Bootstrap 3 -- here's a working example for 3.1: bootply.com/120604
t
thirtydot

You can establish a new @media query to drop the navbar elements down as you see fit, all you have to do is reset the former to accommodate your new query with the desired drop width. Take this for example:

CSS

/** Modified Responsive CSS **/

@media (max-width: 979px) {
    .btn-navbar {
        display: none;
    }
    .navbar .nav-collapse {
        clear: none;
    }

    .nav-collapse {
        height: auto;
        overflow: auto;
    }

    .navbar .nav {
        float: left;
        margin: 0 10px 0 0;
    }

    .navbar .brand {
        margin-left: -20px;
        padding: 8px 20px 12px;
    }

    .navbar .dropdown-menu:before, .navbar .dropdown-menu:after {
        display: block;
    }

    .navbar .nav > li > a, .navbar .dropdown-menu a {
        border-radius: 0;
        color: #999999;
        font-weight: normal;
        padding: 10px 10px 11px;
    }

    .navbar .nav > li {
        float: left;
    }

    .navbar .dropdown-menu {
        background-clip: padding-box;
        background-color: #FFFFFF;
        border-color: rgba(0, 0, 0, 0.2);
        border-radius: 0 0 5px 5px;
        border-style: solid;
        border-width: 1px;
        box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
        display: none;
        float: left;
        left: 0;
        list-style: none outside none;
        margin: 0;
        min-width: 160px;
        padding: 4px 0;
        position: absolute;
        top: 100%;
        z-index: 1000;
    }

    .navbar-form, .navbar-search {
        border:none;
        box-shadow: 0 1px 0 rgba(255, 255, 255, 0.1) inset, 0 1px 0 rgba(255, 255, 255, 0.1);
        float: left;
        margin-bottom: 0;
        margin-top:6px;
        padding: 9px 15px;
    }

    .navbar .nav.pull-right {
        float: right;
        margin-left: auto;
    }
}

@media (max-width: 550px) {
    .btn-navbar {
        display: block;
    }
    .navbar .nav-collapse {
        clear: left;
    }

    .nav-collapse {
        height: 0;
        overflow: hidden;
    }

    .navbar .nav {
        float: none;
        margin: 0 0 9px;
    }

    .navbar .brand {
        margin: 0 0 0 -5px;
        padding-left: 10px;
        padding-right: 10px;
    }

    .navbar .dropdown-menu:before, .navbar .dropdown-menu:after {
        display: none;
    }

    .navbar .nav > li > a, .navbar .dropdown-menu a {
        border-radius: 3px 3px 3px 3px;
        color: #999999;
        font-weight: bold;
        padding: 6px 15px;
    }

    .navbar .nav > li {
        float: none;
    }

    .navbar .dropdown-menu {
        background-color: transparent;
        border: medium none;
        border-radius: 0 0 0 0;
        box-shadow: none;
        display: block;
        float: none;
        left: auto;
        margin: 0 15px;
        max-width: none;
        padding: 0;
        position: static;
        top: auto;
    }

    .navbar-form, .navbar-search {
        border-bottom: 1px solid #222222;
        border-top: 1px solid #222222;
        box-shadow: 0 1px 0 rgba(255, 255, 255, 0.1) inset, 0 1px 0 rgba(255, 255, 255, 0.1);
        float: none;
        margin: 9px 0;
        padding: 9px 15px;
    }

    .navbar .nav.pull-right {
        float: none;
        margin-left: 0;
    }

}

In the following code you can see how I included the original @media query that handles the drop before the 979px mark and the new query to support your desired drop point of 550px. I modified the original query straight from the bootstrap-responsive css to reset all the styles applied to that specific query for the navbar elements and ported them to the new query that carries the drop point you need instead. This way we can commute all the styles from the original query down to the new query without messing around in the bootstrap-responsive stylesheet, this way the default values will still apply to the other elements in your document.

Here is a short demo with a media query set to drop at 550px as you require: http://jsfiddle.net/wU8MW/

Note: I placed the above modified @media queries way down below the css frame as the new modified css is supposed to be loaded first than the responsive css.


Thank you for your detailed answer. It does seem to work--I am still trying to figure out how. If I understand you correctly, you (1) cloned the original @media (max-width: 979px) query to make the new @media (max-width: 550px) query. Then (2) you hand-coded a new 979px query to override the effects of the 979px query in the main bootstrap-responsive.css? The sequence of tags in your CSS does not seem to follow the sequence in bootstrap-responsive.css, so I am having difficulty comparing them to see what you did.
@MarkBerry You're on the right track. The @media (max-width: 550px) query i wrote does not follow the initial @media (max-width: 979px) queries syntax because all i did was a quick example overriding it by hand through firebug and copy/pasting, got lazy on that one, but the right way to do it is as you mentioned on your second point.
This is a tough call when it comes to maintainability. I'm afraid this kind of extensive override, while providing absolute control, would mean lots of manual checking after every Bootstrap update vs. directly updating one or two source code lines per the suggestion by @Duopixel. I'm using Bootstrap in part because I'm not a CSS whiz, so I think I'll go with the simpler solution for now.
t
trisweb

bootstrap-sass will support the variable $navbarCollapseWidth in the next version (2.2.1.0). You'll be able to update it to do exactly what you want once that version is live!


Please could you explain where you put this variable?
Before any Bootstrap imports e.g. @import "bootstrap";
C
Community

As of August 2013, a Bootstrap 3 "Customize and download" page can be found at http://getbootstrap.com/customize/

With Bootstrap 3, the relevant variable is @grid-float-breakpoint.

The following Stack Overflow page has additional details: Bootstrap 3 Navbar Collapse


K
KyleMit

I suspect (and hope) this will be implemented in an official way soon. In the meantime I'm just doing a simple css hack, using visible-phone on the dropdown button and visible-tablet on a second set of buttons I've placed in the navbar. So before it looked like this:

<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
      <a href="<%= root_url %>" class="brand brandtag"></a>
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
      <div class="nav-collapse">
        <ul class="nav">
          <li>Navigation 1</li>
          <li>Navigation 2</li>
          <li>Navigation 3</li>
        </ul>
      </div>
    </div>
  </div>
</div>

And now it looks like:

<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
      <a href="<%= root_url %>" class="brand brandtag"></a>
      <a class="btn btn-navbar visible-phone" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
      <div class="visible-tablet">
        <ul class="nav">
          <li>Navigation 1</li>
          <li>Navigation 2</li>
          <li>Navigation 3</li>
        </ul>
      </div>
      <div class="nav-collapse">
        <ul class="nav">
          <li>Navigation 1</li>
          <li>Navigation 2</li>
          <li>Navigation 3</li>
        </ul>
      </div>
    </div>
  </div>
</div>

Note that order of elements is important, otherwise you may have issues with elements going into the next line


m
mae

I created a separate SCSS file that listed all of the partials that bootstrap needs, that way I can turn the partials on and off depending on what our site needs. This way, I am able to override the breakpoint variable easily. Here's what I got:

// Core variables and mixins
$grid-float-breakpoint: 991px;
@import "bootstrap/variables";
@import "bootstrap/mixins";

// Reset
@import "bootstrap/normalize";
//@import "bootstrap/print";

// Core CSS
@import "bootstrap/scaffolding";
@import "bootstrap/type";
//@import "bootstrap/code";
@import "bootstrap/grid";
@import "bootstrap/tables";
@import "bootstrap/forms";
@import "bootstrap/buttons";

// Components
@import "bootstrap/component-animations";
@import "bootstrap/glyphicons";
@import "bootstrap/dropdowns";
//@import "bootstrap/button-groups";
//@import "bootstrap/input-groups";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/labels";
@import "bootstrap/badges";
//@import "bootstrap/jumbotron";
//@import "bootstrap/thumbnails";
@import "bootstrap/alerts";
//@import "bootstrap/progress-bars";
//@import "bootstrap/media";
//@import "bootstrap/list-group";
@import "bootstrap/panels";
//@import "bootstrap/wells";
@import "bootstrap/close";

// Components w/ JavaScript
@import "bootstrap/modals";
@import "bootstrap/tooltip";
//@import "bootstrap/popovers";
//@import "bootstrap/carousel";

// Utility classes
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities";

K
KyleMit

Here is my code (All other solution showed funky scrollbar as the navbar dropped down so I edited the code so it didn't). I could not post on other answer so I'll do it here for others to find. I am using rails to do this with Bootstrap 3.0.

assets/stylesheets/framework and overrides paste this: (Adjust max width to whatever value to achieve your goal.)

@media (max-width: 2500px) {
.navbar-header {
    float: none;
}
.navbar-toggle {
    display: block;
}
.navbar-collapse {
    border-top: 1px solid transparent;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-collapse.collapse {
    display: none!important;
}
.navbar-collapse.collapse.in {
    display: block!important;
}
.navbar-nav {
    float: none!important;
}
.navbar-nav>li {
    float: none;
}
.navbar-nav>li>a {
    padding-top: 10px;
    padding-bottom: 10px;
}

J
JasonS

Bootstrap 3.x

using LESS, you can change the value of @screen-small to target your min size

example: @screen-small: 600px;

i use this to only switch to "tiny device" mode once the width is less than 600px


Do you know how to do this with SCSS?
sorry i don't. i thought bootstrap was developed using LESS, so you may have to do it the .css way (see bootstrap 2 answers above)
c
coding addicted

Bootstrap 3.x

using SASS, you can change the value of $screen-sm to target your min size

example: $screen-sm: 600px;

You need to put this value in your application.scss file before the @import "bootstrap";

$screen-sm:600px;
@import "bootstrap";

Less variables begin with "@" just changed them to "$" to override them before the import.

Here is the list of variables.


This breaks functionality
j
jinhr

Bootstrap 4.x

It is a snap to change collapse threshold in Bootstrap 4.x. There are 6 cases:

Always expand, never collapse (i.e. breakpoint is 0px):

Breakpoint is sm (576px): Breakpoint is md (768px): Breakpoint is lg (992px): Breakpoint is xl (1200px):
J
Jason Capriotti

This is a great example of where you could be using the LESS version of the Bootstrap CSS files. How to do this is below.

Even better would be to submit this as a pull request on Github so that everyone can benefit and your "custom code" would hopefully be part of Bootstrap moving forward.

Add a variable to variables.less that specifies when to collapse the navbar. Something like: @navCollapseWidth: 979px

Then modify responsive-navbar.less... Up top change @media (max-width: 979px) to @media (max-width: @navCollapseWidth) At the bottom change @media (min-width: 980px) to @media (max-width: @navCollapseWidth - 1)

Up top change @media (max-width: 979px) to @media (max-width: @navCollapseWidth)

At the bottom change @media (min-width: 980px) to @media (max-width: @navCollapseWidth - 1)

Of course... you'd have to compile LESS using one of the suggested methods.


Apparently Bootstrap 2.0.4 has changed the file structure for the responsive stuff. See the comment by bootstrap-sass author @Thomas McDonald. Haven't dug into this yet but it may allow easier modification of the threshold even with the SASS version.
I'm sorry; I completely missed the Sass comment in the question... I was just focused on Bootstrap based on the category. However, the file structure looks the same as what I was looking at in Bootstrap... either way I'll update my answer to it responds to the question.
No worries. And I completely agree that the best solution would be for bootstrap to natively offer a variable or series of variables that controls navbar collapse thresholds. I'm not experienced enough with CSS, LESS, or SASS, or media queries to be the one to write that enhancement ;).
K
KyleMit

Taking tyler's hack even further by adding a visible-phone classed block and a hidden-phone class to an item in the main collapsible navigation, you can 'pull out' one or two of the collapsed items to display even in the phone navbar.

<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
      <a href="<%= root_url %>" class="brand brandtag"></a>
      <a class="btn btn-navbar visible-phone" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
      <div class="visible-tablet">
        <ul class="nav">
          <li>Navigation 1</li>
          <li>Navigation 2</li>
          <li>Navigation 3</li>
        </ul>
      </div>
      <div class="visible-phone">
        <ul class="nav">
          <li>Navigation 1</li>
        </ul>
      </div>
      <div class="nav-collapse">
        <ul class="nav">
          <li class="hidden-phone">Navigation 1</li>
          <li>Navigation 2</li>
          <li>Navigation 3</li>
        </ul>
      </div>
    </div>
  </div>
</div>

G
Ganpat Kakar

Just write down this this code in your custom style.css file and it will work

@media (min-width: 768px) and (max-width: 991px) {
        .navbar-collapse.collapse {
            display: none !important;
        }
        .navbar-collapse.collapse.in {
            display: block !important;
        }
        .navbar-header .collapse, .navbar-toggle {
            display:block !important;
        }
        .navbar-header {
            float:none;
        }
        .navbar-nav {
            float: none !important;
            margin: 0px;
        }
        .navbar-nav {
            margin: 7.5px -15px;
        }
        .nav > li {
            position: relative;
            display: block;
        }
        .navbar-nav > li {
            float: none !important;
        }
        .nav > li > a {
            position: relative;
            display: block;
            padding: 10px 15px;
        }
        .navbar-collapse {
            padding-right: 15px;
            padding-left: 15px;
            overflow-x: visible;
            border-top: 1px solid transparent;
            box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1) inset;
        }
        .nav {
            padding-left: 0px;
            margin-bottom: 0px;
            list-style: outside none none;
        }
    }