由p元素不能包含什么想开去

今天在做读书笔记的时候(目前使用HTML书写),遇到一个困惑:p元素不能包含什么?不想不知道,一想吓一跳。正如最近几天我在反思的:自己对HTML标准理解不够深入,导致自己在很多地方认识很模糊,进而产生模棱两口的情况。我是有着选择强迫症的,这是我不能忍受,多种选择的我定要区分出最佳出来的(在某些时候其实这也挺好)。比如今天的问题:由p元素不能包含?就暴露了自己对行内元素以及块元素区认识不深刻(这是委婉的说法,实际我一直对此的认识为空白),扯远点还有对语义化认识不足。

起初我仅仅想知道p元素不能包含哪些元素,想找出有没有业界约定俗成的做法。但是这样Google显然是无果的,但幸运的是我发现了这篇文章 《HTML中为何P标签内不可包含DIV标签?》 ,这篇文章完美的得解决了我心中的疑惑,并且将我的思考思考方向引领到正确的方向上去。

本文开头提出的问题可以转化为:p元素是什么?既然是块元素,那么问题就是块级块元素不能包涵哪些元素。首先我们需要了解HTML约束的分类。在网上胡乱Google到这些(也无法考证正确性)。HTML元素分为三大种:

  • 顶级元素(Top-level element)
  • 块级元素(Block-level element)
  • 内联元素(Inline element)

下面是对三中元素分类的解释:

顶级元素(Top-level element):

包括html、body、frameset、表现如Block-level element, 属于高级块级元素。这个说法也比较少见,也无法验证是否正确(这种说法在XML中倒是有)。鉴于关于顶级元素的知识点对于解释本文疑惑无太大帮助,姑且跳过。

块级元素(Block-level element):

顾名思义就是以块显示的元素,比如我们常用的 p, h1~h6, div, ul 默认状态下都是属于块级元素。

  • 高度、行高以及顶和底边距都可控制
  • 宽度缺省是它的容器的 100%,除非设定一个宽度。
  • 默认状态下每次都占据一整个行,后面的内容也必须再新起一行显示。

块级元素主要有

address 地址 blockquote 块引用 center 居中对齐块 dir 目录列表
dl 定义列表 div 块级元素 filedset form控制组 form 交互表单
h1 大标题 h2 副标题 h3 3级标题 h4 4级标题
h5 5级标题 h6 6级标题 hr 水平分割线 menu 菜单列表
ol 排序表单 p 段落 table 表格 ul 非排序列表

内联元素(Inline element)

通俗点来说就是文本的显示方式,与块级元素相反,我们常用到的a、span、em都属于内联元素。在《CSS权威指南》这样定义到,“任何不是块级元素的可见元素都是内联元素。

  • 内联元素的高、行高及顶和底边距不可改变
  • 其宽度就是自身文字或者图片的宽度,不可改变
  • 内联元素依附其他块级元素存在, 紧接于被联元素之间显示, 而不换行

通过改变内联元素CSS的display为inline或者给内联元素添加float属性,可以将行内元素转化为块级元素。这时候的内联元素,虽然具有了块状元素的特征,但是这两种有一点区别:

  1. display:block:彻头彻尾和块元素一模一样、都要单独占一行、从左至右,前提没有width和height属性。严格遵循流动布局模型块元素的流动布局方式,自上至下流动。
  2. float:大小是恰好能将内容包含、并且右侧浮动,可以多个在一行。

当加上position:absolute/relative的时候,块状元素和内联元素就不受父级区域的限制了,可以移动到任何位置,此时如果加上width和height属性,那么就具有层的特征了(加上width和height 还有一点好处,就是可以兼容IE浏览器了,所有的浏览器实现效果都一样了)。

内联元素(Inline element)

a 锚点 abbr 缩写 acronym 首字 b 粗体
big 大字体 br 换行 cite 引用 code 计算机代码(在引用源代码的时候需要)
dfn 定义字段 em 强调 font 字体设定(不推荐) i 斜体
img 图片 input 输入框 kbd 定义键盘文本 label 表格标签
q 短引用 s 中划线(不推荐) smap 定义范例计算机代码 select 项目选择
small 小字体文本 span 常用内联容器,定义文本区块 strike 中划线 strong 粗体强调
sub 下标 sup 上标 textarea 多行文本输入框 tt 电传文本
u 下划线 var 定义变量 del 删除 center 居中

搞清楚了内联元素与块级元素的区别,我们再引入这样一条规则: _XHTML DTD中规定p元素中不能插入块级元素,包括自身, 来源 _。所以问题的答案一下子豁然开朗了(实际上我在书写本文的时候还在犯这个错误)。

由此继续引申下去,那么HTML标签正确的嵌套应该是什么呢?

回到上文我可再次回顾HTML元素分类,我们换一种名称来称呼他们

  1. 顶级元素(Top-level element)——一集元素
  2. 块级元素(Block-level element)——二级元素
  3. 内联元素(Inline element)——三级元素

除了上表列出元素,在HTML里有几个元素是比较特别的:ul、ol、dl、table,它们的子一层必须是指定元素,ul、ol的子一级必须是li;dl的子一级必须是dt或者dd; table的子一层必须是caption或thead、tfoot、tbody等,而再子一层必须是tr(tr只存在于thead、tfoot、tbody中),之后才是可放内容的td或者th。

我的理解就是三集元素不能包含《二级元素不能包含《一集元素,以此类推。二级元素可以自由嵌套(p标签除外):例如我们可以把ul嵌在div里面,也可以把div嵌在li里面。

一丝不苟严谨可爱的老外们可不会放过。 Allowed nesting of elements in HTML 4 Strict (and XHTML 1.0 Strict)这篇文章就解释了该问题。我将文章中重点截成图片更加容易看清:

Allowed nesting of elements in HTML 4 Strict  and XHTML 1.0 Strict


update:

本文的文成参考了如下文章:


更新于:2013年5月5日 2:30

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注