How to Make Select Elements Shrink to Max-Width Percent Style Within Fieldset

How to make select elements shrink to max-width percent style within fieldset

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)

css - set max-width for select

If the venues are generated on the server side, you can use your server-side scripting to cut them down to a specific maximum character count.

When using pure CSS I'd also try setting overflow:hidden, both on the select and the option elements. Also try setting max-width on the option element. When it works in all non-IE, you can use the usual scripts to add max-width support for IE.

How to control the width of select tag?

USE style="max-width:90%;"

<select name=countries  style="max-width:90%;">
<option value=af>Afghanistan</option>
<option value=ax>Åland Islands</option>
...
<option value=gs>South Georgia and the South Sandwich Islands</option>
...
</select>

LIVE DEMO

fieldset resizes wrong; appears to have unremovable `min-width: min-content`

Update (25 Sept 2017)

The Firefox bug described below is fixed as of Firefox 53 and the link to this answer has finally been removed from Bootstrap's documentation.

Also, my sincere apologies to the Mozilla contributors who had to block removing support for -moz-document partly due to this answer.

The fix

In WebKit and Firefox 53+, you just set min-width: 0; on the fieldset to override the default value of min-content

Still, Firefox is a bit… odd when it comes to fieldsets. To make this work in earlier versions, you must change the display property of the fieldset to one of the following values:

  • table-cell (recommended)
  • table-column
  • table-column-group
  • table-footer-group
  • table-header-group
  • table-row
  • table-row-group

Of these, I recommend table-cell. Both table-row and table-row-group prevent you from changing width, while table-column and table-column-group prevent you from changing height.

This will (somewhat reasonably) break rendering in IE. Since only Gecko needs this, you can justifiably use @-moz-document—one of Mozilla's proprietary CSS extensions—to hide it from other browsers:

@-moz-document url-prefix() {
fieldset {
display: table-cell;
}
}

(Here's a jsFiddle demo.)


That fixes things, but if you're anything like me your reaction was something like…

What.

There is a reason, but it's not pretty.

The default presentation of the fieldset element is absurd and essentially impossible to specify in CSS. Think about it: the fieldset's border disappears where it's overlapped by a legend element, but the background remains visible! There's no way to reproduce this with any other combination of elements.

To top it off, implementations are full of concessions to legacy behaviour. One such is that the minimum width of a fieldset is never less than the intrinsic width of its content. WebKit gives you a way to override this behaviour by specifying it in the default stylesheet, but Gecko² goes a step further and enforces it in the rendering engine.

However, internal table elements constitute a special frame type in Gecko. Dimensional constraints for elements with these display values set are calculated in a separate code path, entirely circumventing the enforced minimum width imposed on fieldsets.

Again—the bug for this has been fixed as of Firefox 53, so you do not need this hack if you are only targeting newer versions.

Is using @-moz-document safe?

For this one issue, yes. @-moz-document works as intended in all versions of Firefox up until 53, where this bug is fixed.

This is no accident. Due in part to this answer, the bug to limit @-moz-document to user/UA stylesheets was made dependent on the underlying fieldset bug being fixed first.

Beyond this, do not use @-moz-document to target Firefox in your CSS, other resources notwithstanding.³


¹ Value may be prefixed. According to one reader, this has no effect in Android 4.1.2 Stock Browser and possibly other old versions; I have not had time to verify this.

² All links to the Gecko source in this answer refer to the 5065fdc12408 changeset, committed 29ᵗʰ July 2013; you may wish to compare notes with the most recent revision from Mozilla Central.

³ See e.g. SO #953491: Targeting only Firefox with CSS and CSS Tricks: CSS hacks targeting Firefox for widely referenced articles on high-profile sites.



Related Topics



Leave a reply



Submit