22. 通用容器--div 和 span 元素
- 详细资料
- 发布于 2012年9月18日
- 点击数:4694
序言
在本篇文章中,我将向你们介绍何时以及如何使用 HTML 中两个不是用于描述内容的元素。span
和 div
这两个元素不会向它们所包裹的内容赋予任何的含义;反之,它们是在没有其它合适的 HTML 元素可用时,用于创建自定义的结构或元素分组的一种通用机制。然后就可以用 CSS 对这些结构或分组进行样式化,或通过 JavaScript 对其进行操作。尽管 div
元素未添加任何语义含义,但跟适当语义的 class
或 id
名称一样,div
元素可被认为是表示标记的结构性分区。
div
是“标签的最后一种选择”,并且只能被用于没有其他合适的 HTML 元素的情况下,因为 div
对辅助技术或搜索引擎都没有任何意义可言。
本文的结构如下:
语义中性
HTML 中绝大多数元素都是用于描述内容的,例如图像、列表、标题,或是辅助建立文档的,如头部、主体、链接、元信息等。不过有两个元素是没有给定的含义的。HTML 规范中说:
div
和span
元素,连同id
和class
属性,为向文档添加结构提供了一种通用的机制。
这两个元素可被视为是 HTML 的“脚手架”。它们让你能对内容进行分类、在内容周围添加额外信息,并为添加样式和交互性提供钩子。不过它们并不向文档添加任何新的语义含义,无论是在它们包裹之中的内容还是它们自身。
内联元素和区块元素
通过前面的学习,你们已经知道区块元素是指明文档结构的元素。div
元素,division 的缩写,是块级通用容器。它通常被用于包裹其它块级元素,将它们集合在一起(更多讨论请参见下一部分)。它也可被用于把一串在逻辑上不适合放在其它块级元素之下的内联元素和/或文本组合在一起,不过只应作为最后的手段使用。
span
元素是内联通用容器。它同样可帮助指明文档结构,不过是用于集合或包裹其它内联元素和/或文本的,而不是块级元素。
初看之下,这两种不同类型元素之间的区分似乎是非常随意的。需要记住的是,差别之处在于内容的类型,以及在未添加任何样式时内容将如何显示。div
元素包裹的是一组块级元素——例如包裹一个标题加上一个链接列表,以创建一个导航菜单。span
元素包裹的是一组内联元素或(最常见)纯文本。这里“组”这个词很关键,如果 div
元素仅包裹一个块级元素,或 span
元素仅包裹一个内联元素,就没有必要使用它们。例如,请查看以下这段简单的标记中使用 div
和 span
元素的方式:
<body> <div id="mainContent"> <h1>Title of the page</h1> <p>This is the first paragraph of content on my example page.</p> <img src="/example.gif" alt="This image is merely an example, nothing special"> <p>This is the second paragraph of content on my example page. It is very similar to the first, but there is a <span id="specialAlert">special alert here that we want to colour and increase text size using CSS</span>. It's not really standard emphasis - it's more just styling, so <em> and <strong> are not really appropriate.</p> </div> </body>
现在你可以使用它们的 id
属性来选择 div
和 span
元素中的内容,并使用 CSS 对它们进行专门的样式化和定位。
分组内容的进一步说明
通过查看互联网上很多网页的源代码,你都将看到大量的 div
元素以及写在 class
和/或 id
中的一些常见含义——例如 header
、footer
、content
、sidebar
,等等。
class
和 id
的名称应该始终都是语义化的,也就是说,它们应该指内容的含义/作用,而不是仅仅指内容的视觉外观。例如 sidebar
(边栏)和 alertMessage
(警示消息)就是很好的 class
名称,而 redLefthandColumn
(红色的左边栏)和 blueFlashingText
就不是。如果以后你想将边栏的颜色改为红色,或将其位置从页面左边调整到页面右边,redLefthandColumn 这个 class
名称还有什么用呢?还有如果你想将警示消息从蓝色闪光改为绿色不闪光,blueFlashingText 这个 class
名称又有什么用呢?
这些分区在创建页面结构时提供了代码结构的可预测性,更重要的是,在后来重新查看 HTML 代码时,它们提供了你正位于页面哪个部分的线索。一个划分清晰的网页,其内容和意图几乎就是自文档化的。
为更清楚地说明这个道理,让我们在一个真正的网站上查看一下它的 div
结构——即 dev.opera.com 的主页。请注意,除了我特意包含进去的其它一些对创建页面结构来说很重要的元素,以下的示例代码中未包含任何内容。不过我主要考察的还是使用 div
元素来重现该网站的实际结构。在以下的代码中,请仔细阅读这些 HTML 注释——我加入了一些说明网页结构的 HTML 注释。在查看源代码的同时,请在你的浏览器新标签页或窗口中打开 dev.opera.com 的主页,这样你就可以通过参照该网站的外观来研究其结构。
<body> <!-- First up we have a wrap div, which wraps the entire page, and allows more precise control of it as a whole --> <div id="wrap"> <!-- This unordered list contains the list of links to all Opera's different sites, which you can see across the very top of the page --> <ul id="sitenav" class="hidemobile"> ... </ul> ... <!-- This is the search form - the search box you see at the top right of the page --> <form action="/search/" method="get" id="search"> <div> ... </div> </form> <!-- This unordered list contains the main navigation menu of the site - the horizontal tab menu you see just below the main title graphic --> <ul id="menu"> ... </ul> <!-- This nested div forms the structure of the login box, where you enter your user name and password to log in to the site. You will only see this if you are currently logged out. --> <div id="loginbox"> <div id="login"> ... </div> </div> <!-- This series of nested divs is where the main content of the page is contained - all of the article summaries that form the main bulk of the page content --> <div id="content2"> <div id="main"> ... <div class="major"> ... </div> <div class="major"> ... </div> ... </div> </div> <!-- This div contains the sidebar of the page - the article categories, the latest comments, etc --> <div id="side"> ... </div> <!-- This div contains the page footer, which is where you'll see the copyright message, and various links at the bottom of the page. --> <div id="footer"> ... </div> <!-- The end of the page - this is the closing tag for the wrap div --> </div> </body>
额外信息
一些内容具有对用户代理和其它解析器有用的额外信息,这类额外信息需要通过一个属性来传达。span
元素为将此类额外信息附加到网页内容上提供了很好的方式,就如你们将在下面所看到的那样。
在一个文档中出现另一种不同的语言,就是一个好例子。例如:
<p><q>Plus ça change, plus c'est la même chose</q> she said.</p>
尽管主文档的语言为英语,但这段引用是法语。通过使用 lang
属性,这一点得以被指明,如下所示:
<p><q lang='fr'>Plus ça change, plus c'est la même chose</q> she said.</p>
在以上这个例子中,由于整句引语都是法语,要标记出语言的变化是很容易的,使用 q
元素将引语包裹起来即可。不过在有些情况下,当没有适当的语义化元素可用时,就只能采用 span
或 div
元素,例如:
<p>A screen reader will read the French word chat (cat) as chat (to talk informally) unless it is properly marked up.</p>
在以上这个例子中,单词 chat 的第一个实例,作为英语文档中出现的一个法语词,必须指明其差异才不会被解释为英语单词chat。这时就可以使用 span
元素将“chat”这个法语词包裹起来,因为其它 HTML 元素都不适于用来包裹这个法语词(我们并不想强调这个词,它既不是一句引语,也不是一段代码,等等)。同时作为一个句子内的单个词语,它属于内联级别。因此上面那段代码最好写成下面这个样子:
<p>A screen reader will read the French word <span lang='fr'>chat</span> (cat) as chat (to talk informally) unless it is properly marked up.</p>
使用微格式 标记网页内的一般数据格式时,也用到了同样的技术。关于微格式更多的信息,可在 dev.opera.com 上关于更高级的 HTML 的文章中找到。
JavaScript 和 CSS 的钩子
我已经讲过,如何使用 div
和 span
,连同 id
和 class
属性,为页面内特定部分的内容提供 CSS 样式化和定位的钩子。在文档中使用 JavaScript 时,也可以这样做。
如果文档内某一给定的元素需要由 JavaScript 查找和处理,通常的做法是为该元素赋一个 id
然后使用 getElementById
函数来找到这个元素。关于 JavaScript,在本课程的后面部分将详细讲述。
避免滥用 div 元素
有一点值得引起注意,那就是在 web 开发人员圈子里通常被称为“div-itis”的对 div 元素的滥用现象。
通过大量的嵌套 div
或 span
元素来添加样式确实很方便,但还是应尽量避免这种诱惑。在多数情况下,为文档内现有元素附加样式或 JavaScript 功能是可以做到不必引入 div
或 span
元素的。作为通用容器的 div
或 span
元素应作为最后的手段使用——也就是说,最好是先尽量以语义化元素来编写网页,仅在确实需要时才加入通用容器元素。
不恰当的语义元素
在这个部分,我们将探讨一些使用 HTML 标记内容时的常见错误,如果可能的话,应尽量避免犯这些错误。
通用“段落”
有时候人们倾向于将任何文本块都包裹在 p
(段落)元素之中,这其实是不对的。正如我在前面那篇 关于标记文本内容的文章中已指出的那样:
那些不成句子、仅由几个词组成的文本,不应被标记为一个段落。
对于那些不能被其它具有语意的 HTML 元素所涵盖的不连贯的文本内容,将它们包裹在 div
或 span
(视具体情况而定)元素中,才是正确的选择。
表象性元素
在互联网上经常看到一种不良建议,即建议使用短的表象性元素如 b
或 i
元素来代替 span
元素作为通用容器,其理由无外乎以下两个原因中的一个:
- b 或 i 元素比 span 元素少 3 个字节,这样在 HTML 和 CSS 中都节省带宽。
- 内容所需的样式仅涉及外观,因此在这种情况下使用“表象性”元素是可以的。
第一个理由并没有错,但所节省的带宽可以忽略不计(除非你使用了惊人数量的表象性元素)。而且 web 服务器在通过互联网将文档发送到浏览器上之前,都要采用现代技术对文档进行压缩,这已让文档的体积大大缩小,远超过任何人工缩写所能达到的程度。
第二个理由则显示出他们对 HTML 语境中表象性元素的真正含义缺乏正确的理解。表象性元素描述的是它们所包含的内容所应有的外观(如 b
就仅仅是指“包含的文本以粗体显示”)。而不是为它们所包含的内容提供进行样式化的通用钩子。
如果一个段落中的一小段文本需要被样式化或被 JavaScript 处理,且没有适用的语义元素来包裹该文本,那么使用 span
元素来包裹它们就是唯一正确的选择。
总结
我已深入地讲述了 span
和 div
元素的各个方面——在读完这篇文章后,你们应该已经很好地了解了这两个元素的功能,并能自如地使用它们了。在后面关于 CSS 的文章中,我将更深入地讲述如何使用它们进行页面布局及其它内容。
练习题
div
元素和span
元素的区别何在?- 给出这两种元素在网页内的两个主要用途。
- 查看你最喜爱的网站内某一个网页的源代码,并思考其页面结构。该页面是否使用了大量的
div
和span
元素?你能发现有不正确地使用这两个元素的地方吗?如果有,该如何修正?