denislexic
denislexic

Reputation: 11382

Twitter Bootstrap Accordion and button dropdown overflow issue

I'm using Bootstrap for a section of my website. I mix accordion with a dropdown button. The problem comes when the button is on the bottom, the drop-down is hidden since the .accordion-body overflow is set to hidden.

You can view jsfiddle here: http://jsfiddle.net/DBQU7/6/

So I did what you would expect, tried to do overflow-y:visible. But then you can see the result here, it doesn't work: (You can maybe also notice that the drop-down is inside the div, which creates a scroll bar inside the div instead of just showing up.

http://jsfiddle.net/DBQU7/5/

I saw this question that was similar: Twiiter Bootstrap (Button Dropdown) + Div Fixed

But it doesn't fix the problem as I mentioned above.

So the question is, how can I just make the dropdown show up normally.

Thanks.


The only solution I have found so far (and I would be happy to be proved wrong) was to add a CSS property that made the overflow visible when it was open and then through a JS script make it toggle between visible and hidden...not ideal, but nothing better so far.

-- Edited -- It actually doesn't work very well and doesn't seem to be a viable solution.

Upvotes: 20

Views: 25059

Answers (10)

zadarum
zadarum

Reputation: 21

If you have found your way here looking for help with getting the Bootstrap button dropdown to work inside of jqgrid (from the linked question), the answer turns out to be dead simple. First, in the colModel entry for your button column, set a css class using the 'classes' attribute, then add a line to your css file to make the style for that class overflow: visible. As a bonus, if you set title: false in the colModel entry, you will get rid of the tooltip hover on your button.

So:

colModel:[...
    {name:"Action", index:"RecID", classes:"actionTD", title:false, label:"Action", width: 80, fixed: true, sortable:false, align: 'center', formatter: 'actionFormatter'}

and:

.ui-jqgrid tr.jqgrow td.actionTD {overflow: visible;}

Upvotes: 2

Will
Will

Reputation: 324

This is the first result for this issue in Google, so I'm going to repost this here on behalf of the bootstrap community. According to the bootstrap team, this problem should be fixed in 3.0; below is the recommended interim solution:

In boostrap.js, alter the transition function:

, complete = function () {
        if (startEvent.type == 'show') that.reset()
        that.transitioning = 0
        that.$element[method]('fully').trigger(completeEvent)
      }

in boostrap.css, add this class:

.collapse.in.fully
{
    overflow:visible;
}

I've tested this in IE8, 9, and 10, FF 11 & 12. Those are all the browsers allowed on our network, but if it functions in IE8 and FF11, chances are good it'll work everywhere. I had problems with the accepted solution in FF11.

source: twitter github issue #3601

Upvotes: 0

eaj
eaj

Reputation: 2618

I know I'm seven months late to this party, but maybe someone else will find this helpful.

The cleanest solution I've found to this problem is to use the Bootstrap event handlers on the accordion. It's still kind of kludgy, but IMO it's less hackish than the accepted answer by ScottS (which I think would be better if not for the behavior in Chrome).

$(document).ready(function() {
  $('.accordion-body').on('shown', function() {
    $(this).css('overflow', 'visible');
  });
  $('.accordion-body').on('hide', function() {
    $(this).css('overflow', 'hidden');
  });
});

Upvotes: 1

VUE-fr
VUE-fr

Reputation: 121

Another solution which seems to work in every browsers :

.accordion-body[class*="in collapse"]{ overflow:visible;}

Upvotes: 12

ScottS
ScottS

Reputation: 72261

Original Idea

You were very close with your solution. This is it:

.accordion-body.in { overflow:visible; }

The .in class is added when opened, and thus only sets visibility when open.

See the example fiddle.

Update That May Help with Chrome Bug

The bug mg1075 notes below can be solved by a slight change to the code above, like so:

.accordion-body.in:hover { overflow:visible; }

This essentially prevents the overflow from occurring before the animation is complete. It works well, except that when you click your down button to open the dropdown, and then exit the .accordion-body it will crop off the dropdown again, but only until you mouseover the dropdown area again. Some might consider the behavior preferable.

See the fiddle with the update code.

Upvotes: 39

Ray
Ray

Reputation: 2728

This is all you should need to add to make the dropdown menu show:

#collapseThree {
 overflow: visible;   
}​

http://jsfiddle.net/DBQU7/6/

Upvotes: 0

artlung
artlung

Reputation: 33823

So here's a partial solution. This does make the dropdown go upward on purpose. Making it a dropup.

Here's the CSS rule to add:

.btn-group.open-upward.open ul.dropdown-menu {
    top: auto;
    bottom: 100%;
}

So the class to add is open-upward

<div class="btn-group open-upward">
  <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
    Action
    <span class="caret"></span>
  </a>
  <ul class="dropdown-menu">
    <!-- dropdown menu links -->
      <li>Dropdown stuff</li>
      <li>Dropdown stuff</li>
      <li>Dropdown stuff</li>
      <li>Dropdown stuff</li>
  </ul>
</div>

I say partial because once you add the class, it will go upward. You'd have to remove the class to reverse it back to the default behavior.

Upvotes: 1

mg1075
mg1075

Reputation: 18155

I don't know if you would find this an acceptable alternative solution, or how many items your dropdown would have, but you could use the "dropup" class, so as to make the dropdown menu drop UP instead of down.

http://jsfiddle.net/ecSH4/

<div class="btn-group dropup">

UPDATE

Rather kludgy at this point, yet in a limited sense, it "works".

http://jsfiddle.net/ecSH4/52/

$(".special-drop, .special-drop .caret").click(function() {
    var $myCollapsable = $(this).closest(".collapse"),
        $myDropDown = $(this).closest(".dropdown"),
        $myDropDownMenu = $(this).next(".dropdown-menu");

    function toggleDropMenu() {
        if ($myDropDown.hasClass("open")) {
            $myDropDownMenu.hide();
        } else {
            $myDropDownMenu.show();
        }
    }

    if ($myCollapsable.css("overflow") === "hidden") {
        $myCollapsable.css("overflow", "visible");
        toggleDropMenu();
    } else {
        $myCollapsable.css("overflow", "hidden");
        $myDropDownMenu.hide();
        toggleDropMenu();
    }

});

$(document).click(function() {
   $(".collapse").css("overflow", "hidden");
   $(".dropdown-menu").hide();
});​

Upvotes: 4

Jeffery To
Jeffery To

Reputation: 11936

Set overflow: visible when the menu is open (demo):

$('html').on('click', function() {
    setTimeout(function() {
        $('[data-toggle="dropdown"]').closest('.collapse').css('overflow', '');
    }, 0);
});

$('body').on('click', '[data-toggle="dropdown"]', function() {
    var parent = $(this).parent(), collapse = parent.closest('.collapse');
    setTimeout(function() {
        collapse.css('overflow', parent.hasClass('open') ? 'visible' : '');
    }, 0);
});

There seems to be a redraw issue in Chrome (tested with Chrome 19 on Linux) if we set overflow directly. setTimeout() works around this issue.

Upvotes: 2

baptme
baptme

Reputation: 10092

add an id to the dropdown toggle link.

example:

id="actionButton"

and with jQuery

function actionButtonExpand() {
    var actionButtonDropdownMenuHeight=$(this).parent().children(".dropdown-menu").height()+19;
    var actionButtonAccordionBodyHeight = $(this).parent().parent().parent().height();
    var actionButtonAccordionBodyExtended = actionButtonDropdownMenuHeight+actionButtonAccordionBodyHeight;
        $(this).dropdown();
        if($(this).parent().hasClass("open")){        
            $(this).parent().parent().parent().css("height","");
            $(this).parent().css("margin-bottom","9px");
        } else {
            $(this).parent().parent().parent().height(actionButtonAccordionBodyExtended);
            $(this).parent().css("margin-bottom",actionButtonDropdownMenuHeight);
        }
    }

function actionButtonContract() {
    $("#actionButton").parent().parent().parent().css("height","");
    $("#actionButton").parent().css("margin-bottom","9px");

}                           
$("#actionButton").click(actionButtonExpand);
$(".accordion-toggle").click(actionButtonContract);

http://jsfiddle.net/baptme/6yAnc/

Upvotes: 1

Related Questions