简体   繁体   中英

Alter Bootstrap nav tabs row wrapping

With Bootstrap 3, rows of nav-tabs wrap in a way where the widest rows tend to be at the top while the shorter rows are at the bottom:

在此处输入图片说明

This leaves the tabs looking awkward and unbalanced. Is there a way that nav-tabs can be modified so that the rows are wider at the bottom? More like this:

在此处输入图片说明

Here's the JSFiddle that produced the first image.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

<div class="container">
  <div class="row">
    <div class="col-sm-6">
      <ul class="nav nav-tabs">
        <li class="active"><a href="#">Foo Bar 1</a></li>
        <li><a href="#">FooBar 2</a></li>
        <li><a href="#">FooBar 3</a></li>
        <li><a href="#">FooBar 4</a></li>
        <li><a href="#">FooBar 5</a></li>
        <li><a href="#">FooBar 6</a></li>
        <li><a href="#">FooBar 7</a></li>
        <li><a href="#">FooBar 8</a></li>
        <li><a href="#">FooBar 9</a></li>
        <li><a href="#">FooBar 10</a></li>
        <li><a href="#">FooBar 11</a></li>
        <li><a href="#">FooBar 12</a></li>
        <li><a href="#">FooBarBaz 13</a></li>
        <li><a href="#">FooBarBaz 14</a></li>
      </ul>
    </div>
  </div>
</div>

I know it's not the best solution from the performance point of view but, anyway...Hope, this will be helpful. This solution doesn't depends on specific tab width and provides the result you want.

JSFiddle: https://jsfiddle.net/cpxd8eh0/6/

对于更大的屏幕尺寸

对于较小的屏幕尺寸

$(function(){
  var $container = $('#sync-tabs');

  updateTabs($container);
  $(window).resize(function(){
     updateTabs($container);
  });

  function updateTabs($tabsContainer){
    var $containerWidth = $tabsContainer.width();
    var tabWidths = [];
    var $tabs = $tabsContainer.find('li');
    $tabs.each(function(index, tab){
        tabWidths.push($(tab).width());
    });

    var formattedTabs = [];
    var maxWidth = $containerWidth;
    var maxWidthSet = false;
    var rowWidth = 0;
    for(var i = tabWidths.length - 1; i >= 0; i--){
        var tabWidth = tabWidths[i];
        if(rowWidth + tabWidth > maxWidth){
            if(!maxWidthSet){
              maxWidth = rowWidth;
              maxWidthSet = true;
            }
            rowWidth = tabWidth;
            formattedTabs.unshift($('<div class="spacer"></div>'));
        }else{
           rowWidth += tabWidth;
        }
        formattedTabs.unshift($tabs.get(i));
      }

      var $tempContainer = $('<div></div>');
      formattedTabs.forEach(function(tab, index){
        $tempContainer.append(tab);
      });
      $tabsContainer.html($tempContainer.html());
  }
});

I have updated the answer with a new and improved solution. Here is a demo . _.debounce is a function from Lodash which is being used to improve performance of the resize watcher.

function setTabs() {
  let availableWidth = $('#nav-bar').outerWidth();
  let liNodes = $('#nav-bar li');
  liNodes.removeClass('clear');
  let filledWidth = 0;
  for (var i=liNodes.length-1; i>=0; i--) {
    let currentWidth = $(liNodes[i]).outerWidth();

    if (filledWidth + currentWidth <= availableWidth)
      filledWidth += currentWidth;

    else {
      $(liNodes[i+1]).addClass('clear');
      availableWidth = filledWidth;
      filledWidth = currentWidth;
    }
  }
}

setTabs();
$(window).resize(_.debounce(setTabs, 200));

Are you trying to do something like shown in the fiddle

You can explicitly use css clear trick to achieve what you want.

 .clear { clear: both; }
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/> <div class="container"> <div class="row"> <div class="col-sm-6"> <ul class="nav nav-tabs" id="sync-tabs"> <li class="active"><a href="#">Foo Bar 1</a></li> <li><a href="#">FooBar 2</a></li> <li><a href="#">FooBar 3</a></li> <li><a href="#">FooBar 4</a></li> <li class="clear"><a href="#">FooBar 5</a></li> <li><a href="#">FooBar 6</a></li> <li><a href="#">FooBar 7</a></li> <li><a href="#">FooBar 8</a></li> <li><a href="#">FooBar 9</a></li> <li class="clear"><a href="#">FooBar 10</a></li> <li><a href="#">FooBar 11</a></li> <li><a href="#">FooBar 12</a></li> <li><a href="#">FooBar 13</a></li> <li><a href="#">FooBar 14</a></li> </ul> </div> </div> </div>

Here is a fiddle that i have done according to your requirements

FIDDLE LINK

.nav-tabs
{
  display: -webkit-flex;
   display: flex;
   -webkit-flex-direction: column; 
   flex-direction: column;
   -webkit-align-items: flex-start;
   align-items: flex-start;
}




<div class="container">
  <div class="row">
    <div class="col-sm-6">
      <ul class="nav nav-tabs" id="sync-tabs">
        <li class="active"><a href="#">Foo Bar 1</a></li>
        <li><a href="#">FooBar 2</a></li>
        <li><a href="#">FooBar 3</a></li>
        <li><a href="#">FooBar 4</a></li>
        <li><a href="#">FooBar 5</a></li>
        <li><a href="#">FooBar 6</a></li>
        <li><a href="#">FooBar 7</a></li>
        <li><a href="#">FooBar 8</a></li>
        <li><a href="#">FooBar 9</a></li>
        <li><a href="#">FooBar 10</a></li>
        <li><a href="#">FooBar 11</a></li>
        <li><a href="#">FooBar 12</a></li>
        <li><a href="#">FooBarBaz 13</a></li>
        <li><a href="#">FooBarBaz 14</a></li>
      </ul>
    </div>
  </div>
</div>

UPDATED FIDDLE LINK AS PER THE IMAGE GIVEN

Hope this helps...

I didn't understand what exactly you are looking for, and added following css to look good https://jsfiddle.net/2tu6a2yh/2/

.nav-tabs {
display: table;
table-layout: fixed;
width : 100%;
}

.nav-tabs li {
display: table-cell;
width:120px; // constant width
}

I think you need to set the column sizes for each list item for a more consistent look. Otherwise positions are determined according to the text length they contain. I think, if you make a few trial you'll find the combination you want for each screen size. Try something like following approach

<div class="container">
<div class="row">
<div class="col-sm-6">
  <ul class="nav nav-tabs" id="sync-tabs">
    <li class="active col-sm-4"><a href="#">Foo Bar 1</a></li>
    <li class="col-sm-4"><a href="#">FooBar 2</a></li>
    <li class="col-sm-4"><a href="#">FooBar 3</a></li>
    <li class="col-sm-4"><a href="#">FooBar 4</a></li>
    <li class="col-sm-4"><a href="#">FooBar 5</a></li>
    <li class="col-sm-4"><a href="#">FooBar 6</a></li>
    <li class="col-sm-3"><a href="#">FooBar 7</a></li>
    <li class="col-sm-3"><a href="#">FooBar 8</a></li>
    <li class="col-sm-3"><a href="#">FooBar 9</a></li>
    <li class="col-sm-3"><a href="#">FooBar 10</a></li>
    <li class="col-sm-3"><a href="#">FooBar 11</a></li>
    <li class="col-sm-3"><a href="#">FooBar 12</a></li>
    <li class="col-sm-3"><a href="#">FooBarBaz 13</a></li>
    <li class="col-sm-3"><a href="#">FooBarBaz 14</a></li>
  </ul>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM