How to make the Selected Option the width of the current Selected Option's text?

I am trying to make the Select Option to have the width of the current Selected Option.

My code is the standard HTML for a Select Option dropdown:

<select name="search_options">
  <option value="all">All</option>
  <option value="entertainment">Entertainment</option>
  <option value="newsandpolitics">News &amp; Politics</option>
  <option value="sports">Sports</option>
  <option value="lifestyle">Lifestyle</option>
  <option value="health">Health</option>
  <option value="scienceandtech">Science &amp; Tech</option>
</select>

I have been trying to do this with just CSS or Javascript, with no JQuery, and I can't figure it out.

I have found several fiddles with JQuery already, but no CSS/Javascript ones.

http://jsfiddle.net/5AANG/4/

http://jsfiddle.net/qqcc5/

Is there any way to achieve this, identical with the above 2 fiddles, using just CSS or pure Javascript?

Any pointers in the right direction would be great.

Answers:

Answer

Based on your second link you can do it like this:

var selectId = document.getElementById("yourSelect");

selectId.onchange=function(){
   var selectedValue = selectId.options[selectId.selectedIndex].value; 
   var selectedText = selectId.options[selectId.selectedIndex].text;

   selectId.style.width = 20 + (selectedText.length * 8) + "px";
}

Test: http://jsfiddle.net/ndquxquu/

Answer

Converting to JavaScript and explaining your first example (http://jsfiddle.net/5AANG/4/).

This creates a temporary <span> element and copies the styles from the select box to the span. Then it measures the width of the span, sets the width of the select box based on that width, and removes the span from the document.

In plain old JavaScript:

Grab all the <select>s:

var selects = document.querySelectorAll('select');

Add our event listener (defined below) to each:

for (var i = 0; i < selects.length; i++) {
    selects[i].addEventListener('change', changeWidth);
}

Define the event listener:

function changeWidth (e) {

Base variable definitions:

    var select = e.target;
    var o = select.options[select.selectedIndex];
    var s = document.createElement('span');

Set the content of our temporary span (s) to the content of the selected option:

    s.textContent = o.textContent;

The fun part! Assigning to the <span> the styles of the selected option. (See getComputedStyle)

    var ostyles = getComputedStyle(o);
    s.style.fontFamily = ostyles.fontFamily;
    s.style.fontStyle = ostyles.fontStyle;
    s.style.fontWeight = ostyles.fontWeight;
    s.style.fontSize = ostyles.fontSize;

Append the span to the document so we can grab its width:

    document.body.appendChild(s);

Set the <select>'s width based on the span's width (30 is a magic number pulled from the above mentioned fiddle).

    select.style.width = (s.offsetWidth + 30) + 'px';

Quick! Remove the temporary span before anybody sees it!

    document.body.removeChild(s);
}

Demo: https://jsfiddle.net/Hatchet/a0xzz6mf/

Answer

I wrote this answer for a different thread which just got closed as a duplicate of this one. The problem with these answers is they are a bit complex and use hard-coded padding values, which can be unreliable. Here is my solution which doesn't require anything hard-coded.


While there isn't a CSS and HTML only way, a fairly straight-forward way to do it is to create a hidden select, set its only option to the chosen value, and the take that width and set it to the visible select.

The dummy select is basically just a reliable method for measuring how wide it should be.

Add that logic to "change" and it should be good and manually trigger it once, then you should be good.

const select = document.querySelector('select');
select.addEventListener('change', function() {
  const dummySelect = document.createElement('select');
  dummySelect.classList.add('dummy');
  
  const dummyOption = document.createElement('option');
  dummyOption.innerHTML = this.value;
  dummySelect.appendChild(dummyOption);
  
  document.body.appendChild(dummySelect);
  select.style.width = `${dummySelect.offsetWidth}px`;
  
  document.body.removeChild(dummySelect);
});

// Trigger for the first time
select.dispatchEvent(new Event('change'));
select {
  display: inline;
}

.dummy {
  position: absolute;
  left: -10000px;
}
<select>
 <option>A</option>
 <option>A much longer title</option>
 <option>Middleground</option>
</select>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.