Drop down list width fit selected item text

13,579

Solution 1

My answer is similar to D3mon-1stVFW's, but instead uses a hidden drop-down to set the width on dynamically. As long as you use the same styling for your hidden and "real" one, it should account for different font sizes, decoration, etc. Here's the HTML:

<!-- this is our hidden "template" drop-down that we'll
     use to determine the size of our "real" one -->
<select id="template" style="display:none;">
  <option id="templateOption"></option>
</select>
<!-- this is our "real" template that will be re-sized -->
<select id="sel">
  <option>Short</option>
  <option>Really, Really, Really Long</option>
</select>​

And the Javascript:

function setSelectWidth() {
  var sel = $('#sel');
  $('#templateOption').text( sel.val() );
  // for some reason, a small fudge factor is needed
  // so that the text doesn't become clipped
  sel.width( $('#template').width() * 1.03 );
}

$(document).ready( function() {
  setSelectWidth();

  $('#sel').change( function() {
    setSelectWidth();
  } );​    
});

JSFiddle here: http://jsfiddle.net/kn9DF/1/

Solution 2

Variation on @Ethan Brown's answer, with the .val() corrected to .text() and a dynamically-created select so your page isn't polluted:

HTML:

<select id="sel">
  <option>Short</option>
  <option>Really, Really, Really Long</option>
</select>​

JS:

function setSelectWidth(selector) {
    var sel = $(selector);
    var tempSel = $("<select style='display:none'>")
        .append($("<option>").text(sel.find("option:selected").text()));
    tempSel.appendTo($("body"));

    sel.width(tempSel.width());

    tempSel.remove();
}

$(function() {
    setSelectWidth("#sel");

    $("#sel").on("change", function() {
        setSelectWidth($(this));
    });
});

Fiddle:

http://jsfiddle.net/kn9DF/242/

Tested on Chrome 39, FF 36, IE 11.

Solution 3

Here's a generic jQuery function you can drop into any page. It immediately resizes all selectors and ensures they will be resized when they are changed.

function setSelectWidth() {
    var $yardstick = $('<select><option>' + $(this).val() + '</option></select>')
    $yardstick.css({display: 'none'}).appendTo('body');
    var fudge = 1.03; // need a little more to avoid clipping for some reason    
    $(this).width( fudge * $yardstick.width() );
    $yardstick.remove();
}

function initSelectors() {
  $('select').each(function() {
    setSelectWidth.apply(this);
  }).one('change', function() {
    setSelectWidth.apply(this);
  });
}

initSelectors();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- examples -->
<select id="example-1">
    <option>Short</option>
    <option>Really, Really, Really Long</option>
</select>

<select id="example-2">
    <option>Tiny</option>
    <option>A bit bigger</option>
    <option>Huuuuuuuuuuuuuuuuuuuuge</option>    
</select>

The script is forked from Ethan and Ian's answers. The initSelectors function does need to be re-called if you add a selector, but it uses jQuery one so it can be safely called multiple times if previous selectors remain on the page.

Solution 4

Use this sample I wrote. Use the same when you create the list, just get the default selected and set it in the span and get its width.

<script>
    function newSelected(ele){
       document.getElementById('jsize').innerHTML = ele.value;
       document.getElementById('selectList').style.width = ($(jsize).width()+30)+'px';
    }

</script>

<span id="jsize" style="display:none"></span><br />

<select id="selectList" onchange="newSelected(this);">
    <option>small item</option>
    <option>a really big long item</option>
</select>

​ see http://jsfiddle.net/39ffp/2/ it can be tweaked

Share:
13,579
formatc
Author by

formatc

Updated on June 13, 2022

Comments

  • formatc
    formatc almost 2 years

    Is there a way in javascript/jquery or css to make html <select>/@Html.DropDownList auto width so it fits currently selected item, I tried with diplay:inline-block and width:auto but width always seems to fit largest item on list?

  • formatc
    formatc about 12 years
    It's still the same. I'll go to js fiddle to test it maybe something is wrong with my code.
  • formatc
    formatc about 12 years
    Well still doesn't work at least not in FF 11, Ethan got it right from your answer
  • formatc
    formatc about 12 years
    Thanks, works like a charm, but I'm little suprised that it requires so much hacking..
  • Bat_Programmer
    Bat_Programmer almost 6 years
    In my case it worked when I set "width:auto" style to template element