When screen size made smaller bootstrap tabs are overlapping

时间:2016-05-17 11:07:53

标签: html css twitter-bootstrap overlap bootstrap-tabs

When screen size made smaller bootstrap tabs are overlapping like image. enter image description here

I used col-sm and my angular HTML is like this (but any non-angular HTML solution is fine too):

<div class="col-sm-6"> <tabset> <tab>
    <tab-heading active="true">
        Tab1
        <toggle-switch ></toggle-switch>
    </tab-heading>
...
</tab>
<tab>
    <tab-heading>Tab2
        <toggle-switch ></toggle-switch></tab-heading>
    ...
</tab>
<tab>
    <tab-heading>Tab3
        <toggle-switch ></toggle-switch></tab-heading>
    ...
</tab></tabset></div>

I would like for the other tabs to stack in the background instead of the foreground.

desired screenshot

Please forgive my terrible gimp skills, but the active tab should always be up front, so if tab 3 is selected, then the other row should shift to the back.

desired active

It doesn't have to be arranged specifically like this, but the point is that the active tab should not have anything in between it and its content pane, so something like this is also fine:

enter image description here

7 个答案:

答案 0 :(得分:4)

有一个结合了Css和Javascript的解决方案。

但是,你需要知道标签的高度和宽度!

因为每张标签在图片中都有相同的宽度和高度,所以这似乎不是问题。

// Tab width
var tabWidth = 140;
// Tab height
var tabHeight = 42;

var updateAllTabs = function(){
	$('li.active a[data-toggle="tab"]').each(function(){
		updateTabs({target : this});
	});
};

var updateTabs = function(e){
	// Get elements
	var activeItem = e.target.parentNode;
	var menu = activeItem.parentNode;
	var items = menu.getElementsByTagName("li");
	
	// Reset menu
	menu.style.paddingLeft = 0;
	menu.style.paddingBottom = 0;
	
	var menuWidth = jQuery(menu).width();
	
	var otherItems = [];
	
	// Clear old changes - make new list
	for(var i=0; i < items.length; i++){
		items[i].style.marginLeft = "0px";
		items[i].style.marginTop = "0px";
		
		if(items[i] != activeItem)
			otherItems.push(items[i]);
	}
	
	// If one line return (or only one item)
	if(menuWidth >= items.length * tabWidth || items.length <= 1)
		return;
	
	// Make some calculations
	var perLine = Math.floor(menuWidth / tabWidth);
	var lines = Math.ceil(items.length / perLine);
	
	// 1 tab per line
	if(perLine == 1){
		menu.style.paddingBottom = jQuery(activeItem).height() + "px";
		return;
	} else if(perLine + 1 == items.length){
		menu.style.paddingBottom = jQuery(activeItem).height() + "px";
	}
	
	var pad = jQuery(activeItem).width();
	
	// More than one per tab
	menu.style.paddingLeft = pad + "px";
	
	// For every line exept the last
	for(var i=0; i < lines-1; i++){
		// Move first of the line
		otherItems[i*perLine].style.marginLeft = ((i+1)*pad*(-1)) + "px";
		otherItems[i*perLine].style.marginTop = (i*tabHeight) + "px";
	}
	
	return;
};

$( window ).resize(updateAllTabs);
$('a[data-toggle="tab"]').on('shown.bs.tab', updateTabs);
updateAllTabs();
.nav-tabs > li{
  width: 140px;
  height: 42px;
}

@media only screen and (max-width:  840px) {
  .nav-tabs{
    position: relative;
  }
  .nav-tabs > li.active{
    position: absolute;
    bottom: -1px;
    left: 0px;
  }
}
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

<div>

  <!-- Nav tabs -->
  <ul class="nav nav-tabs" role="tablist">
    <li role="presentation" class="active"><a href="#tab1" aria-controls="home" role="tab" data-toggle="tab">Tab 1</a></li>
    <li role="presentation"><a href="#tab2" aria-controls="profile" role="tab" data-toggle="tab">Tab 2</a></li>
    <li role="presentation"><a href="#tab3" aria-controls="messages" role="tab" data-toggle="tab">Tab 3</a></li>
    <li role="presentation"><a href="#tab4" aria-controls="settings" role="tab" data-toggle="tab">Tab 4</a></li>
    <li role="presentation"><a href="#tab5" aria-controls="settings" role="tab" data-toggle="tab">Tab 5</a></li>
    <li role="presentation"><a href="#tab6" aria-controls="settings" role="tab" data-toggle="tab">Tab 6</a></li>
  </ul>

  <!-- Tab panes -->
  <div class="tab-content">
    <div role="tabpanel" class="tab-pane active" id="tab1">This is the tab 1</div>
    <div role="tabpanel" class="tab-pane" id="tab2">This is the tab 2</div>
    <div role="tabpanel" class="tab-pane" id="tab3">This is the tab 3</div>
    <div role="tabpanel" class="tab-pane" id="tab4">This is the tab 4</div>
    <div role="tabpanel" class="tab-pane" id="tab5">This is the tab 5</div>
    <div role="tabpanel" class="tab-pane" id="tab6">This is the tab 6</div>
  </div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

那么,这是如何运作的?

基本思路是每次激活新标签时, 我们将有效标签设为position: absolute; left: 0px; bottom: -1px; 然后我们添加选项卡菜单填充等于选项卡的宽度。 最后,我们在每行的第一个标签上添加一个边距减去标签的宽度。

更多信息:

即使有超过2行标签,代码也能正常工作。

通过在otherItems数组上添加假项目并在previus项目上添加margin-right,可以轻松转换为与上一张图片的布局相匹配。 (得到了吗?或者我必须为你编码?:P)

答案 1 :(得分:1)

试试这个解决方案: https://jsfiddle.net/DTcHh/22583/

CSS

.nav-tabs { border-bottom: 2px solid #DDD; }
.nav-tabs > li.active > a, .nav-tabs > li.active > a:focus, .nav-tabs > li.active > a:hover { border-width: 0; }
.nav-tabs > li > a { border: none; color: #666; }
.nav-tabs > li.active > a, .nav-tabs > li > a:hover { border: none; color: #4285F4 !important; background: transparent; }
.nav-tabs > li > a::after { content: ""; background: #4285F4; height: 2px; position: absolute; width: 100%; left: 0px; bottom: -1px; transition: all 250ms ease 0s; transform: scale(0); }
.nav-tabs > li.active > a::after, .nav-tabs > li:hover > a::after { transform: scale(1); }
.tab-nav > li > a::after { background: #21527d none repeat scroll 0% 0%; color: #fff; }
.tab-pane { padding: 15px 0; }
.tab-content{padding:20px}

<强>更新 我做了一些改进,添加了一些jquery。现在看看小提琴。

var active = $('.nav-tabs > li.active').html(),
    last = $('.nav-tabs > li:last-child').html();
    $('.nav-tabs > li.active').removeClass('active').html(last);
    $('.nav-tabs > li:last-child').addClass('active').html(active); 
    last = active;
    $('.nav-tabs li').on('click', function(){
        active = $(this).html();
        last = $('.nav-tabs > li:last-child').html();
        $(this).removeClass('active').html(last);
        $('.nav-tabs > li:last-child').addClass('active').html(active);      
        last = active;
    });

答案 2 :(得分:1)

我也面临同样的问题,我找到了解决方案。我认为这对你有帮助。

注意:在处理引导标签时,它在移动设备上没有响应标签,因此必须使用可折叠网格启动,如下所述...

这是我以前经历的。

这是我的代码链接。

codepen.io/nehemc/pen/RRQKZB

以下是代码,您需要在javascript中添加。

<script>
    var fakewaffle = (function($, fakewaffle) {
          'use strict';

          fakewaffle.responsiveTabs = function(collapseDisplayed) {

            fakewaffle.currentPosition = 'tabs';

            var tabGroups = $('.nav-tabs.responsive');
            var hidden = '';
            var visible = '';
            var activeTab = '';

            if (collapseDisplayed === undefined) {
              collapseDisplayed = ['xs', 'sm'];
            }

            $.each(collapseDisplayed, function() {
              hidden += ' hidden-' + this;
              visible += ' visible-' + this;
            });

            $.each(tabGroups, function(index) {
              var collapseDiv;
              var $tabGroup = $(this);
              var tabs = $tabGroup.find('li a');

              if ($tabGroup.attr('id') === undefined) {
                $tabGroup.attr('id', 'tabs-' + index);
              }

              collapseDiv = $('<div></div>', {
                'class': 'panel-group responsive' + visible,
                'id': 'collapse-' + $tabGroup.attr('id')
              });

              $.each(tabs, function() {
                var $this = $(this);
                var oldLinkClass = $this.attr('class') === undefined ? '' : $this.attr('class');
                var newLinkClass = 'accordion-toggle';
                var oldParentClass = $this.parent().attr('class') === undefined ? '' : $this.parent().attr('class');
                var newParentClass = 'panel panel-default';
                var newHash = $this.get(0).hash.replace('#', 'collapse-');

                if (oldLinkClass.length > 0) {
                  newLinkClass += ' ' + oldLinkClass;
                }

                if (oldParentClass.length > 0) {
                  oldParentClass = oldParentClass.replace(/\bactive\b/g, '');
                  newParentClass += ' ' + oldParentClass;
                  newParentClass = newParentClass.replace(/\s{2,}/g, ' ');
                  newParentClass = newParentClass.replace(/^\s+|\s+$/g, '');
                }

                if ($this.parent().hasClass('active')) {
                  activeTab = '#' + newHash;
                }

                collapseDiv.append(
                  $('<div>').attr('class', newParentClass).html(
                    $('<div>').attr('class', 'panel-heading').html(
                      $('<h4>').attr('class', 'panel-title').html(
                        $('<a>', {
                          'class': newLinkClass,
                          'data-toggle': 'collapse',
                          'data-parent': '#collapse-' + $tabGroup.attr('id'),
                          'href': '#' + newHash,
                          'html': $this.html()
                        })
                      )
                    )
                  ).append(
                    $('<div>', {
                      'id': newHash,
                      'class': 'panel-collapse collapse'
                    })
                  )
                );
              });

              $tabGroup.next().after(collapseDiv);
              $tabGroup.addClass(hidden);
              $('.tab-content.responsive').addClass(hidden);

              if (activeTab) {
                $(activeTab).collapse('show');
              }
            });

            fakewaffle.checkResize();
            fakewaffle.bindTabToCollapse();
          };

          fakewaffle.checkResize = function() {

            if ($('.panel-group.responsive').is(':visible') === true && fakewaffle.currentPosition === 'tabs') {
              fakewaffle.tabToPanel();
              fakewaffle.currentPosition = 'panel';
            } else if ($('.panel-group.responsive').is(':visible') === false && fakewaffle.currentPosition === 'panel') {
              fakewaffle.panelToTab();
              fakewaffle.currentPosition = 'tabs';
            }

          };

          fakewaffle.tabToPanel = function() {

            var tabGroups = $('.nav-tabs.responsive');

            $.each(tabGroups, function(index, tabGroup) {

              // Find the tab
              var tabContents = $(tabGroup).next('.tab-content').find('.tab-pane');

              $.each(tabContents, function(index, tabContent) {
                // Find the id to move the element to
                var destinationId = $(tabContent).attr('id').replace(/^/, '#collapse-');

                // Convert tab to panel and move to destination
                $(tabContent)
                  .removeClass('tab-pane')
                  .addClass('panel-body fw-previous-tab-pane')
                  .appendTo($(destinationId));

              });

            });

          };

          fakewaffle.panelToTab = function() {

            var panelGroups = $('.panel-group.responsive');

            $.each(panelGroups, function(index, panelGroup) {

              var destinationId = $(panelGroup).attr('id').replace('collapse-', '#');
              var destination = $(destinationId).next('.tab-content')[0];

              // Find the panel contents
              var panelContents = $(panelGroup).find('.panel-body.fw-previous-tab-pane');

              // Convert to tab and move to destination
              panelContents
                .removeClass('panel-body fw-previous-tab-pane')
                .addClass('tab-pane')
                .appendTo($(destination));

            });

          };

          fakewaffle.bindTabToCollapse = function() {

            var tabs = $('.nav-tabs.responsive').find('li a');
            var collapse = $('.panel-group.responsive').find('.panel-collapse');

            // Toggle the panels when the associated tab is toggled
            tabs.on('shown.bs.tab', function(e) {

              if (fakewaffle.currentPosition === 'tabs') {
                var $current = $(e.currentTarget.hash.replace(/#/, '#collapse-'));
                $current.collapse('show');

                if (e.relatedTarget) {
                  var $previous = $(e.relatedTarget.hash.replace(/#/, '#collapse-'));
                  $previous.collapse('hide');
                }
              }

            });

            // Toggle the tab when the associated panel is toggled
            collapse.on('shown.bs.collapse', function(e) {

              if (fakewaffle.currentPosition === 'panel') {
                // Activate current tabs
                var current = $(e.target).context.id.replace(/collapse-/g, '#');
                $('a[href="' + current + '"]').tab('show');

                // Update the content with active
                var panelGroup = $(e.currentTarget).closest('.panel-group.responsive');
                $(panelGroup).find('.panel-body').removeClass('active');
                $(e.currentTarget).find('.panel-body').addClass('active');
              }

            });
          };

          $(window).resize(function() {
            fakewaffle.checkResize();
          });

          return fakewaffle;
        }(window.jQuery, fakewaffle || {}));

        (function($) {
          fakewaffle.responsiveTabs(['xs', 'sm']);
        })(jQuery);
        $(document).ready(function() {
          $('.tabcontainer .accordion-toggle').click(function() {
            var divTarget = $(this).attr('href'),
              divTargetElt = $(this);

            setTimeout(function() {
              console.log(divTarget);
              $('html,body').animate({
                  scrollTop: divTargetElt.offset().top
                },
                'slow');
            }, 500);
          });
        });
    </script>

答案 3 :(得分:0)

我对你实际想要实现的目标感到有些困惑。但我做了这个解决方案来隐藏部分非活动标签(并使它们部分重叠/堆叠)。我使用了默认的bootstrap示例。解释在代码中。使用这种技术,您基本上可以缩小标签,使其适合较小的屏幕。请注意,您可以包装您希望在一段时间内消失的所有内容。

这仍然无法通过极大数量的标签来实现您的目标。在这种情况下,您将不得不使用一些JavaScript来使一些标签消失/重新出现在屏幕的左/右侧。

Example

<强> HTML

<ul class="nav nav-tabs">
  <li role="presentation" class="active"><a href="#">Home <span>I m whatever was missing</span></a></li>
  <li role="presentation"><a href="#">P<span>rofile</span></a></li>
  <li role="presentation"><a href="#">M<span>essages</span></a></li>
</ul>
<div id="stuff"></div>

<强> CSS

/*hide all the items after the part you want to show*/
.nav-tabs li span{
  display: none;
}
/*show the items on the parts with the bootstrap .active class*/
li.active span{
  display: inline-block;
}
#stuff{
  background-color: yellow;
  height: 200px;
}
.active a{
  background-color: yellow !important;
}

答案 4 :(得分:0)

不要使用float属性。我认为没有使用float属性的解决方案。你可以通过使用,实现这一点 的风格= “位置是:固定;”
我写了一些东西。希望它会对你有所帮助。

<强> CSS



    ul {
        list-style-type: none;
        margin: 0;
        padding: 0;
        background-color: #333;
        width:800px;
        height:45px; width:100%;
    }
    li a {
        position:fixed;
        color: white;
        text-align: center;
        padding: 14px 16px;
        text-decoration: none;

    }

    li a:hover:not(.active) {
        background-color: #111;
    }

    .active {
        background-color: #4CAF50;
    }


HTML

  <html>
    <body>
    <ul >
      <li><a class="active" href="#home">Tab1</a></li>
      <li><a href="#n2" style="left:80px;" >Tab2</a></li>
      <li><a href="#n3" style="left:160px;">Tab3</a></li>
      <li><a href="#n4" style="left:240px;">Tab4</a></li>
      <li><a href="#n5" style="left:320px;">Tab5</a></li>
      <li><a href="#n6" style="left:400px;">Tab6</a></li>
      <li><a href="#n7" style="left:480px;">Tab7</a></li>
      <li><a href="#n8" style="left:560px;">Tab8</a></li>
      <li><a href="#n9" style="left:640px;">Tab9</a></li>
      <li><a href="#n10" style="left:720px;" >Tab10</a></li>
    </ul>
    </body></html>

答案 5 :(得分:0)

计算添加到li的行索引添加。在初始化或活动选项卡更改时,它会排序li位置,直到它位于底行。

希望这是你想要实现的目标。

演示:http://codepen.io/anon/pen/GqQdyb

HTML     
      

    <div class="col-md-12">

      <ul id="tabs" class="nav nav-tabs" role="tablist">
        <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">Tab 1</a></li>
        <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Tab 2</a></li>
        <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">Tab 3</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 4</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 5</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 6</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 7</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 8</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 9</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Tab 10</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Profile</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Message</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Very long tab name</a></li>
        <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Programming</a></li>
      </ul>

      <!-- Tab panes -->
      <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="home">...</div>
        <div role="tabpanel" class="tab-pane" id="profile">...</div>
        <div role="tabpanel" class="tab-pane" id="messages">...</div>
        <div role="tabpanel" class="tab-pane" id="settings">...</div>
      </div>      
    </div>    
  </div>  
</div>

JS

$( function() {  
    var _max = 0;  

    var _calc = function() {
      var _w = $('#tabs').width();
      var _h = $('#tabs').height();  
      var _a = _w;  

      var _index = 0;
      $('#tabs li').each(function(i, v) {            
        var _t = $(v).outerWidth();      
        if(_a < _t) {
          _a = _w;
          _index++;
        }
        $(v).data('rowindex', _index);      
        _a -= _t;      
      });

      _max = _index;
      console.log(_max);
    };



    var _sortTab = function() {      
      var _active = $('li.active').data('rowindex');      
      var _tabs = $('#tabs');
      _tabs.find('li').sort(function(a, b) {        
        var _a = $(a).data('rowindex');
        var _b = $(b).data('rowindex');        
        return (_a == _active && _a !== _b);
      }).appendTo(_tabs);      
      _calc();

      if(_active !== _max) {
        _sortTab();
      }      
    };


  $('#tabs li').on('shown.bs.tab', function (e) {  
    _sortTab();
  });  
  _calc();
  _sortTab();  
});

答案 6 :(得分:-1)

长列表选项卡不适合固定的小屏幕,因此只能在第二行显示选项卡,这是默认行为。

另一个将在下拉菜单中显示其他标签。像here

这样的东西

这是在bootply中创建的一个很好的例子。 click for code