<fieldset>resize错误; 似乎有不可移动的`min-width:min-content`

问题

我有一个<select>其中一个<option>的文本值非常长。 我希望<select>resize,所以它不会比其父级宽,即使它必须切断其显示的文本。 max-width: 100%应该这样做。

在resize之前:

调整大小之前的页面,显示整个<code> select </ code>

resize后我想要什么:

我想调整大小后的页面,用<code> select </ code>剪裁它的内容

但是,如果加载此jsFiddle示例并将“结果”面板的宽度调整为小于<select>的宽度,则可以看到<fieldset>中的select未能缩小其宽度。

resize后我实际看到的是:

我的当前页面调整后,用滚动条

但是, 具有<div>而不是<fieldset>的等效页面可以正确缩放。 如果在一个页面上有一个<fieldset>和一个<div>则可以更容易地看到并更改testing 。 如果你删除周围的<fieldset>标签 ,resize的作品。 <fieldset>标记以某种方式导致水平resize中断。

<fieldset>行为就好像有一个CSS规则fieldset { min-width: min-content; } fieldset { min-width: min-content; } 。 ( min-content意思是指不会导致孩子溢出的最小宽度。)如果用<div> min-width: min-content <div>min-width: min-contentreplace<fieldset> ,它看起来完全一样。 然而,在我的样式中,在浏览器的默认样式表中没有规则,或者在Firebug的CSS检查器中可见。 我尝试覆盖Firebug的CSS Inspector中的<fieldset>和Firefox的默认样式表forms.css中可见的每个样式,但是这并没有帮助。 特别是重写min-widthwidth也没有做任何事情。

字段集的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例子中 ,这个例子更类似于我实际试图修复的网页。 你可以看到<select>不是问题 – 内联块div也无法resize。 虽然这个例子比较复杂,但我认为上面这个简单例子的修复也将解决这个更复杂的情况。

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

关于这个问题的一个好奇的是, 如果你设置div.wrapper { width: 50%; } div.wrapper { width: 50%; }<fieldset>停止调整自身的大小,那么全尺寸的<select>将会碰到视口的边缘。 resize就好像<select>具有width: 100% ,尽pipe<select>看起来像是具有width: 50%

用50%宽度的包装div调整大小后

如果给出<select>本身width: 50% ,则不会发生该行为; 宽度只是正确设置。

选择50%宽度后调整大小

我不明白这个差别的原因。 但它可能不相关。

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

背景目标和要求

我试图做到这一点的原因是作为一个现有的大型窗体页面的移动样式的一部分。 表单有多个部分,其中一部分包含在<fieldset> 。 在智能手机上(或者如果您使浏览器窗口很小),使用<fieldset>的页面部分比表格的其余部分宽得多。 大部分表单限制了它的宽度,但是<fieldset>部分没有,迫使用户缩小或向右滚动查看所有的部分。

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

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


编辑:浏览器支持

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

我在不同的浏览器上重新testing了我的破解的fieldset示例 。 它实际上已经在这些浏览器中工作:

  • Internet Explorer 8,9和10
  • 适用于Android的Chrome

它在这些浏览器中打破:

  • 火狐
  • 适用于Android的Firefox
  • Internet Explorer 7

因此,我唯一关心的是当前代码打破的浏览器是Firefox(在桌面和移动设备上)。 如果代码是固定的,所以它在Firefox中工作,而不会在任何其他浏览器中打破它,这将解决我的问题。

网站HTML模板使用Internet Explorer条件注释将诸如.ie8.oldie等类添加到<html>元素。 如果您需要解决IE中的样式差异问题,则可以在CSS中使用这些类。 添加的类与此旧版本的HTML5 Boilerplate相同 。

更新(2017年9月25日)

让我很高兴的是,下面描述的Firefox bug在Firefox 53中是固定的,而且这个答案的链接已经从Bootstrap的文档中删除了 。

修复

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

尽pipe如此,Firefox在字段集中还是有点奇怪的。 若要在早期版本中使用此function,您必须将字段集的display属性更改为以下值之一:

  • table-cell (推荐)
  • table-column
  • table-column-group
  • table-footer-group
  • table-header-group
  • table-row
  • table-row-group

其中,我build议table-celltable-rowtable-row-group防止你改变宽度,而table-columntable-column-group防止你改变height。

这将(有点合理)中断在IE中的渲染。 由于只有Gecko需要这个,所以你可以合理地使用Mozilla专有的CSS扩展的 @-moz-document -one来将其隐藏起来:

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

(这是一个jsFiddle演示 。)


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

什么。

有一个原因,但不是很漂亮。

fieldset元素的缺省表示是荒谬的,在CSS中不可能指定。 仔细想想:fieldset的边框会消失在与图例元素重叠的地方,但是背景仍然可见! 没有办法用任何其他元素的组合来重现这一点。

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

但是,内部表格元素构成了Gecko中的特殊框架types 。 具有这些display值设置的元素的尺寸约束是在单独的代码path中计算的,完全避免了施加在字段上的强制的最小宽度。

再次 – 这个错误已经被修正为火狐53,所以你不需要这个黑客,如果你只是针对较新的版本。

正在使用@-moz-document安全吗?

对于这个问题,是的。 @-moz-document在所有版本的Firefox中都能正常工作,直到53年,这个bug已经修复。

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

除此之外,我不再build议使用@-moz-document在你的CSS中专门定位Firefox,尽pipe如此。


¹值可能以前缀。 据一位读者介绍,这在Android 4.1.2 Stock Browser和其他旧版本中可能没有任何影响; 我没有时间来validation这一点。

²在这个答案中所有指向Gecko源的链接都是指2013年7月29日承诺的5065fdc12408变更集 ; 您可能希望将注意事项与Mozilla中心的最新版本进行比较。

³参见例如SO#953491:仅针对Firefox和CSS以及CSS技巧:针对Firefox的CSS黑客攻击高端网站上广泛引用的文章。

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

我发现Jordan Gray的答案特别有用。 然而它似乎并没有解决这个问题在Safari iOS上。

这个问题对我来说很简单,如果字段中的元素的最大宽度为%宽度,则字段集不能有自动宽度。

修复问题

简单地将字段设置为100%宽度的容器似乎解决了这个问题。

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

请参阅下面的工作示例 – 如果您从字段集中删除%宽度或将其replace为自动,它将不会继续运行。

JSFiddle | Codepen

我已经挣扎了好几个小时,基本上,浏览器正在应用您需要在CSS中重写的计算样式。 我忘记了fieldset元素与div的设置(也许min-width ?)的确切属性。

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

希望有所帮助。

更新:添加display: table-cell有助于在非Chrome浏览器中使用。

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

删除该规则,并将.fake-selectmax-width:100%更改为width:100%并且一切都合适。 需要注意的是,你可以看到假select的所有内容,但是我认为这并不是那么糟糕,现在它是水平的。

更新:在下面的小提琴(其中只包含真正的select)当前的规则,字段的子项被限制为正确的宽度。 除了删除.fake-select和修复注释的规则(从// comment/* comment */ ,我已经注意到小提琴的CSS的变化。

我现在更了解你的问题了,小提琴反映了一些进步。 我为所有的<select> s设置了默认规则,并且为那些你知道宽度超过480px的人保留.xxlarge(这只适用于你知道 #viewport的宽度,并且可以手动将这个类添加到那些太宽的类中。只需要一点点的testing)

certificate