needed a way to force redraw of <select>s in MSIE8
Asked Answered
C

4

15

with (simulated) media queries I'm changing font-size of <select>s in my page

I have problems with other browsers too, but I resolved temporarily detaching the elements from DOM and re-attaching them after a small amount of time

but with MSIE8 I still have problems with height of <option>s which is equal to the max fontSize set, even if it's not applied anymore

http://fiddle.jshell.net/U3bzT/show/light/

expected result:

the font-size is updated while switching from a bigger font size to a smaller one

but not the line-height/height of <option>s

happens to both select-multiple and select-one

how can I fix this?

Note: <select>s may have events attached, so I can't use a copy

<script>

// just some code to simulate media query on/off state
var select;

setTimeout(function(){

    select = document.getElementsByTagName("select")[0];

    select.style.fontSize='40px';
    webkitFix();

    setTimeout(function(){
        select.style.fontSize='10px';
        webkitFix();
    },5000);

},5000);

function webkitFix(){
    document.body.removeChild(select);
    setTimeout(function(){ document.body.appendChild(select); }, 1);
}

</script>

<select multiple size="6" style="font-size:10px">
    <option>AAAAAA1</option>
    <option>BBBBBB2</option>
    <option>AAAAAA3</option>
    <option>BBBBBB4</option>
    <option>AAAAAA5</option>
    <option>BBBBBB6</option>
    <option>AAAAAA7</option>
    <option>BBBBBB8</option>
    <option>AAAAAA9</option>
</select>
Charlie answered 18/8, 2013 at 5:3 Comment(20)
Maybe I wasn't following properly, but why can't you just manually reset the line-height to its proper value?Shreeves
i didn't set the line-height at all, i just changed the font-size - I can set line-height:normal or line-height:1 but nothing changesCharlie
Try setting every possible CSS property to near zero (not zero; sometimes it doesn't like zeros). line-height: 1px; padding: 1px; margin: 1px. And whatever other spacing properties might exist. If all of the text ends up nearly piling up, then you've hit the right property. Remove them one by one to identify the culprit. It doesn't matter if you didn't change those properties. Don't underestimate the nonsense a browser can unexpectedly poop on you.Shreeves
is there a reason why you're not using jQuery?Brackish
Odd, it looks fine to me using IE10 in IE8 standards mode.Gravure
@RobertMcKee: IE8 mode != IE8Brackish
@WouterHuysentruit They act the same in all but a very select few cases, but yes, they aren't exactly the same.Gravure
It's reproducible in IETester if you want to tryCharlie
I'm a little surprised that no one has actually mentioned that this is a very old problem, that to this day remains impossible to implement in IE 5.5, 6, 7 and to some extents in 8 without polyfills / replacement. I'm sorry to say it Wes but there is no answer that anyone can give you that will solve this specific problem in <= IE8Nerve
@WouterHuysentruit: IE8 mode !== IE8 #javascriptAllodium
I pretty much agree with @DavidBarker. I've occasionally been able to solve specific IE select box bugs in the past, but often the answer is either live with it or go nuclear. ("Go nuclear" = wild, ugly hacks, completely reimplementing select etc…)Destruct
Normally I think StackOverflow comments of the ilk of "just use jQuery" are a dereliction of duty, but the truth is this is an ancient problem. Select boxes are rubbish — get over it. Why not simply take a solution which creates a fully-stylable DHTML interface for the select box? It's far less effort than the immense amount of time you could sink into finding a hacky way to enable your line-height issue. Select 2 is generally held up as a model of what select boxes should be.Hebetate
If you have to use select boxes, then use 2 of them, one with small font and one with bigger font, make them the same class, have the same events attached to both of them and just show/hide instead of changing fontsWalkway
you, gentlemen, are arcadian sissiesCharlie
@DavidBarker I've just tried the jsfiddle link on IE7, surprisingly, it works fine!Hutchison
@Hutchison yes it does -- this is a msie8 only issue :(Charlie
@Wes, if you forcibly defines the font-size, height and width of the select box does get it back to the normal? If it does, you could store those values in the attributes of the select to later ajustment.Haleyhalf
Yes it does work in IE7 but have you actually tried styling the select box beyond its font-size in ie7? In a word... don't. :-) IE8 tried to implement select box styling in line with w3c recommendations to an extent but actually broke the parts it tried to fix and the result... problems similar to the one outlined in this question.Nerve
Looks fine on my WinXP IE8 VM... goes from 'expected result' -> (5 seconds) -> First attached image -> (5 seconds) -> 'expected result'Keenan
I have not done this recently, so my note may be wrong under current MSIE (back then it worked for then MSIE7). I used to make a new selectbox via DOM functions (inc re-registering all the event hooks), and swap the old for new. Can't you do this?Particle
N
11

This is, and has been a big headache for a lot of developers over the years. There is no workaround that I have ever found that has fixed this problem without using alternative markup along with mixtures of JS and CSS. This is due to the rigidity of the select box design in Internet Explorer. Once a select box has been rendered by <= IE8, modifying the appearance with class' and/or JS is not actually possible as you have found. Even modifying the select boxes appearance with CSS on render is incredibly limited and has left many developers hunting for alternatives. Thankfully in later versions of IE (of which 8 is much better than 7, though still very lacking) select boxes are far more mutable.

I can point you to a number of resources that back this up, a number of which are on stackoverflow.

A lot of questions pertaining to this are also left unanswered on SO, again for this reason, there is no solution to the problem in the way you wish to solve it.

There are a multitude of workarounds provided that all involve a few of the following techniques.

  • Using <ul>'s, styled to look like select boxes with javascript
  • JS / jQuery solutions that replace select boxes with a mixture of the above and <div> based solutions

For your specific problem you will find yourself consistently banging your head against a brick wall if you don't adopt a DOM replacement technique for IE.

Some resources for you that offer solutions, as well as other answers here that mention the use of jQuery / javascript.

In conclusion, I'm afraid you're problem is unsolvable without using a polyfill for IE or adopting a total select box replacement strategy.

Nerve answered 20/8, 2013 at 13:1 Comment(3)
Well I'm not sure why the downvotes when this is correct, with evidence. At least you could leave a comment on why this is apparently incorrect?Nerve
These kinds of IE problems remind me of the Dr Faustus: « Why, this is hell — nor am I out of it! ». But the thing is, select boxes just aren't very good at all, no matter what browser you're using: they're very inflexible and there's nothing they can do that can't be better achieved with radio or checkboxes and markup. A year ago Paul Irish called on the W3C and browser devs to make a better <select>, recommending Select 2 (an improvement on Chosen).Hebetate
So this question is effectively a duplicate of many questions that has been asked beforeWalkway
O
2

(Note: Please ignore this answer as your edit suggest not to use clone. If anybody face this problem and want to go for cloning use this, which is the reason I am not removing my answer).

If you can manage to put a clone to select tag even though events are attached as desired result is almost not possible with current implementation. Here is the approach with code.

Browser's checked: Chrome 28.0.0 Firefox 22.0 IE 7.0/8.0

  1. Used a clone select for managing the desired result.

CODE:

!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title> - jsFiddle demo</title>

  <script type='text/javascript' src='/js/lib/dummy.js'></script> 

  <link rel="stylesheet" type="text/css" href="/css/result-light.css">

  <style type='text/css'>
  </style>    

<script type='text/javascript'>

window.onload=function(){
var select;

function webkitFix(){
    document.body.removeChild(select);
    setTimeout(function(){ document.body.appendChild(select); }, 1);
}

setTimeout(function(){
    select = document.getElementsByTagName("select")[0];        
    select.style.fontSize='40px';       
    webkitFix();


    setTimeout(function(){
    select.style.visibility = 'hidden';
    select1 = document.getElementsByTagName("select")[0];
    select1.style.visibility = 'visible';    
    select1.style.fontSize='10px';
    webkitFix();
    },5000);

},5000);
}     
</script>  

</head>
<body>
  <select id="one" multiple size="6" style="font-size:10px;">
    <option value="AAAAAA1">AAAAAA1</option>
    <option value="BBBBBB2">BBBBBB2</option>
    <option>AAAAAA3</option>
    <option>BBBBBB4</option>
    <option>AAAAAA5</option>
    <option>BBBBBB6</option>
    <option>AAAAAA7</option>
    <option>BBBBBB8</option>
    <option>AAAAAA9</option>
</select>

<select id="two" multiple size="6" style="font-size:10px; position:absolute; visibility:hidden;">
    <option value="AAAAAA1">AAAAAA1</option>
    <option value="BBBBBB2">BBBBBB2</option>
    <option>AAAAAA3</option>
    <option>BBBBBB4</option>
    <option>AAAAAA5</option>
    <option>BBBBBB6</option>
    <option>AAAAAA7</option>
    <option>BBBBBB8</option>
    <option>AAAAAA9</option>
</select>      
</body>  

Screenshot 1:

enter image description here

Screenshot 2:

enter image description here

Screenshot 3:

enter image description here

Ozieozkum answered 21/8, 2013 at 12:24 Comment(0)
H
2

I've tried so many things, height, line-height, offsetHeight, padding, margin, word-spacing, letter-spacing, white-space, text-indent, -ms-word-break, -ms-word-wrap, line-break, and many others.. even tried to understand the IE hasLayout property and how to do some workaround, this bug/issue of IE8 seems to be unfixable..

If you don't want to use a plugin like what @DavidBarker suggested, neither you want to clone/copy the original dropdown like what @Akki619, here is the best thing I could come up with:

if($isIE8) {// alternative solution for IE8


    setTimeout(function() {
        var w = parseInt(select.style.width, 10);
        var h = parseInt(select.style.height, 10);
        // change select zoom rather than changing the font-size (since font-size is buggy)
        //select.style.fontSize = '40px';
        select.style.zoom = '400%';// almost equal to '40px'
        var longestOptionText = 1;
        // for the below, I used jquery to get the longest option text, you might replace it with some javascript
        $('select option').each(function() {
            var txtlen = $(this).text().length;
            if(txtlen > longestOptionText) {
                longestOptionText = txtlen;
            }
        });
        // -------- end of jquery usage
        select.style.width = (parseInt(select.style.fontSize, 10) * longestOptionText) + 'px';
        select.style.height = (parseInt(select.style.fontSize, 10) * longestOptionText) + 'px';
        setTimeout(function() {
            //select.style.fontSize = '10px';
            select.style.zoom = '100%';
            select.style.width = w + 'px';
            select.style.height = h + 'px';
        }, 5000);
    }, 5000);


} else {// all other browsers

    // keep your original code here..

}

The result will look kind of similar to what you're expecting, but now there is slightly little problem, if zoom is set to bigger than 100%, the scroller vertical bar will not be visible. Solution: increase the select height to have all options visible.

Hutchison answered 25/8, 2013 at 13:32 Comment(0)
B
0

Try accessing the offsetHeight on the select. It forces a redraw.

Bevy answered 18/8, 2013 at 6:50 Comment(6)
And by accessing, you mean reading? Because you can't write offsetHeightBrackish
Reading, yes. Accessing doesn't necessarily mean writing.Bevy
+1 no need to vote down since this is though. anyway didn't work :(Charlie
you can adjust zoom:1 after setting font-size. let me know if it worksCoker
If you do a simple Google, you'll see there are hundreds of results recommending reading offsetHeight, as the browser has to redraw to calculate that value. Stop being so elitist, it's very unattractive.Bevy
@ultraviol3tlux I did not have the intention to be elitist. But, if you tested this before answering, you would have seen that it didn't work, alas...Brackish

© 2022 - 2024 — McMap. All rights reserved.