Select dropdown with fixed width cutting off content in IE

HtmlCssInternet ExplorerHtml Select

Html Problem Overview


The issue:

Some of the items in the select require more than the specified width of 145px in order to display fully.

Firefox behavior: clicking on the select reveals the dropdown elements list adjusted to the width of the longest element.

IE6 & IE7 behavior: clicking on the select reveals the dropdown elements list restricted to 145px width making it impossible to read the longer elements.

The current UI requires us to fit this dropdown in 145px and have it host items with longer descriptions.

Any advise on resolving the issue with IE?

The top element should remain 145px wide even when the list is expanded.

Thank you!

The css:

select.center_pull {
	background:#eeeeee none repeat scroll 0 0;
	border:1px solid #7E7E7E;
	color:#333333;
	font-size:12px;
	margin-bottom:4px;
	margin-right:4px;
	margin-top:4px;
	width:145px;
}

Here's the select input code (there's no definition for the backend_dropbox style at this time)

<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>

Full html page in case you want to quickly test in a browser:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dropdown test</title>

<style type="text/css">
<!--
select.center_pull {
	background:#eeeeee none repeat scroll 0 0;
	border:1px solid #7E7E7E;
	color:#333333;
	font-size:12px;
	margin-bottom:4px;
	margin-right:4px;
	margin-top:4px;
	width:145px;
}
-->
</style>
</head>

<body>
<p>Select width test</p>
<form id="form1" name="form1" method="post" action="">
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</form>
</body>
</html>

Html Solutions


Solution 1 - Html

For IE 8 there is a simple pure css-based solution:

select:focus {
    width: auto;
    position: relative;
}

(You need to set the position property, if the selectbox is child of a container with fixed width.)

Unfortunately IE 7 and less do not support the :focus selector.

Solution 2 - Html

I did Google about this issue but didn't find any best solution ,So Created a solution that works fine in all browsers.

just call badFixSelectBoxDataWidthIE() function on page load.

function badFixSelectBoxDataWidthIE(){
    if ($.browser.msie){
      $('select').each(function(){
    if($(this).attr('multiple')== false){
      $(this)
          .mousedown(function(){
               if($(this).css("width") != "auto") {
                   var width = $(this).width();
                   $(this).data("origWidth", $(this).css("width"))
                          .css("width", "auto");
                   /* if the width is now less than before then undo */
                   if($(this).width() < width) {
        $(this).unbind('mousedown');
                       $(this).css("width", $(this).data("origWidth"));
                   }
               }
           })
           /* Handle blur if the user does not change the value */
           .blur(function(){
               $(this).css("width", $(this).data("origWidth"));
   
           })
           /* Handle change of the user does change the value */
           .change(function(){
               $(this).css("width", $(this).data("origWidth"));
   
           });
        }
      });
    }
    }

Solution 3 - Html

Here is a little script that should help you out:

http://www.icant.co.uk/forreview/tamingselect/

Solution 4 - Html

For a simple Javascript-free solution, adding a title-attribute to your <option>s holding the text might be enough, depending on your requirements.

<option value="242" title="Very long and extensively descriptive text">
  Very long and extensively descriptive text
</option>

This will show the cut-off text in a tool-tip fashion on hovering the <option>, regardless of the width of the <select>.

Works for IE7+.

Solution 5 - Html

Not javascript free i'm afraid, but I managed to make it quite small using jQuery

$('#del_select').mouseenter(function () {

	$(this).css("width","auto");

});

$('#del_select').mouseout(function () {

	$(this).css("width","170px");

});	

Solution 6 - Html

Simply you can use this plugin for jquery ;)

http://plugins.jquery.com/project/skinner

$(function(){
          $('.select1').skinner({'width':'200px'});
});

Solution 7 - Html

Small, but hopefully useful update to the code from MainMa & user558204 (thanks guys), which removes the unnecessary each loop, stores a copy of $(this) in a variable in each event handler as it's used more than once, also combined the blur & change events as they had the same action.

Yes, it's still not perfect as it resizes the select element, rather than just the drop-down options. But hey, it got me out of a pickle, I (very, very unfortunately) still have to support an IE6-dominant user base across the business.

// IE test from from: https://gist.github.com/527683
var ie = (function () {
  var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i');
  while (
    div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
    all[0]
  );
  return v > 4 ? v : undef;
} ());


function badFixSelectBoxDataWidthIE() {
  if (ie < 9) {
    $('select').not('[multiple]')
      .mousedown(function() {
        var t = $(this);
        if (t.css("width") != "auto") {
          var width = t.width();
          t.data("ow", t.css("width")).css("width", "auto");

          // If the width is now less than before then undo
          if (t.width() < width) {
            t.unbind('mousedown');
            t.css("width", t.data("ow"));
          }
        }
      })
  
      //blur or change if the user does change the value
      .bind('blur change', function() {
        var t = $(this);
        t.css("width", t.data("ow"));
      });
  }
}

Solution 8 - Html

I found a pretty straightforward fix for this. In the <select> html element add these properties:

onmouseover="autoWidth(this)" 
onblur="resetWidth(this)" 

So whenever user clicks on that the width will automatically expand, and user moves out of the select box, the width will be reset to original.

Solution 9 - Html

A different approach:

  1. instead of a select make it an edit box, disabled so noone can enter anything manually or change contents after selection
  2. another hidden edit to contain an id of a selected option (explained below)
  3. make a button [..] and script it to show that div below
  4. make a hidden div with absolute position under or near the edit box
  5. make that div to contain a select with style size="6" (to show 6 options and a scrollbar rather than a drop-down list) and a button "select" and maybe "cancel"
  6. Do not style width so the whole thing will assume width of the widest option or the button plus maybe some padding of your choice
  7. script the "select" button to copy id of the selected option to the hidden edit box and it's value to the visible one, also to hide the div again.

4 simple javascript commands total.

Solution 10 - Html

similar solution can be found here using jquery to set the auto width when focus (or mouseenter) and set the orignal width back when blur (or mouseleave) http://css-tricks.com/select-cuts-off-options-in-ie-fix/.

Solution 11 - Html

for (i=1;i<=5;i++){
   idname = "Usert" + i;
   document.getElementById(idname).style.width = "100%";

}

I used this way to showed the drop down list when the width is not showed correctly.

It work for IE6, Firefox and Chrome.

Solution 12 - Html

A full fledged jQuery plugin is available, check out the demo page: http://powerkiki.github.com/ie_expand_select_width/

disclaimer: I coded that thing, patches welcome

Solution 13 - Html

Why would anyone want a mouse over event on a drop down list? Here's a way of manipulating IE8 for the way a drop down list should work:

First, let's make sure we are only passing our function in IE8:

    var isIE8 = $.browser.version.substring(0, 2) === "8.";
    if (isIE8) {
       //fix me code
    }

Then, to allow the select to expand outside of the content area, let's wrap our drop down lists in div's with the correct structure, if not already, and then call the helper function:

        var isIE8 = $.browser.version.substring(0, 2) === "8.";
    if (isIE8) {
        $('select').wrap('<div class="wrapper" style="position:relative; display: inline-block; float: left;"></div>').css('position', 'absolute');
        
        //helper function for fix
        ddlFix();
    }

Now onto the events. Since IE8 throws an event after focusing in for whatever reason, IE will close the widget after rendering when trying to expand. The work around will be to bind to 'focusin' and 'focusout' a class that will auto expand based on the longest option text. Then, to ensure a constant min-width that doesn't shrink past the default value, we can obtain the current select list width, and set it to the drop down list min-width property on the 'onchange' binding:

    function ddlFix() {
    var minWidth;

    $('select')

    .each(function () {
        minWidth = $(this).width();
        $(this).css('min-width', minWidth);
    })
    .bind('focusin', function () {
        $(this).addClass('expand');
    })
    .change(function () {
        $(this).css('width', minWidth);
    })
    .bind('focusout', function () {
        $(this).removeClass('expand');
    });
}

Lastly, make sure to add this class in the style sheet:

 select:focus, select.expand {
    width: auto;
}

Solution 14 - Html

Not javascript free, I am afraid too and my solution do require a js library, however, you can only use those files which you need rather than using them all, maybe best suited for those who are already using YUI for their projects or deciding which one to use. Have a look at: http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/

My blog post also discusses other solutions as well, one is referenced back to here on stackoverflow, why I went back to create my own SELECT element is because of simple reason, I don't like mouseover expand events. Maybe if that helps anyone else too!

Solution 15 - Html

The jquery BalusC's solution improved by me. Used also: Brad Robertson's comment here.

Just put this in a .js, use the wide class for your desired combos and don't forge to give it an Id. Call the function in the onload (or documentReady or whatever).
As simple ass that :)
It will use the width that you defined for the combo as minimun length.

function fixIeCombos() {
    if ($.browser.msie && $.browser.version < 9) {
    var style = $('<style>select.expand { width: auto; }</style>');
    $('html > head').append(style);

    var defaultWidth = "200";

    // get predefined combo's widths.
    var widths = new Array();
    $('select.wide').each(function() {
        var width = $(this).width();
        if (!width) {
        width = defaultWidth;
        }
        widths[$(this).attr('id')] = width;
    });

    $('select.wide')
    .bind('focus mouseover', function() {
        // We're going to do the expansion only if the resultant size is bigger
        // than the original size of the combo.
        // In order to find out the resultant size, we first clon the combo as
        // a hidden element, add to the dom, and then test the width.
        var originalWidth = widths[$(this).attr('id')];

        var $selectClone = $(this).clone();
        $selectClone.addClass('expand').hide();
        $(this).after( $selectClone );
        var expandedWidth = $selectClone.width()
        $selectClone.remove();
        if (expandedWidth > originalWidth) {
        $(this).addClass('expand').removeClass('clicked');
        }
    })
    .bind('click', function() {
        $(this).toggleClass('clicked'); 
    })
    .bind('mouseout', function() {
        if (!$(this).hasClass('clicked')) {
        $(this).removeClass('expand');
        }
    })
    .bind('blur', function() {
        $(this).removeClass('expand clicked');
    })
    }
}

Solution 16 - Html

Its tested in all version of IE, Chrome, FF & Safari

// JavaScript code

    <script type="text/javascript">
    <!-- begin hiding
    function expandSELECT(sel) {
      sel.style.width = '';
    }
    function contractSELECT(sel) {
      sel.style.width = '100px';
    }
    // end hiding -->
    </script>

// Html code

    <select name="sideeffect" id="sideeffect"  style="width:100px;" onfocus="expandSELECT(this);" onblur="contractSELECT(this);" >
      <option value="0" selected="selected" readonly="readonly">Select</option>
    <option value="1" >Apple</option>
    <option value="2" >Orange + Banana + Grapes</option>

Solution 17 - Html

I've got yet another contribution to this. I wrote this a while back that you may find helpful: http://dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html

It's a jquery plugin to make a styleable unordered list backed by the hidden select element.

The source is on github: https://github.com/tncbbthositg/GiantDropdown

You'd be able to handle behaviors and styles on the UL that you can't with the SELECT. Everything else should be the same because the select list is still there, it's just hidden but the UL will use it as a backing data store (if you will).

Solution 18 - Html

Here is a solution that actually works.

It sets the width in IE and doesn't mess up your page layout and doesn't close the dropdown when you mouse over the select options like some of the other solutions on this page.

You will need however to change the margin-right value and width values to match what you have for your select fields.

Also you can replace the $('select') with $('#Your_Select_ID_HERE') to only effect a specific select field. As well you will need to call the function fixIESelect() on the body onload or via jQuery using DOM ready as I did in my code below:

//////////////////////////
// FIX IE SELECT INPUT //
/////////////////////////
window.fixIESelect_clickset = false;
function fixIESelect()
{
 if ($.browser.msie)
 {
  $('select').mouseenter(function ()
  {
   $(this).css("width","auto");
   $(this).css("margin-right","-100");
  });
  $('select').bind('click focus',function ()
  {
   window.fixIESelect_clickset = true;
  });
  $('select').mouseout(function ()
  {
   if(window.fixIESelect_clickset != true)
   {
    $(this).css("width","93px");
    window.fixIESelect_clickset = false;
   }
  });
  $('select').bind('blur change',function ()
  {
   $(this).css("width","93px");
  });
 }
}
/////////////
// ONLOAD //
////////////
$(document).ready(function()
{
 fixIESelect();
});


Solution 19 - Html

I wanted this to work with selects that I added dynamically to the page, so after a lot of experimentation, I ended up giving all the selects that I wanted to do this with the class "fixedwidth", and then added the following CSS:

table#System_table select.fixedwidth { width: 10em; }
table#System_table select.fixedwidth.clicked { width: auto; }

and this code

<!--[if lt IE 9]>
	<script type="text/javascript">
		jQuery(document).ready(function() {
            jQuery(document).on(
              {
                'mouseenter': function(event) {
                    jQuery(this).addClass('clicked');
                    },
                'focusout change blur': function() {
                    jQuery(this).removeClass('clicked');
                    }
              }, 'select.fixedwidth');
		});
	</script>
<![endif]-->

A couple of things to note:

  • In spite of the fact that my selects are all in a table, I had to do "on" to the jQuery(document).on instead of to jQuery('table#System_table').on
  • In spite of the fact that the jQuery documentation says to use "mouseleave" instead of "blur", I found that in IE7 when I moved the mouse down the drop down list, it would get a mouseleave event but not a blur.

Solution 20 - Html

For my layout, I didn't want a hack (no width increasing, no on click with auto and then coming to original). It broke my existing layout. I just wanted it to work normally like other browsers.

I found this to be exactly like that :-

http://www.jquerybyexample.net/2012/05/fix-for-ie-select-dropdown-with-fixed.html

Solution 21 - Html

A workaround if you don't care about the strange view after an option is selected (i.e. Select to jump to a new page):

<!-- Limit width of the wrapping div instead of the select and use 'overflow: hidden' to hide the right part of it. -->
<div style='width: 145px; overflow: hidden; border-right: 1px solid #aaa;'>
  <select onchange='jump();'>
    <!-- '&#9660;(▼)' produces a fake dropdown indicator -->
    <option value=''>Jump to ... &#9660;</option>
    <option value='1'>http://stackoverflow.com/questions/682764/select-dropdown-with-fixed-width-cutting-off-content-in-ie</option>
    ...
  </select>
</div>

Solution 22 - Html

A pure css solution : http://bavotasan.com/2011/style-select-box-using-only-css/

.styled-select select {
   background: transparent;
   width: 268px;
   padding: 5px;
   font-size: 16px;
   line-height: 1;
   border: 0;
   border-radius: 0;
   height: 34px;
   -webkit-appearance: none;
   }

.styled-select {
   width: 240px;
   height: 34px;
   overflow: hidden;
   background: url(http://cdn.bavotasan.com/wp-content/uploads/2011/05/down_arrow_select.jpg) no-repeat right #ddd;
   border: 1px solid #ccc;
   }

<div class="styled-select">
   <select>
      <option>Here is the first option</option>
      <option>The second option</option>
   </select>
</div>

Solution 23 - Html

Best solution: css + javascript

http://css-tricks.com/select-cuts-off-options-in-ie-fix/

var el;

$("select")
  .each(function() {
    el = $(this);
    el.data("origWidth", el.outerWidth()) // IE 8 can haz padding
  })
  .mouseenter(function(){
    $(this).css("width", "auto");
  })
  .bind("blur change", function(){
    el = $(this);
    el.css("width", el.data("origWidth"));
  });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaaandreView Question on Stackoverflow
Solution 1 - HtmlrustyView Answer on Stackoverflow
Solution 2 - HtmlAnoop SharmaView Answer on Stackoverflow
Solution 3 - HtmlZacView Answer on Stackoverflow
Solution 4 - HtmlislanderView Answer on Stackoverflow
Solution 5 - HtmlstukerrView Answer on Stackoverflow
Solution 6 - HtmlanbiView Answer on Stackoverflow
Solution 7 - HtmlTechSpudView Answer on Stackoverflow
Solution 8 - HtmlTheOnlyOneView Answer on Stackoverflow
Solution 9 - HtmlKitetView Answer on Stackoverflow
Solution 10 - Htmlschrodinger's codeView Answer on Stackoverflow
Solution 11 - HtmlkeongView Answer on Stackoverflow
Solution 12 - HtmlPowerKiKiView Answer on Stackoverflow
Solution 13 - HtmlBen SewardsView Answer on Stackoverflow
Solution 14 - HtmlHammad TariqView Answer on Stackoverflow
Solution 15 - HtmlFederico ValidoView Answer on Stackoverflow
Solution 16 - HtmlArifView Answer on Stackoverflow
Solution 17 - HtmlD. PatrickView Answer on Stackoverflow
Solution 18 - HtmlGallagherView Answer on Stackoverflow
Solution 19 - HtmlPaul TomblinView Answer on Stackoverflow
Solution 20 - HtmlSteveView Answer on Stackoverflow
Solution 21 - HtmlMergen WuView Answer on Stackoverflow
Solution 22 - HtmlTeenageView Answer on Stackoverflow
Solution 23 - Htmltuffo19View Answer on Stackoverflow