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
/
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>
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>
Share
Improve this question
edited Sep 4, 2013 at 16:18
Michal
2,5321 gold badge20 silver badges27 bronze badges
asked Aug 18, 2013 at 5:03
user652649user652649
20
- 1 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. – Ariane Commented Aug 18, 2013 at 5:35
- 2 is there a reason why you're not using jQuery? – huysentruitw Commented Aug 18, 2013 at 5:40
- 4 @RobertMcKee: IE8 mode != IE8 – huysentruitw Commented Aug 18, 2013 at 6:05
- 2 It's reproducible in IETester if you want to try – user652649 Commented Aug 18, 2013 at 6:14
- 2 @WouterHuysentruit: IE8 mode !== IE8 #javascript – zigo Commented Aug 20, 2013 at 14:43
4 Answers
Reset to default 11 +250This 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.
- Setting the height of a select element in IE
- IE font size reduction does not cause selects height to decrease
- An equally frustrated developer, see first reply
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.
- Twitter Bootstrap Dropdowns
- Twitter style dropdowns
- Chosen (library)
- Select box replacement jQuery plugin
- Custom select-box jQuery plugin
In conclusion, I'm afraid you're problem is unsolvable without using a polyfill for IE or adopting a total select box replacement strategy.
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.
(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
- 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:
Screenshot 2:
Screenshot 3:
Try accessing the offsetHeight on the select. It forces a redraw.