chosen icon indicating copy to clipboard operation
chosen copied to clipboard

Chosen gets "cut" when placed in area with "overflow:hidden".

Open ethaniel opened this issue 12 years ago • 129 comments

I have a div with a form. The div has "overflow:hidden" option in the css. When Chosen gets created, and it goes below the bottom line of the div, it gets cut.

Here is a screenshot:

Imgur

ethaniel avatar Jul 27 '11 13:07 ethaniel

This is the same as issue #59

reconbot avatar Jul 27 '11 13:07 reconbot

Isn't this unavoidable since the container element, is well, "overflow :hidden" that's just how CSS works. The only way around this is to render the drop down outside of the container and then use absolute positioning.

dfischer avatar Jul 28 '11 19:07 dfischer

Yeah, I agree with dfischer. Doesn't seem like a Chosen issue. By definition, the overflow property specifies what happens if content overflows an element's boundaries. If you don't want it the overflow to be hidden, then change that property.

johnnyfreeman avatar Jul 28 '11 21:07 johnnyfreeman

While true, I think this is a common use case with dialog boxes. (Especially jquery dialog)

reconbot avatar Jul 28 '11 21:07 reconbot

It is a common use case, however based on this ticket, like I previously mentioned... the entire structure and implementation has to change if you want to accomplish this.

You are required to render outside of the container for this to happen and then use jQuery/JS magic to figure out the positioning relative to the trigger.

jQuery Dialog's case doesn't depend upon a container element so it just uses positioning based on center dimensions and width of the dialog.

dfischer avatar Jul 28 '11 21:07 dfischer

This is more of a CSS issue, not a Chosen issue. Don't put overflow: hidden on the container. You're going to have to use another technique to clear the floats below it if that's what you're doing.

dfischer avatar Jul 28 '11 21:07 dfischer

I just wrote some code which I think does what you're looking for:

$.fn.extend({ chosen: function (data, options) { if ($(this).parent().css("overflow") == "hidden") { //get the offsets between parent and child to calculate the diff //when we push to absolute var y = $(this).offset().top - $(this).parent().offset().top, x = $(this).offset().left - $(this).parent().offset().left, $t1 = $("<div/>", { css: { "position": "relative", "height": $(this).parent().height, "width": $(this).parent().width } }), $t2 = $("<div/>", { css: { "position": "absolute", "top": y, "left": x } }); $t1.insertBefore($(this).parent()); $(this).parent().appendTo($t1); $t2.appendTo($t1); $(this).appendTo($t2); } return $(this).each(function (input_field) { if (!($(this)).hasClass("chzn-done")) { return new Chosen(this, data, options); } }); } });

(btw I'm new to github as of today so if there is a different place where I should be posting code let me know)

That code effectively does the following:

  1. calculate the offset between the select box and the parent.
  2. create a parent div with the same dimensions as your overflow hidden and set to relative.
  3. create a parent for the select box creating the element as absolute using the x and y offsets from step 1.
  4. insert new parent before the select's parent, append the overflow div inside of the new parent, append that new select parent inside of the master parent, append the select to the new child parent.

medelbrock avatar Jul 28 '11 21:07 medelbrock

Interesting idea Matthew, but I think that's not going to work in a jQuery-UI dialog is it?

It's more likely that the dropdown element (.chzn-drop) needs to be pulled out of the .chzn-container and up to the document body...

tompaton avatar Jul 29 '11 09:07 tompaton

Just add a style to the page and your answer is yes:

.ui-dialog{ overflow:visible; }

medelbrock avatar Jul 29 '11 13:07 medelbrock

Doesn't work for me, since I create my pages using div's as columns (as opposed to td's and tables). I use "overflow:hidden" to stop runaway content from ruining neighbour divs.

I suppose many of you use the same structure.

ethaniel avatar Jul 29 '11 13:07 ethaniel

That won't work, as the dialogs are set to overflow:auto so they can have scrollbars if necessary.

On Fri, Jul 29, 2011 at 11:47 PM, ethaniel [email protected] wrote:

Doesn't work for me, since I create my pages using div's as columns (as opposed to td's and tables). I use "overflow:hidden" to stop runaway content from ruining neighbour divs.

I suppose many of you use the same structure.

Reply to this email directly or view it on GitHub: https://github.com/harvesthq/chosen/issues/86#issuecomment-1681303

tompaton avatar Jul 29 '11 13:07 tompaton

Before we get any further into this conversation, what I've done is a theoretical fix. It can't be applied to all scenarios because all it takes is one element having a counter-attribute to screw it up. The above solution with the overflow visible will only work with dialog option resizable:false. Why would you need to have a select overflow outside of a dialog?

medelbrock avatar Jul 29 '11 13:07 medelbrock

Ok, here are a bunch of screenshots which hopefully clarify the issue.

http://i.imgur.com/9ZY9O.png http://i.imgur.com/c2PLo.png http://i.imgur.com/1oqZ7.png http://i.imgur.com/ZBrQj.png

Screenshots 1 & 2 show how it behaves, there isn't enough space for the dropdown "inside" the dialog, so it scrolls and is hidden as a result. This is very clunky to use and ugly and not how the built in select controls work (they show over the top of the content, no matter how deep inside it they are or what it's overflow style is.)

Screenshots 3 & 4 show my current work-around, which is to put a whole heap of space below the dropdown. This is also ugly and makes the form harder to use.

So, to summarise, the real point is that native select controls aren't restricted to their parent container and if it's possible, the chosen enhanced select control shouldn't be either, since it's designed to be a drop-in replacement for the native control.

tompaton avatar Jul 29 '11 14:07 tompaton

This theoretically can be done but it would require a completely different construction/positioning system by the chosen plugin. This change would be extensive and require about a 30% rewrite of the current plugin. I consider this a feature request and not a bug. All browsers have a default render for select elements.Chosen replicates it using divs but is not treated like a select element.

medelbrock avatar Jul 29 '11 17:07 medelbrock

Like I said, the only way to do this is absolute positioning OUTSIDE of the triggered element. There's no other way. Correct on @medelbrock

dfischer avatar Jul 29 '11 20:07 dfischer

While it would be very nice to have chosen behave like a browser widget, I agree this should be considered a feature not a bug. Can we currently set a max height?

reconbot avatar Jul 29 '11 22:07 reconbot

@veloper: I gave that a go (as best I could) and it didn't seem to help. I can't see how it would work either, as the div.chzn-drop is still contained in the dialog, so will be clipped regardless of whether it is absolutely positioned or not.

The only way to stop that is going to be to pull the div.chzn-drop out of the dialog and make it a child of <body>, but as everyone is pointing out, that is a bigger change than anyone is willing to get their hands dirty trying.

tompaton avatar Aug 02 '11 09:08 tompaton

Unfortunately using overflow:visible isn't an option, the dialog needs to be scrollable if necessary.

tompaton avatar Aug 05 '11 09:08 tompaton

I think I've solved the issue by setting the drop down position to absolute and whenever showing the drop down setting it's position. e.g. Changing (editing the javascript)

this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
});

to

var parent = this.dropdown.parent();
var offset = parent.offset();
dd_top = offset.top + parent.outerHeight();
dd_width = parent.width();
this.dropdown.css({
    "top": dd_top + "px",
    "left": offset.left,
    "width": dd_width + "px"
});

chris-herring avatar Aug 15 '11 01:08 chris-herring

I'm running into this problem myself while trying to make Chosen work inside a Wijmo / jQuery UI Dialog. I may be way out of my league here, but isn't there a fairly simple fix of making the "dropdown" portion have "display: none" while hidden, and then "display: block" when shown? You'd still incur the scroll bars when the dropdown is open, but that's probably better than having the scroll bars always present.

Polemarchus avatar Aug 18 '11 22:08 Polemarchus

The fix (tested in Chrome 13, Firefox 7 and IE 9) :

In chosen.css:

.chzn-container .chzn-drop { position: fixed; }

and in Chosen.prototype.results_show

var offset = this.container.offset(); this.dropdown.css({ "top": (offset.top+dd_top) + "px", "left": offset.left + "px", "display": "block" });

http://img30.imageshack.us/img30/4094/chosen3.png

levushka avatar Sep 05 '11 01:09 levushka

That's the stuff, good thinking @levushka. Resolved now in my branch: https://github.com/tompaton/chosen/commit/fda07051161f3fffe6049362b6c9b66ffbe857d1

tompaton avatar Sep 05 '11 11:09 tompaton

Ok, it's a little more complicated than that. The above fix didn't work if the page was scrolled.

I've updated my repo with a changeset that sort of fixes it, the dropdown is positioned correctly now, but if the page is scrolled while the dropdown is visible it doesn't move as expected. That's annoying, but not a show stopper.

tompaton avatar Sep 06 '11 09:09 tompaton

iOS 5 might solve this, but iOS currently doesn't support position: fixed in the same way that desktop browsers do. Chosen works terrifically on the desktop, but this might limit its uses on poorly designed mobile browsers...

I'm not just picking on Apple here, older version of Android also lack support for position: fixed.

jokeyrhyme avatar Sep 06 '11 23:09 jokeyrhyme

As of jQuery 1.7 (not yet released, but in release candidate) they have a built-in test for CSS Position Fixed support: http://bugs.jquery.com/ticket/6809

Might be worth detecting jQuery 1.7 and using their result, or copying their code and getting a separate result otherwise.

jokeyrhyme avatar Oct 02 '11 07:10 jokeyrhyme

+1 for position at the end of body element.

check the jquery widget "autocomplete". pretty good solution for that problem:

http://jqueryui.com/demos/autocomplete/

great plugin by the way.

fluxsaas avatar Nov 09 '11 13:11 fluxsaas

I had this issue mostly in webkit browsers. IE just goes mental with chosen, so i disabled it if ie. Using jquery, i check if the browser is a webkit one, and adjust the overflow of the div containing my chosens like so:

if($.browser.webkit) $(this).css("overflow",($(this).is(":visible"))?"visible":"hidden");

where this is the div containing the chosens.

frostyoni avatar Dec 08 '11 04:12 frostyoni

+1 @levushka and @tompaton Not perfect, but good enough-ish. Barely :)

JonoB avatar Mar 07 '12 17:03 JonoB

@levushka solution is great, but it is global ... so at window.top when you scroll down and click to chosen, it roll down in wrong position. So here is solutuion for normal pages and popup windows

in Chosen.prototype.results_show

replace:

  this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
  });

with:

if($('.popup').length!=0) {

  var offset = this.container.offset();
  this.dropdown.css({
    "top": (offset.top+dd_top) + "px",
    "left": offset.left + "px",
    "display": "block"
  });

} else {

  this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
  });

}

CSS:

   .popup .chzn-container .chzn-drop { position:fixed; }

If you are using jQuery UI or something else, you can have problems with z-index, so set chosen z-index to higher values (jQuery UI is it 1010+)

Now it is wokring in FF and for Chrome you need:

     .popup { overflow-x:visible; overflow-y:visible; }

lover elements can have overlow:hidden with no problems.

Evandar276 avatar Mar 29 '12 14:03 Evandar276

Why not render the dropdown in the body and use Jquery UI's position function to position the box? http://jqueryui.com/demos/position/. This is the standard method used for many jquery ui widgets.

$( ".czn-drop" ).position({ of: $( "#container" ), my: "left top", at: "left bottom", });

pohnean avatar Apr 22 '12 19:04 pohnean