【问题标题】:When screen size made smaller bootstrap tabs are overlapping当屏幕尺寸变小时,引导选项卡重叠
【发布时间】:2016-09-13 10:48:40
【问题描述】:

当屏幕尺寸变小时,引导选项卡会像图像一样重叠。

我使用了col-sm,我的 Angular HTML 是这样的(但任何非 Angular HTML 解决方案也可以):

<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>

我希望其他选项卡堆叠在后台而不是前台。

请原谅我糟糕的 gimp 技能,但活动标签应该总是在前面,所以如果选择了标签 3,那么另一行应该移到后面。

它不必像这样专门安排,但关键是活动选项卡与其内容窗格之间不应有任何东西,所以这样的东西也可以:

【问题讨论】:

  • 好的,所以......他们包装......你想让他们做什么?
  • 嗨@KevinB 我添加了一个可能解决方案的屏幕截图
  • toggle-switch......你在用bootstrap-switch.js吗?
  • @ncd275 除了 angular-js 之外,它看起来像它,但我很乐意只为引导选项卡提供答案。
  • 看这个jsfiddle.net/obliviga/gpavt9h0 把内容变成折叠组件

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


【解决方案1】:

有一个结合 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 数组上添加假项目并在前一个项目上添加 margin-right ,可以轻松地将其转换为与上一张图像的布局相匹配。 (明白了吗?或者我必须为你编码?:P)

【讨论】:

  • 这可能是在正确的路径上,但是在保持标签与其内容同步方面存在一个错误 - 点击标签 6 显示标签 5 的内容,点击 4 显示 3,等等。
  • 问题已解决。错误的 html 属性 :)
【解决方案2】:

试试这个解决方案: 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;
    });

【讨论】:

  • 这是一个很好的解决方案,但我认为当标签页结束时,最终用户会感到有些困惑。有没有办法可以调整此解决方案以使其出现在开头?我意识到您可能想为它发布另一个答案,因为它可能会大不相同,因为这个答案取决于现有的堆栈 - 而不是将非活动标签移到后面。
【解决方案3】:

我也遇到了同样的问题,我已经解决了这个问题。我想这对你很有帮助。

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

这是我以前经历过的。

这是我的代码链接。

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>

【讨论】:

    【解决方案4】:

    我对您实际想要达到的目标感到有些困惑。但是我做了这个解决方案来隐藏部分非活动选项卡(并使它们部分重叠/堆叠)。我使用了默认的引导示例。解释在代码中。使用这种技术,您基本上可以使标签更小,以便它们适合更小的屏幕。请注意,您可以将想要消失的所有内容包装在一个跨度中。

    对于大量标签,这仍然无法满足您的需求。在这种情况下,您将不得不使用一些 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;
    }
    

    【讨论】:

      【解决方案5】:

      不要使用浮动属性。我认为没有使用浮动属性的解决方案。您可以通过使用
      style="Position:Fixed;" 来实现这一点
      我写了一些东西。希望对你有帮助。

      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>
      

      【讨论】:

        【解决方案6】:

        计算添加到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();  
        });
        

        【讨论】:

          【解决方案7】:

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

          另一个是在下拉菜单中显示附加选项卡。类似here

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

          【讨论】:

          • 您的假设 “唯一的方法是在第二行显示选项卡” 可能是正确的,但问题是如何在后台显示第二行而不是前景。
          • 谢谢@Jeff 的解释
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-19
          • 2020-11-03
          相关资源
          最近更新 更多