This is an odd problem. I'm trying to combat the age old IE crap of fixed width selects being cut off. I'm using javascript (jquery) like this:

$select.mousedown(function(){ $(this).addClass("resetWidth"); })
  .blur(function(){ $(this).removeClass("resetWidth"); })
  .change(function(){ $(this).removeClass("resetWidth"); })

and my CSS is like this

select{
  width:100px;
  min-width:100px;
}
select.resetWidth{
  width:auto;
  min-width:100px;
}

So here's my problem. If the select's options are all really short ie. 2 letters, when setting width:auto, it completely ignores min-width and makes the width of the select super small (to fit the small options text). Works like a charm if options are larger than 100px, expands and everything. Just the min-width seems to be completely disregarded. Any thoughts?

  • So it appears that although IE supports min-width, it doesn't work on selects, that's why it's being ignored in the above example, still searching... Brad Robertson over 9 years ago
  • I just realized that I hadn't mentioned at all that I'm trying to get IE7 to work, don't care about IE6 which i KNOW doesn't support min-width Brad Robertson over 9 years ago

3 answers

0
points

This is a case where you may need to make up for IE weaknesses.

Change your code as follows:

$select.mousedown(function(){ 
    $(this).addClass("resetWidth"); 
    if ($(this).width() < 100) {
        $(this).width(100);
    }
}).blur(function(){ 
    $(this).removeClass("resetWidth").css("width","auto");
}).change(function(){ 
    $(this).removeClass("resetWidth").css("width","auto"); 
});

This was not tested but it looks right to me.

Answered over 9 years ago by Eli Cochran
  • So I also tried the if $(this).width < x but, there's a further problem, if you click a select and it's width becomes smaller (as it would with adding resetWidth if the options are small in length) then the select itself doesn't open. So that works, as far as keeping the select to a minimum size, but it doesn't actually open. Brad Robertson over 9 years ago
Anthony 25
0
points

I'm not sure if I'm reading your idea correctly, but it seems like you are trying to shift the size when the user focuses on the select. If that's the case, there are 3 problems, as I see it:

  1. dynamic size shifting like that can be startling or simply unattractive to users.
  2. Size shifts like that can throw off other elements that are on the same line as the select, which would be unattractive and hack-looking.
  3. By using jquery the way you do in the example, you force the solution on all browsers, including the ones that can handle min-width just fine. If that's the case, why bother using the CSS at all?

But I'm not out to be negative. It's a real problem, and a really annoying one at that. So here are some ideas:

  1. Have you tried conditional comments? IE supports commenting out code based on conditions (such as if IE or if < IE 7). For your case, it would be:

    select {
         width:100px;
         min-width:100px;
      }
     <!--[if IE]>
    select {
         width: auto;
      }    
     <![endif]-->
    
  2. You could use jquery to get the width of the longest select option and set the width to that on page load. It would be a bit hacky like I suggested above, but perhaps with a cool slide or slow effect added on it could look intentional. Something like:

       var longest = 0;
       $("select option").each(function() {
               var opt_length = $(this).text().length();
               longest = (opt_length > longest) ? opt_length : longest;
            });
           $("select").css("width", longest/4 + "em");
    

I'm no good with the effects, but I imagine adding on in that last bit would be a breeze.

Answered over 9 years ago by Anthony
  • Ya this will only be displayed in IE, i just left that code out for simplicity sake. Also, I'm setting opacity:0 on it and using a div to echo out the selected val of the select, so you can't actually see the select expand (no jarring) and it's position absolute within a relative position span so it doesn't affect anything around it. I'll play around with that longest code and see what I find Brad Robertson over 9 years ago
  • Can you explain the longest/4 em for me? I always wondered if there was some way of getting the width of an element by it's text, what's the logic here? Brad Robertson over 9 years ago
  • `$(this).text().length();` will return the number of characters in the text of an element. I used "/4 em" because I figure that's about ideal for a string that you want on a single line. So if it was a single character, you'd set the width to .25em. You can play around with that, of course. I wish there was a good width-relative font-unit. Anyways I believe using ".text().length" will work in non-jquery as well, or something very similar. I can look it up if need be. Anthony over 9 years ago
0
points

Ok, so i've come up with a solution I don't like, but it works. working with Eli's code, I noticed that IE closes the select immediately if the width:auto "width" is less than the current width. THis is obviously unacceptable. So, I decided to clone the object, apply the class and test it's width. Not awesome, but it works. Here's the code (in the mousedown method)

$select.mousedown(function(){
// This whole clone business is not ideal but I can't come up with any other method
// If you resize a select in IE and it becomes smaller, the select closes immediately
// So, I'm cloning the select, applying the class, adding it to the dom (width doens't work otherwise)
// Getting it's width, testing if it's less than the current select's width and if it is, don't apply the width:auto class
// If it's greater than the width, apply the class and the select will expand.
var $selectClone = $(this).clone();
$selectClone.addClass("resetWidth").hide();
$(this).after( $selectClone );

var cloneWidth = $selectClone.width();
$selectClone.remove();
if (cloneWidth > $(this).width() ){
    $(this).addClass("resetWidth");
}
})
Answered over 9 years ago by Brad Robertson