问题

我有一个<select>,其中一个<option>的文本值非常长。我想要调整<select>的大小,以便它永远不会比它的父元素更宽,即使它必须切断其显示的文本。Max-width: 100%应该这样做。

调整前:

调整大小后我想要什么:

但是,如果您加载这个jsFiddle示例并将Result面板的宽度调整为小于<select>的宽度,您可以看到<fieldset>中的select无法缩小其宽度。

调整大小后我实际看到的情况:

但是,使用<div>代替<fieldset>的等效页面可以适当缩放。如果你在一个页面上有一个<fieldset>和一个<div>相邻,你可以更容易地看到和测试你的更改。如果您删除了周围的<fieldset>标记,则调整大小生效。<fieldset>标记以某种方式导致水平大小调整中断。

The <fieldset> acts is as if there is a CSS rule fieldset { min-width: min-content; }. (min-content means, roughly, the smallest width that doesn’t cause a child to overflow.) If I replace the <fieldset> with a <div> with min-width: min-content, it looks exactly the same. Yet there is no rule with min-content in my styles, in the browser default stylesheet, or visible in Firebug’s CSS Inspector. I tried to override every style visible on the <fieldset> in Firebug’s CSS Inspector and in Firefox’s default stylesheet forms.css, but that didn’t help. Specifically overriding min-width and width didn’t do anything either.

Code

fieldset的HTML:

<fieldset>
    <div class="wrapper">
        <select id="section" name="section">
            <option value="-1"></option>
            <option value="1501" selected="selected">Sphinx of black quartz, judge my vow. The quick brown fox jumps over the lazy dog.</option>
            <option value="1480">Subcontractor</option>
            <option value="3181">Valley</option>
            <option value="3180">Ventura</option>
            <option value="3220">Very Newest Section</option>
            <option value="1481">Visitor</option>
            <option value="3200">N/A</option>
        </select>
    </div>
</fieldset>

我的CSS应该工作,但不是:

fieldset {
    /* hide fieldset-specific visual features: */
    margin: 0;
    padding: 0;
    border: none;
}

select {
    max-width: 100%;
}

将width属性重置为默认值不起任何作用:

fieldset {
    width: auto;
    min-width: 0;
    max-width: none;
}

进一步的CSS,我试图解决这个问题:

/* try lots of things to fix the width, with no success: */
fieldset {
    display: block;
    min-width: 0;
    max-width: 100%;
    width: 100%;
    text-overflow: clip;
}

div.wrapper {
    width: 100%;
}

select {
    overflow: hidden;
}

更多的细节

这个问题也出现在这个更全面、更复杂的jsFiddle示例中,它更类似于我实际试图修复的web页面。你可以看到<select>不是问题所在——一个内联块div也不能调整大小。虽然这个例子更复杂,但我认为对上面简单情况的修复也可以修复这个更复杂的情况。

[编辑:见下面的浏览器支持细节。]

关于这个问题的一个奇怪的事情是,如果你设置div.wrapper {width: 50%;}时,<fieldset>停止调整自己的大小,然后全尺寸的<select>将击中视口的边缘。调整大小发生时,就好像<select>的宽度为100%,即使<select>看起来它的宽度为50%。

如果你给<select>本身width: 50%,这种行为不会发生;宽度设置正确。

我不明白为什么会有这种差别。但这可能无关紧要。

我还发现了一个非常相似的问题,HTML fieldset允许孩子无限扩展。询问者找不到解决方案,并猜测除了删除<fieldset>之外没有解决方案。但我想知道,如果真的不可能使<fieldset>显示正确,为什么呢?什么在<fieldset>的规范或默认CSS(作为这个问题)导致这种行为?这个特殊的行为可能在某个地方有记录,因为许多浏览器都是这样工作的。

背景目标及要求

我试图这样做的原因是作为一个大表单的现有页面编写移动样式的一部分。表单有多个部分,其中一部分封装在<fieldset>中。在智能手机上(或者如果您将浏览器窗口设置得较小),具有<fieldset>的页面部分要比表单的其余部分宽得多。大多数表单都能很好地限制它的宽度,但带有<fieldset>的部分却没有,迫使用户缩小或右滚动以查看该部分的所有内容。

我对简单地删除<fieldset>很谨慎,因为它是在一个大应用程序的许多页面上生成的,而且我不确定CSS或JavaScript中的选择器可能依赖于它。

如果需要,我可以使用JavaScript,有JavaScript解决方案总比没有好。但如果JavaScript是做到这一点的唯一方法,我很好奇为什么只使用CSS和HTML是不可能的。


编辑:浏览器支持

在网站上,我需要支持Internet Explorer 8及更高版本(我们刚刚放弃了对IE7的支持),最新的Firefox和最新的Chrome。这个特殊的页面应该也适用于iOS和Android智能手机。对于ie8来说,稍微降级但仍然可用的行为是可以接受的。

我在不同的浏览器上重新测试了我坏掉的fieldset示例。它实际上已经在这些浏览器中工作:

Internet Explorer 8、9和10 铬 Chrome for Android

它在以下浏览器中崩溃:

火狐 Firefox for Android Internet Explorer 7

因此,我所关心的当前代码所能破解的浏览器只有Firefox(在桌面和移动端都是如此)。如果代码得到修复,可以在Firefox中正常运行,而不会破坏其他浏览器,那就可以解决我的问题。

站点HTML模板使用Internet Explorer条件注释将.ie8和.oldie等类添加到< HTML >元素。如果你需要处理IE中的样式差异,你可以在CSS中使用这些类。添加的类与旧版本的HTML5 Boilerplate相同。


当前回答

Safari在iOS上的问题与选定的答案

我发现乔丹·格雷(Jordan Gray)的答案特别有用。 然而,对我来说,它似乎并没有在Safari iOS上解决这个问题。

我的问题是,字段集不能有一个自动宽度,如果其中的元素有一个max-width作为%宽度。

修复问题

简单地将fieldset设置为容器的100%宽度似乎就可以解决这个问题。

例子

fieldset {
    min-width: 0; 
    width: 100%; 
}

请参考下面的工作示例-如果您从字段集中删除% width或将其替换为auto,它将无法继续工作。

JSFiddle |代码依赖

其他回答

Safari在iOS上的问题与选定的答案

我发现乔丹·格雷(Jordan Gray)的答案特别有用。 然而,对我来说,它似乎并没有在Safari iOS上解决这个问题。

我的问题是,字段集不能有一个自动宽度,如果其中的元素有一个max-width作为%宽度。

修复问题

简单地将fieldset设置为容器的100%宽度似乎就可以解决这个问题。

例子

fieldset {
    min-width: 0; 
    width: 100%; 
}

请参考下面的工作示例-如果您从字段集中删除% width或将其替换为auto,它将无法继续工作。

JSFiddle |代码依赖

我为此挣扎了好几个小时,基本上,浏览器正在应用你需要在CSS中重写的计算样式。我忘记了在fieldset元素和divs上设置的确切属性(可能是min-width?)

我最好的建议是将元素更改为div,从检查器中复制计算样式,然后将元素更改回fieldset,并比较计算样式以找到罪魁祸首。

希望这能有所帮助。

更新:添加display: table-cell有助于非chrome浏览器。

.fake-select {white-space:nowrap;}导致字段集根据.fake-select元素的原始宽度来解释它,而不是它的强制宽度(即使溢出是隐藏的)。

删除该规则,并将.fake-select的max-width:100%更改为width:100%并且所有内容都合适。需要注意的是,您可以看到假选择的所有内容,但我不认为这很糟糕,它现在可以水平放置了。

更新:在当前的规则在以下提琴(其中只包含实选择),字段集的孩子被限制为正确的宽度。除了删除.fake-select规则和修复注释(从// comment到/* comment */)之外,我还注意到小提琴的CSS的变化。

我现在更好地理解了你的问题,小提琴反映了一些进步。我为所有<select>s设置默认规则,并为那些你知道将比480px宽的保留.xxlarge(这只是因为你知道#viewport的宽度,并且可以手动添加类到那些太宽。只需要一点点测试)

证明

更新 (2017年9月25日)

下面描述的Firefox错误已在Firefox 53中修复,该答案的链接最终已从Bootstrap的文档中删除。

同时,我向Mozilla贡献者表示诚挚的歉意,他们不得不阻止删除对-moz-document的支持,部分原因是这个答案。

修复

在WebKit和Firefox 53+中,只需设置min-width: 0;覆盖默认值min-content.¹

尽管如此,当涉及到字段集时,Firefox还是有点……奇怪。要在早期版本中实现此功能,必须将字段集的display属性更改为以下值之一:

表格单元(推荐) 表列 table-column-group table-footer-group table-header-group 作用是 table-row-group

其中,我推荐table-cell。table-row和table-row-group都阻止您更改宽度,而table-column和table-column-group都阻止您更改高度。

这将(合理地)破坏IE中的渲染。因为只有Gecko需要这个,你可以合理地使用@-moz-document (Mozilla的专有CSS扩展之一)来对其他浏览器隐藏它:

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

(这里是jsFiddle的演示。)


这解决了问题,但如果你像我一样,你的反应是……

什么。

这是有原因的,但不是很好。

fieldset元素的默认表示是荒谬的,基本上不可能在CSS中指定。想想看:字段集的边界在与图例元素重叠的地方消失了,但背景仍然可见!任何其他元素的组合都无法重现这种效果。

最重要的是,实现充满了对遗留行为的让步。其中之一就是字段集的最小宽度永远不会小于其内容的固有宽度。WebKit提供了一种在默认样式表中指定它的方法来覆盖这种行为,但是Gecko²更进一步,在呈现引擎中强制执行它。

然而,在Gecko中,内部表元素构成了一种特殊的框架类型。具有这些显示值的元素的尺寸约束在单独的代码路径中计算,完全绕过了施加在字段集上的强制最小宽度。

同样,这个bug在Firefox 53已经修复了,所以如果你只是针对新版本,你不需要这个hack。

使用@-moz-document安全吗?

在这个问题上,是的。@-moz-document在53版本之前的所有Firefox版本中都正常工作,该错误已被修复。

这并非偶然。部分由于这个答案,将@-moz-document限制为用户/UA样式表的错误取决于底层字段集的错误首先被修复。

除此之外,不要在CSS中使用@-moz-document来针对Firefox,尽管有其他资源


¹值可以加前缀。根据一位读者的说法,这在Android 4.1.2库存浏览器和其他旧版本中没有影响;我还没有时间去核实。

²本回答中所有到Gecko源代码的链接均参考5065fdc12408变更集,提交29ᵗʰ2013年7月;您可能希望与Mozilla Central的最新修订版进行比较。

参见e.g. SO #953491:仅针对Firefox使用CSS和CSS技巧:CSS黑客针对Firefox在知名网站上被广泛引用的文章。