HTML中`Content Model`和CSS中的`Replaced element`

发表于 2017-01-24
更新于 2024-05-23
分类于 技术专栏
阅读量 9919
字数统计 3746

前言

写这篇文章缘于在写下面这两段代码的时候没有得到自己想要的结果,于是乎,便仔细深究这个问题的原因:

第一段代码:

button {
  display: block;
}
<button style="width: auto;">要独占一行,结果没有</button>

第二段代码:

1、问题一

要想弄清上面第一个问题的原因,我们还得将CSS的一个基础概念拿出来解释,其实这个概念也是我第一次才知道。

1.1、Replaced Element vs Non-replaced Element

如果在Google上搜索这两个概念,可以出现很多的解释,我自己找了一下,发现这个解释算是最形象的一个: CSS Non-replaced and Replaced Elements

CSS将HTML标签分为两类:非替换元素和替换元素。下面是对这两个分类的描述
1. Non-replaced elements-绝大部分的HTML元素都有一个开始标签和一个闭合标签,在两个标签之间放着我们想要展示的内容。比如:
<div>content</div>或<p>content</p>

div和p元素都被成为non-replaced元素因为他们的内容是实实在在地显示,也就是两个标签里有什么就显示什么,并不会被其他东西给替换掉

2. Replaced elements-一些HTML元素在其开始和结束标签之间没有内容,比如:
<img src="eightball.gif">  或  <input type="reset">
img和input元素没有独立的结束标记因此他们没有任何内容。这些元素使用属性去指定想要显示的外部资源(external resources)。在上面的例子中,img元素指定一张想要显示的图片,input则指定一个按钮。你可以这么说:“它们的内容被外部资源给替换掉了”

ok,翻译完上面的解释之后,相信大家应该能够明白这个概念的含义了吧

1.2、Replaced Elements的特性

现在我们知道Replaced element的显示和大小都是由其外部资源决定,那么有多少HTML元素属于这一种范畴呢?Rendering章节明确指出了<img>(images )、<object>(plugins )、<button><textarea><input><select>等都是属于该类,更多的可以参考replaced elments

Replaced Elements有固有的大小-也就是说其宽度和高度都是元素自己本身定义而不是它所处的文档周边的元素。比如,如果一个image元素的宽度设置为auto,那么它使用的外部资源-图片的大小将决定其宽度。除了固有大小的特性之外还有一个内在比例,也就是说如果你指定img的宽度为100px,但是外部资源即图片的大小是200*100px,那么图片的大小最后会按照等比例的形式压缩或者扩展,此例中为100*50px

1.3、结论

现在我们知道button标签属于replaced element,那么其大小是由其button内部的那些文字决定的当其width=auto的时候,即使display:block也无法改变这种特性

2、问题二

问题二的问题是在Firefox中,代码写的监听mousedown事件不生效,但是在谷歌却是可以的,那么这是为什么呢?

弄懂这个问题之前我们依然要揪出一个以前从未听过的概念:Content Model,在MDN有关于它的解释。

2.1、Content Model

根据MDN的描述,每一个HTML元素必须遵从规则去定义它自己本身可以存放哪种类型的内容。这些规则被分成几组内容模型给一些元素共用,每一个HTML元素可以属于0个或者1个、多个内容模型。

根据W3C,内容模型大致分为以下7种:Flow, Metadata, Embedded, Interactive, Heading, Phrasing 和 Sectioning。

其关系如下:

内容模型的作用在于帮助告诉编程者在某个元素之内适合放置什么类型的内容,这有助于缩小某些HTML规则范围,如元素嵌套。

但请记住并不是HTML5所有的元素都会属于这些模型,有些会属于其他分类,比如Transparent或Form-associated。

更多内容请参考MDN,这里我们只想针对button标签做出解释。

2.2、button的特性

在MDN上我们可以看到button有下面列举的特性:

其中我们注意到有这么一个特性Permitted content,也就是button内部能够允许放置的内容模型,即Permitted content。如果大家仔细看是会发现在MDN上的所有标签都有这些特性,甚是清楚。

2.3、结论

由此我们知道,button只能放置Phrasing content的内容模型,而我们查看Phrasing content包含哪些标签可以发现并没有div标签,也就是说如果按照上面代码的书写方式,在严格的浏览器下渲染是不承认这种嵌套方式的,也就是会忽略掉对应的代码,那么火狐浏览器就是属于那种严格的浏览器,而谷歌浏览器的兼容性比较强,所以可以监听到mousedown的事件。

因此写HTML文档树的时候建议还是严谨些,不要在不能用的地方用上某些标签,切记切记。

参考

  1. https://www.w3.org/TR/CSS21/conform.html
  2. http://stackoverflow.com/questions/40975094/mousedown-listener-doesnt-work-in-firefox-on-absolute-positioned-element/40975362#40975362
  3. https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element
  4. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
  5. https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories
  6. http://reference.sitepoint.com/css/replacedelements
  7. https://www.w3.org/TR/html5/rendering.html#replaced-elements
  8. http://stackoverflow.com/questions/27605390/why-doesnt-display-block-width-auto-stretch-a-button-to-fill-the-contai
  9. http://randymatusky.com/2015/09/15/understanding-html5-content-models/

公众号关注一波~

微信公众号

关于评论和留言

如果对本文 HTML中`Content Model`和CSS中的`Replaced element` 的内容有疑问,请在下面的评论系统中留言,谢谢。

网站源码:linxiaowu66 · 豆米的博客

Follow:linxiaowu66 · Github