<pre>会撑开父辈<fieldset>的宽度,怎么能让pre的宽度随filedset的宽度

写手机页面,所以不希望有滚动条的解决方案,而且希望pre能自动适应父辈fieldset的宽度

阅读 16.1k
2 个回答

更新:对pre的机制说明更新

更新2:给出解决方案

更新3:两年以后,终于找到了stackoverflow的处理方案……


第一个问题,fieldset的设置宽度以后,为何会被撑宽。

fieldset在没有内部元素时,是以block方式解析的,即外部100%宽度自适应;但设置width以后,本应当维持这个宽度了,为何会被撑宽呢?

因为它的min-width属性,在CSS的属性的权重中,min-width > width,在chrome里面:

fieldset { min-width: -webkit-min-content; }

改变它的min-width就可以,复写它的值,或者改为inherit(考虑到是手机端开发,inherit是全支持的)都可以。

fieldset { min-width: inherit; }
/*or*/
fieldset { min-width: 100px; }

IE和chrome的相应问题已经解决,但是还剩firefox。查看fieldset的默认样式:

cssfieldset {
  display: block;
  margin-left: 2px;
  margin-right: 2px;
  padding: 0.35em 0.625em 0.75em;
  border: 2px groove ThreeDFace;
}
*|*::-moz-fieldset-content {
  display: block;
  unicode-bidi: inherit;
  text-overflow: inherit;
  height: 100%;   
}

抱歉,没有能够找到使得其宽度固定时,使得其被子元素撑宽的属性。等今后有空了再细细研究吧。

至此,已经能符合楼主的一半要求,在手机端大部分浏览器(非firefox浏览器)下面,fieldset的宽度不再被子元素撑宽。


第二个问题,pre元素为何会自动撑宽。

因为其white-space属性:

pre { white-space: pre; }

pre的语义既是预保留格式,这意味着(外部标签无法决定pre标签的宽度,pre标签自动包裹内部的文本节点,不忽略空白//有误,见下)。

pre标签的宽度是由如下机制进行的:

  1. 在内部内容不宽过父容器时,其宽度自适应于父容器;
  2. 在内部内容比父容器宽的时候,其宽度包裹内部内容。

这个机制类似于min-width,但比min-width还多了对于换行/空白符的处理,下面是w3school对于white-space属性值的解释:

normal  默认。空白会被浏览器忽略。
pre 空白会被浏览器保留。其行为方式类似 HTML 中的 <pre> 标签。
nowrap  文本不会换行,文本会在在同一行上继续,直到遇到 <br> 标签为止。
pre-wrap    保留空白符序列,但是正常地进行换行。
pre-line    合并空白符序列,但是保留换行符。
inherit 规定应该从父元素继承 white-space 属性的值。

把white-space改为除了nowrap和pre以外的值即可符合你的要求。不过我想问,你真的需要修改pre标签的默认行为吗?改变pre标签的默认行为,即意味着你放弃了pre标签的原本语义。


所以我们看看撑宽的路线:

pre内部文本节点宽度—(white-space:pre撑宽机制)—>pre宽度—(min-width自动包裹内部内容撑宽机制)—>fieldset宽度。

而我们想要的自适应宽度的路线:

fieldset宽度—(定宽机制)—>pre宽度—(white-space:非pre/非nowrap排版)—>pre内部文本节点宽度。

所以,有两种解决方案:

  1. 破坏fieldset的min-width包裹机制,破坏pre的white-space撑宽机制,放弃pre标签的语义。
  2. 破坏fieldset的min-width包裹机制,保留pre的white-space撑宽机制,给外层加上overflow,如下:
    fieldset {
      overflow:scroll;
      -webkit-overflow-scrolling:touch;
      -moz-overflow-scrolling:touch;
      -o-overflow-scrolling:touch ;
    }

<pre> 会撑开很多标签的宽度,不仅仅是 <fieldset>

解决的方法就是为<pre>设置一个溢出属性:

pre {
  overflow: auto;
}

超过容器时显示滚动条即可。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题