41

When I reduce the width of my browser window, select elements within the fieldset does not reduce in size despite the max-width command:

<fieldset style="background:blue;">
<select name=countries style="max-width:90%;">
 <option value=gs>South Georgia and the South Sandwich Islands</option>
</select>
</fieldset>

However, this works perfectly outside fieldset element. How do I make the select elements shrink to the max-width (percentage) within the fieldset?

Note: I have tested both Firefox 12.0 and Google Chrome. I am now sure that it is a cross-browser problem.

Clarification: Please refer to this example and note the difference between the behaviour of a select element inside a fieldset and another outside the fieldset. What I want to achieve is for the select element within the fieldset to behave like the one outside the fieldset element.

Question Overflow
  • 10,925
  • 18
  • 72
  • 110
  • Works for me on Chrome http://jsfiddle.net/waitinforatrain/J5j39/2/ . Does this not work for you on Firefox? – bcoughlan May 20 '12 at 10:26
  • @waitinforatrain: nope, it didn't shrink at all when I reduce the browser window. – Question Overflow May 20 '12 at 10:27
  • As far as I could see, no one had reported that Firefox bug, so I did: https://bugzilla.mozilla.org/show_bug.cgi?id=823483 Hopefully that is not a duplicate. I have not reported the corresponding Chrome/Webkit bug. Perhpas someone else would like to/ – Tim Hunt Dec 20 '12 at 13:02

5 Answers5

79

The problem

This isn't possible, at least if you only use max-width (see below for solution). <select>s are always a little bit tricky to style, as they're interactive content elements and form control elements. As such, they have to follow some implicit rules. For one, you cannot make a select less wide than one of its options when using max-width. Think of the following scenario:

+------------------------------------+-+
|Another entry                       |v|
+------------------------------------+-+
|Another entry                         |
|Select box, select anything, please   |
|Another entry                         |
|Another entry                         |
+------------------------------------+-+

Let's say that you want to squeeze this <select> - what will happen? The select's width will get lesser, until...

+------------------------------------+-+   +-----------------------------------+-+
|Another entry                       |v|   |Another entry                      |v|
+------------------------------------+-+   +-----------------------------------+-+
|Another entry                         |   |Another entry                        | 
|Select box, select anything, please   |-->|Select box, select anything, please  | 
|Another entry                         |   |Another entry                        | 
|Another entry                         |   |Another entry                        | 
+------------------------------------+-+   +-----------------------------------+-+ 
                                                   |
           +---------------------------------------+
           v
+----------------------------------+-+   +---------------------------------+-+
|Another entry                     |v|   |Another entry                    |v|
+----------------------------------+-+   +---------------------------------+-+
|Another entry                       |   |Another entry                      | 
|Select box, select anything, please |-->|Select box, select anything, please| 
|Another entry                       |   |Another entry                      | 
|Another entry                       |   |Another entry                      | 
+----------------------------------+-+   +---------------------------------+-+ 

And then the process will stop, as the <option>s wouldn't fit anymore. Keep in mind that you can't style <option>s or at least only a little bit (color, font-variant) without getting some nasty quirks. However, the border-box can be changed, if the select is prepared correctly:

The solution

Use a width value on the select. Yep, it's easy as that:

<fieldset style="background:blue;">
 <select name=countries style="width:100%;max-width:90%;">
  <option value=gs>South Georgia and the South Sandwich Islands</option>
 </select>
</fieldset>

Why does this work? Because the option will now recognize the width of the select correctly and won't force the select to have a implicit min-width. Notice that the width is absurd, as it is more than the max-width. Most browsers won't care and use the max-width in this case, as it provides an upper bound.

JSFiddle Demo (works in FF12, Chrome 18, IE9, Opera 11.60)

Edit

Wrapper based solution, this won't change the original width:

<fieldset style="background:blue;">
<div style="display:inline-block;max-width:90%;"> <!-- additional wrapper -->
 <select name=countries style="width:100%">
  <option value=gs>South Georgia and the South Sandwich Islands</option>
 </select>
</div>
</fieldset>

JSFiddle Demo (works in browsers listed above)

Community
  • 1
  • 1
Zeta
  • 103,620
  • 13
  • 194
  • 236
  • thanks for trying. I apologise if my question is not clear enough. I have added some clarification and an example in the question. Please have a look. Your proposed solution would cause the select element to expand to what is more than necessary. – Question Overflow May 29 '12 at 09:15
  • I don't think there's an easy way to do this. You can use a smaller `width` (something like `45ex` should be enough). ` – Zeta May 29 '12 at 09:39
  • 1
    That's great! This is what I want. I have also invited two other users to help me with this question, the bounty will be yours unless they can come up better solutions. Thanks for your time :) – Question Overflow May 29 '12 at 10:22
  • Thanks for this insight... however, why does it behave differently when inside and outside
    ? I find this inconsistency perplexing!
    – iamkeir Apr 19 '13 at 20:28
  • 4
    @iamkeir [Apparently](http://stackoverflow.com/a/17863685/578288) `fieldset`s have legacy sizing behavior that is kept for compatibility. In Chrome, this is implemented with a default style `min-width: min-content`, and in Firefox, this is hard-coded into the rendering engine. – Rory O'Kane Aug 06 '13 at 21:05
  • Your first solution initially looks broken in ie. clicking the dropdown looks like the arrow disappears and that is all. May I suggest adding a second or even third option to the JSFiddle demo: ../J5j39/5/ – Danny Mahoney Mar 06 '16 at 23:57
  • @DannyMahoney: Which IE version? Currently on Linux, but I can check IE later. – Zeta Mar 07 '16 at 08:03
  • @Zeta I am viewing this in IE Version: 11.0.9600.18204 – Danny Mahoney Mar 09 '16 at 00:46
  • Looks like only the last solution from this answer works in latest version chrome, not the one above it. – matanster Aug 09 '16 at 13:50
  • Why not just make `max-width` perform like `max-width`, and `width` like width, as with all other controls? Why swap them around for just the ` – run_the_race Mar 05 '23 at 03:14
  • In case you're asking _why_ things are specified that way, then you're probably at the wrong spot, @run_the_race. I didn't set the spec for form elements and their interaction with CSS :). (That being said, this answer is almost 11 years old, I don't quite know today's situation) – Zeta Mar 06 '23 at 10:43
3

Is this what you’re looking for?

<fieldset style="background:blue; display:inline; width:100%;">
  <select name=countries style="width:90%;">
    <option value=gs>South Georgia and the South Sandwich Islands</option>
  </select>

  <input name=others style="display:block; min-width:300px; width:90%;">
</fieldset>

Either way, when you specify the width with a value (such as 300px) – this height will take priority and the element will be assigned 300px itself. Define the width in percentages and give the min-width as an absolute value. The percentage is taken from its parent element. So, you should give a percentage to its parent too.

I hope this helps.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
Vivek Chandra
  • 4,240
  • 9
  • 33
  • 38
1

Wrap the select. For this example, I'll use a div with "select_wrap".

div.select_wrap {
  height: 1em;
} 
div.select_wrap select { 
  position: absolute;
  max-width: calc(100% - 6px);
  text-overflow: ellipsis;
} 

The "absolute" context allows max-width to be interpreted - no actual position information, just force it into a different context. calc() lets you be a bit more detailed with what max-width actually should be, given you don't have margins and padding where they were previously. text-overflow looks nice.

select_wrap's height is needed to make sure the form flows around the select as expected - you need to reserve the space the select formerly filled.

0

Set the width of the fieldset to 100% (or any other value)

http://jsfiddle.net/e2H82/3/

Tested in Google Chrome.

Tom Pietrosanti
  • 4,184
  • 2
  • 24
  • 29
-4

try:

fieldset select{
    margin:auto
}
kmchen
  • 39
  • 5
  • 4
    Please explain how your answer solves the problem, it will help everyone understand your solution with more clarity and for future reference. – Aziz Apr 06 '16 at 10:16