I'm working on a control where you'd have two multi-select lists with collections of items that can be moved between one another.
There's a possibility that the contents of one or both lists will be wider than I'd like the item itself to be, and so I have them each represented by two divs and a select as follows:
<div class="container">
<div class="concealer">
<select size="4">
...
</select>
</div>
</div>
Putting the select within a div allows horizontal scrolling (since select doesn't). The select is resized (size attribute is set) to fit its contents as items are added or removed. The "concealer" div avoid double scroll bars hides the vertical scroll bar on the select, and it is vertically sized when the select changes as well.
I'm using html5. IE9 in standards mode and Firefox are fine. The problem that I'm having is with Chrome (actually Safari as well, so... webkit). If the control is in a window or container (a div for example) with vertical scrolling, and you have it scrolled to the point where you can't see the top of the select, if the bottom of the select is visible (or would be visible in the outer container, if overflow could be seen), when you click an item in the select, causing the select to focus, Chrome scrolls the outer container either to its top or far enough so that the top of the select would be visible if you could see it through the divs which contain it.
As noted, if the bottom-most option in the select is visible in the (containing) window, but the top of the select is not, chrome will scroll.
I have written script to adjust the scrollTop of the scrolled window back to its current position, and that would work, except that I am finding that in my staging and production environments, the adjustment being done by chrome is also causing the actual option selection to happen AFTER chrome has done its own adjustment, which means the click registers on the wrong option (it's off by however much the browser scrolled up), It's a problem whether there's an onfocus event on the select or not.
I haven't been able to get the option select problem to happen in a barebones test like this, but the scrolling itself is a problem.
The only way I've found to prevent this from happening is to size the select to some number that's large enough to put the bottom of the select well outside the bottom of the outer container, but this is not at all ideal, as it leaves lots of whitespace, is a bad user experience, and fights a problem that (while fairly profound) only affects webkit.
Does anyone know how else I might prevent or counteract this behavior?
I did have images to go with this, but understandably, new users can't post images. Here's a js fiddle that should allow you to easily reproduce the issue: http://jsfiddle.net/4N9Kg/22/
In the address bar, type chrome://flags and press enter. In the Flags tab, search for the Smooth Scrolling setting. You can do this manually in the Available tab or use the search bar to find it. Once you've located it, press the drop-down menu next to the feature and select Enabled or Disabled.
An element can be focused by either using the autofocus="true" attribute or calling the element. focus() method. In both cases, the browser will automatically scroll the element into the viewport.
To hide the scrollbar and disable scrolling, we can use the CSS overflow property. This property determines what to do with content that extends beyond the boundaries of its container. To prevent scrolling with this property, just apply the rule overflow: hidden to the body (for the entire page) or a container element.
I have a workaround.. (DISCLAIMER: It's a workaround not a solution)
$('#sel').mousedown(function(e){
$(e.target).attr('selected', 'selected'); //select the clicked <option> item
e.preventDefault();
});
DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With