iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Modern Web

前端迷走中:從零開始的新手之路系列 第 7

[Day07] 網頁也要分章節──續談HTML語意化結構元素

  • 分享至 

  • xImage
  •  

昨天我們介紹了網頁中常見的區塊,以及用來劃分這些區塊的語意化結構元素(semantic structural elements),包括<header><nav><main><aside><section><article><footer>等。

乍看之下,這些元素有其對應的網頁區塊,像是<nav>對應到導覽列。
但實際上,他們的意義不只是如此,所以<nav>也可能出現在其他地方。

這是怎麼一回事,又要怎麼使用這些元素呢?

讓我們繼續看下去~

<header>元素

規範<header>元素的定義如下:

The header element represents a group of introductory or navigational aids.

由定義可知,<header>元素能協助使用者理解當前看到的內容,或是便於使用者瀏覽網頁。

<header>裡通常會包括標題、Logo、作者資訊等。[1]

<header>元素不能放在<footer><address>元素裡,或是又放進其他的<header>元素裡。[1]

網頁頁首之外的<header>

<header>可能是直接放在<body>裡,也可能是放在<article><section>等元素裡。
如果是前者,會是整個網頁的頁首,可能會有網頁標題、Logo等;如果是後者,則會是這些元素內容的介紹,可能包括文章標題、作者資訊等。[2]

網頁內同時有多個<header>

一個網頁內可以同時有多個<header>元素。

MDN提供的這個例子中,便同時有兩個<header>存在於網頁內。其中一個直接放在<body>裡面的<header>,為整個網頁加入了帶有背景圖片的標題,且標題本身也是連結。另一個則放在<body>內的<article>裡,為文章添加標題以及編輯時間。

<body>
  <header>
    <a class="logo" href="#">Cute Puppies Express!</a>
  </header>
  <article>
    <header>
      <h1>Beagles</h1>
      <time>08.12.2014</time>
    </header>
    <p>
      I love beagles <em>so</em> much! Like, really, a lot. They’re adorable
      and their ears are so, so snugly soft!
    </p>
  </article>
</body>

頁首裡也可能有<nav>跟其他內容

在另外一個由規範提供的例子中,<header>直接放在<body>裡,是整個網頁的頁首。裡面有用<h1>定義的網頁標題,還有作為導覽列的<nav>。除了這些,還有一些關於網頁的介紹性內容,包括Important News與Games。

<body>
 <header>
  <h1>Little Green Guys With Guns</h1>
  <nav>
   <ul>
    <li><a href="/games">Games</a>
    <li><a href="/forum">Forum</a>
    <li><a href="/download">Download</a>
   </ul>
  </nav>
  <h2>Important News</h2> <!-- this starts a second subsection -->
  <!-- this is part of the subsection entitled "Important News" -->
  <p>To play today's games you will need to update your client.</p>
  <h2>Games</h2> <!-- this starts a third subsection -->
 </header>
 <p>You have three active games:</p>
 <!-- this is still part of the subsection entitled "Games" -->
 ...

<nav>元素

規範<nav>元素的定義如下:

The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.

由定義可知,<nav>元素用於引導使用者前往其他地方。不論裡頭的連結是通往其他網頁,還是通往同個網頁內的其他地方。

通常<nav>元素會以選單、目錄或索引的形式呈現於網頁中。[3]

網頁內同時有多個<nav>

一個網頁內可以同時有多個<nav>元素。可能有的用來切換至其他頁面,其他的則引導使用者前往頁面中的其他地方。

以下由規範提供的範例便同時有兩個<nav>。一個直接放在<body>裡,連結到其他頁面。另一個則放在<body>中的<article>裡,通往<article>的各個部分。

<body>
 <h1>The Wiki Center Of Exampland</h1>
 <nav>
  <ul>
   <li><a href="/">Home</a></li>
   <li><a href="/events">Current Events</a></li>
   ...more...
  </ul>
 </nav>
 <article>
  <header>
   <h2>Demos in Exampland</h2>
   <p>Written by A. N. Other.</p>
  </header>
  <nav>
   <ul>
    <li><a href="#public">Public demonstrations</a></li>
    <li><a href="#destroy">Demolitions</a></li>
    ...more...
   </ul>
  </nav>
  <div>
   <section id="public">
    <h2>Public demonstrations</h2>
    <p>...more...</p>
   </section>
   <section id="destroy">
    <h2>Demolitions</h2>
    <p>...more...</p>
   </section>
   ...more...
  </div>
  <footer>
   <p><a href="?edit">Edit</a> | <a href="?delete">Delete</a> | <a href="?Rename">Rename</a></p>
  </footer>
 </article>
 <footer>
  <p><small>© copyright 1998 Exampland Emperor</small></p>
 </footer>
</body>

不是所有連結都需要放在<nav>

雖然<nav>元素主要是用來放連結,但不是網頁中的所有連結都需要放在<nav>裡面,只有主要的導覽連結才需要用<nav>裝起來。

網頁頁尾內可能也會放入版權聲明或服務條款等頁面的連結。這些連結不需要特別用<nav>元素包起來,可以直接放在<footer>元素裡面就好。

以下是規範提供的另一個範例。可以看到雖然<header><footer>都有一些連結,但沒有再用<nav>元素裝起來。

<body itemscope itemtype="http://schema.org/Blog">
 <header>
  <h1>Wake up sheeple!</h1>
  <p><a href="news.html">News</a> -
     <a href="blog.html">Blog</a> -
     <a href="forums.html">Forums</a></p>
  <p>Last Modified: <span itemprop="dateModified">2009-04-01</span></p>
  <nav>
   <h2>Navigation</h2>
   <ul>
    <li><a href="articles.html">Index of all articles</a></li>
    <li><a href="today.html">Things sheeple need to wake up for today</a></li>
    <li><a href="successes.html">Sheeple we have managed to wake</a></li>
   </ul>
  </nav>
 </header>
 <main>
  <article itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting">
   <header>
    <h2 itemprop="headline">My Day at the Beach</h2>
   </header>
   <div itemprop="articleBody">
    <p>Today I went to the beach and had a lot of fun.</p>
    ...more content...
   </div>
   <footer>
    <p>Posted <time itemprop="datePublished" datetime="2009-10-10">Thursday</time>.</p>
   </footer>
  </article>
  ...more blog posts...
 </main>
 <footer>
  <p>Copyright ©
   <span itemprop="copyrightYear">2010</span>
   <span itemprop="copyrightHolder">The Example Company</span>
  </p>
  <p><a href="about.html">About</a> -
     <a href="policy.html">Privacy Policy</a> -
     <a href="contact.html">Contact Us</a></p>
 </footer>
</body>

<nav>也可以是文章?

雖然<nav>元素內的連結通常會以導覽列或是清單的形式呈現,但實際上也可以用其他方式呈現。
在下面來自規範的例子中,<nav>元素內便放入一般的文章,並在提及一些事物時適時加上相關連結。

<nav>
 <h1>Navigation</h1>
 <p>You are on my home page. To the north lies <a href="/blog">my
 blog</a>, from whence the sounds of battle can be heard. To the east
 you can see a large mountain, upon which many <a
 href="/school">school papers</a> are littered. Far up thus mountain
 you can spy a little figure who appears to be me, desperately
 scribbling a <a href="/school/thesis">thesis</a>.</p>
 <p>To the west are several exits. One fun-looking exit is labeled <a
 href="https://games.example.com/">"games"</a>. Another more
 boring-looking exit is labeled <a
 href="https://isp.example.net/">ISP™</a>.</p>
 <p>To the south lies a dark and dank <a href="/about">contacts
 page</a>. Cobwebs cover its disused entrance, and at one point you
 see a rat run quickly out of the page.</p>
</nav>

<main>元素

規範<main>元素的定義如下:

The main element represents the dominant contents of the document.

由定義可知,<main>元素裡面放的是網頁的主要內容。

版權資訊的頁尾、導覽列的連結等整個網站都有的共用資訊,不適合用<main>元素來裝。[4]

通常<main>元素的相鄰外層會是<body>元素,不會再包在其他元素之中。[2]

網頁內可以同時有多個<main>

一個網頁只能有一個<main>元素,除非其他<main>元素設定了hidden屬性。[4]

以下出自規範的例子中,雖然同時存在多個<main>元素,但其他<main>都加上hidden屬性,只有一個沒有hidden屬性。

<nav>
 <a href=/>Home</a>
 <a href=/about>About</a>
 <a href=/contact>Contact</a>
</nav>
<main>
 <h1>Home</h1>
 …
</main>
<main hidden>
 <h1>About</h1>
 …
</main>
<main hidden>
 <h1>Contact</h1>
 …
</main>
<footer>Made with ❤️ by <a href=https://example.com/>Example 👻</a>.</footer>

<aside>元素

規範<aside>元素的定義如下:

The aside element represents a section of a page that consists of content that is tangentially related to the content around the aside element, and which could be considered separate from that content. Such sections are often represented as sidebars in printed typography.

由定義可知,<aside>元素裡會放入與週遭主題沒有直接相關的內容。因為是間接相關的內容,如果抽掉也不會影響原本的內容。

<aside>元素通常會以側邊欄或對話框的形式呈現。[5]

<aside>不一定是網頁側邊欄

除了作為網頁的側邊欄,<aside>元素也可以放在網頁的主要內容裡,添加與主題間接相關的內容。

以下來自MDN的例子,便在<article>元素中放入了<aside>,以添加與主題間接相關的資訊。

<article>
  <p>
    The Disney movie <cite>The Little Mermaid</cite> was first released to
    theatres in 1989.
  </p>
  <aside>
    <p>The movie earned $87 million during its initial release.</p>
  </aside>
  <p>More info about the movie…</p>
</article>

網頁內同時有多個<aside>

一個網頁內可以同時有多個<aside>元素。但依據所在位置,代表的東西也會不同。

在下方由規範提供的例子中,總共有三個<aside>元素,其中兩個<aside>元素直接放在<body>裡,另一個放在表示部落格文章的<article>元素內。

放在<body>裡的<aside>,一個用來放作者於推特上的推文。另一個<aside>裡放了兩個<nav>,分別導覽至其他部落格,以及該部落格的文章。
至於<article>裡的<aside>,則用來放跟文章間接相關的內容。

<body>
 <header>
  <h1>My wonderful blog</h1>
  <p>My tagline</p>
 </header>
 <aside>
  <!-- this aside contains two sections that are tangentially related
  to the page, namely, links to other blogs, and links to blog posts
  from this blog -->
  <nav>
   <h2>My blogroll</h2>
   <ul>
    <li><a href="https://blog.example.com/">Example Blog</a>
   </ul>
  </nav>
  <nav>
   <h2>Archives</h2>
   <ol reversed>
    <li><a href="/last-post">My last post</a>
    <li><a href="/first-post">My first post</a>
   </ol>
  </nav>
 </aside>
 <aside>
  <!-- this aside is tangentially related to the page also, it
  contains twitter messages from the blog author -->
  <h1>Twitter Feed</h1>
  <blockquote cite="https://twitter.example.net/t31351234">
   I'm on vacation, writing my blog.
  </blockquote>
  <blockquote cite="https://twitter.example.net/t31219752">
   I'm going to go on vacation soon.
  </blockquote>
 </aside>
 <article>
  <!-- this is a blog post -->
  <h2>My last post</h2>
  <p>This is my last post.</p>
  <footer>
   <p><a href="/last-post" rel=bookmark>Permalink</a>
  </footer>
 </article>
 <article>
  <!-- this is also a blog post -->
  <h2>My first post</h2>
  <p>This is my first post.</p>
  <aside>
   <!-- this aside is about the blog post, since it's inside the
   <article> element; it would be wrong, for instance, to put the
   blogroll here, since the blogroll isn't really related to this post
   specifically, only to the page as a whole -->
   <h2>Posting</h2>
   <p>While I'm thinking about it, I wanted to say something about
   posting. Posting is fun!</p>
  </aside>
  <footer>
   <p><a href="/first-post" rel=bookmark>Permalink</a>
  </footer>
 </article>
 <footer>
  <p><a href="/archives">Archives</a> -
   <a href="/about">About me</a> -
   <a href="/copyright">Copyright</a></p>
 </footer>
</body>

<footer>元素

規範<footer>元素的定義如下:

The footer element represents a footer for its nearest ancestor sectioning content element, or for the body element if there is no such ancestor. A footer typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like.

由定義可知,<footer>元素是其所在的sectioning content element的註腳,或者說是各種補充資訊。

根據規範,這類元素包括<article><aside><nav><section>等。
如果<footer>元素不是包在這類元素裡面,則<footer>元素就會是有關<body>元素,即整個網頁的補充資訊。

<footer>元素裡通常會包括作者資訊、版權聲明、聯絡資訊、相關文件等。如果是聯絡資訊,通常會再用<address>元素包起來。
<footer>元素不能放在<header><address>元素裡,或是又放進其他的<footer>元素裡。[6]

網頁頁尾之外的<footer>

<footer>可能是直接放在<body>裡,作為整個網頁的頁尾,裡面放入版權聲明、聯絡資訊等關於整個網頁的補充資訊。
但也可能是放在<article><aside><nav><section>等元素中,代表關於這些內容個別的補充資訊。

網頁內同時有多個<footer>

一個網頁可以同時有多個<footer>元素。

在下列由規範提供的例子中,便同時有三個<footer>元素。其中一個直接放在<body>裡,裡面放了服務條款與部落格索引等連結。另外兩個則放在<article>裡,用於表示兩篇文章的發佈時間。

<HTML LANG="en"><HEAD>
<TITLE>The Ramblings of a Scientist</TITLE>
<BODY>
<H1>The Ramblings of a Scientist</H1>
<ARTICLE>
 <H1>Episode 15</H1>
 <VIDEO SRC="/fm/015.ogv" CONTROLS PRELOAD>
  <P><A HREF="/fm/015.ogv">Download video</A>.</P>
 </VIDEO>
 <FOOTER> <!-- footer for article -->
  <P>Published <TIME DATETIME="2009-10-21T18:26-07:00">on 2009/10/21 at 6:26pm</TIME></P>
 </FOOTER>
</ARTICLE>
<ARTICLE>
 <H1>My Favorite Trains</H1>
 <P>I love my trains. My favorite train of all time is a Köf.</P>
 <P>It is fun to see them pull some coal cars because they look so
 dwarfed in comparison.</P>
 <FOOTER> <!-- footer for article -->
  <P>Published <TIME DATETIME="2009-09-15T14:54-07:00">on 2009/09/15 at 2:54pm</TIME></P>
 </FOOTER>
</ARTICLE>
<FOOTER> <!-- site wide footer -->
 <NAV>
  <P><A HREF="/credits.html">Credits</A> —
     <A HREF="/tos.html">Terms of Service</A> —
     <A HREF="/index.html">Blog Index</A></P>
 </NAV>
 <P>Copyright © 2009 Gordon Freeman</P>
</FOOTER>
</BODY>
</HTML>

<article>元素

規範<article>元素的定義如下:

The article element represents a complete, or self-contained, composition in a document, page, application, or site and that is, in principle, independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.

由定義可知,<article>元素用於表示自身意義完整,可抽離當前網頁獨立存在,甚至能在其他網頁重複使用的內容。像是部落格文章、讀者留言跟小工具等。

<article>元素裡通常會有標題,也可能有<section>元素。[7]

一個網頁中可以同時有多個<article>元素。

<article>裡的<article>

<article>元素裡也可以再放入其他相關的<article>。舉例來說,在表示文章內容的<article>裡,放入表示讀者留言的<article>

以下範例來自規範。其中,在表示文章的<article>裡面,放入了表示留言的<section>。而這個<section>裡面,則包含了多個代表留言的<article>

需要注意的是,雖然這些留言是裝在文章內容的<article>裡面,也不代這些留言是文章的一部分。文章與留言都是具備完整意義的內容,彼此獨立存在。[8]

<article itemscope itemtype="http://schema.org/BlogPosting">
 <header>
  <h2 itemprop="headline">The Very First Rule of Life</h2>
  <p><time itemprop="datePublished" datetime="2009-10-09">3 days ago</time></p>
  <link itemprop="url" href="?comments=0">
 </header>
 <p>If there's a microphone anywhere near you, assume it's hot and
 sending whatever you're saying to the world. Seriously.</p>
 <p>...</p>
 <section>
  <h1>Comments</h1>
  <article itemprop="comment" itemscope itemtype="http://schema.org/Comment" id="c1">
   <link itemprop="url" href="#c1">
   <footer>
    <p>Posted by: <span itemprop="creator" itemscope itemtype="http://schema.org/Person">
     <span itemprop="name">George Washington</span>
    </span></p>
    <p><time itemprop="dateCreated" datetime="2009-10-10">15 minutes ago</time></p>
   </footer>
   <p>Yeah! Especially when talking about your lobbyist friends!</p>
  </article>
  <article itemprop="comment" itemscope itemtype="http://schema.org/Comment" id="c2">
   <link itemprop="url" href="#c2">
   <footer>
    <p>Posted by: <span itemprop="creator" itemscope itemtype="http://schema.org/Person">
     <span itemprop="name">George Hammond</span>
    </span></p>
    <p><time itemprop="dateCreated" datetime="2009-10-10">5 minutes ago</time></p>
   </footer>
   <p>Hey, you have the same first name as me.</p>
  </article>
 </section>
</article>

<section>元素

規範<section>元素的定義如下:

The section element represents a generic section of a document or application. A section, in this context, is a thematic grouping of content, typically with a heading.

由定義可知,<section>元素代表一種通用的結構區塊(也有人稱作區段),用來將相同主題的內容包在一起。

使用<section>元素時,通常會加上標題。

<section>元素不能放在<address>元素裡。[9]

作為組成成分

<section><article>類似。但相較於<article>元素具有完整獨立的意涵,<section>通常是作為其他完整內容的組成成分。[2]

以文章跟書籍來舉例的話,就會是段落之上整體之下的各層結構,像是章、節、小節等。

像是在規範提供的一個例子中,是以<article>元素來表示一篇關於蘋果的文章。而在這篇文章裡,又用兩個<section>區隔不同的段落,分別介紹不同的蘋果品種

<article>
 <hgroup>
  <h2>Apples</h2>
  <p>Tasty, delicious fruit!</p>
 </hgroup>
 <p>The apple is the pomaceous fruit of the apple tree.</p>
 <section>
  <h3>Red Delicious</h3>
  <p>These bright red apples are the most common found in many
  supermarkets.</p>
 </section>
 <section>
  <h3>Granny Smith</h3>
  <p>These juicy, green apples make a great filling for
  apple pies.</p>
 </section>
</article>

將其他內容包起來

雖然<section>常用於表示其他完整內容的組成成分,不過當這些完整內容屬於同個主題需要裝在一起的時候,就可以使用<section>將他們組織起來。

像是在前述介紹<article>的例子中,便是以<section>表示留言區,將表示讀者留言的<article>包在一起。而這個<section>又放在表示文章的<article>裡面。

所以也可能會有<article>裡有<section>,而這些<section>裡又有其他<article>的情況。

<article itemscope itemtype="http://schema.org/BlogPosting">
 <header>
  <h2 itemprop="headline">The Very First Rule of Life</h2>
  <p><time itemprop="datePublished" datetime="2009-10-09">3 days ago</time></p>
  <link itemprop="url" href="?comments=0">
 </header>
 <p>If there's a microphone anywhere near you, assume it's hot and
 sending whatever you're saying to the world. Seriously.</p>
 <p>...</p>
 <section>
  <h1>Comments</h1>
  <article itemprop="comment" itemscope itemtype="http://schema.org/Comment" id="c1">
   <link itemprop="url" href="#c1">
   <footer>
    <p>Posted by: <span itemprop="creator" itemscope itemtype="http://schema.org/Person">
     <span itemprop="name">George Washington</span>
    </span></p>
    <p><time itemprop="dateCreated" datetime="2009-10-10">15 minutes ago</time></p>
   </footer>
   <p>Yeah! Especially when talking about your lobbyist friends!</p>
  </article>
  <article itemprop="comment" itemscope itemtype="http://schema.org/Comment" id="c2">
   <link itemprop="url" href="#c2">
   <footer>
    <p>Posted by: <span itemprop="creator" itemscope itemtype="http://schema.org/Person">
     <span itemprop="name">George Hammond</span>
    </span></p>
    <p><time itemprop="dateCreated" datetime="2009-10-10">5 minutes ago</time></p>
   </footer>
   <p>Hey, you have the same first name as me.</p>
  </article>
 </section>
</article>

<section>的使用時機

優先使用其他語意化結構元素

由於<section>元素是通用的結構區塊,應該優先使用其他有明確意義的元素。只有在其他元素難以表達意義的情況下,才建議使用<section>。舉例來說,如果是網頁中的導覽列,就應該使用<nav>來表達。[9]

依情境判斷適合的元素

就算是同樣的內容,在不同情境下也可能適合用不同的元素包起來。[8]

規範以描述Granny Smith這種蘋果的話‘These juicy, green apples make a great filling for apple pies.’為例來說明。

如果這句話是放在書中,會適合用<section>裝起來。因為可能會有其他章節討論其他種類的蘋果;但如果是出現在一則社群貼文,或一則廣告,則適合用<article>裝起來。因為這就是所有的內容。

意義與<div>不同

<section>有網頁內容的組成結構的意義,與<div>的定位有差別。
而且<section>是所謂的section content element,會出現在網頁生成的outline之中。[10]

如果將內容包起來只是要以CSS設定樣式或執行Javascript程式等,而不是想要將其作為組成結構列於網頁的大綱中,應該要使用<div>

小結

透過這些語意化結構元素,我們可以將網頁內容劃分成不同區塊。

不過這些區塊只是劃分內容的結構,實際上網頁會呈現出什麼版面又是另一回事。還需要另外以CSS設定這些結構區塊的樣式,才能真的劃分出版面上的不同區塊。

兩者雖然都是分成區塊,意思卻不太一樣,所以不能就直接將這些元素代表的結構區塊,對應到網頁呈現出的版面區塊。

這些結構區塊,也有人用其他的名稱如區段來稱呼。不過這裡暫時還是先用廣義的區塊來描述,並以語意化結構元素來稱呼這些元素。

雖然寫這篇文章的時候一直在想怎麼描述才比較精確,但讀起來可能還是很模糊,希望大家能聽懂我在說什麼 ( ̄▽ ̄)

如果還是不懂這些元素的使用時機,可以參考html5 Doctor整理的流程圖來判斷。也許之後會介紹到~

想先了解的,可以參考Cami的文章

參考資料

[1]:MDN, <header>: The Header element
[2]:MDN, Structuring documents
[3]:MDN, <nav>: The Navigation Section element
[4]:MDN, <main>: The Main element
[5]:MDN, <aside>: The Aside element
[6]:MDN, <footer>: The Footer element
[7]:MDN, <article>: The Article Contents element
[8]: HTML Standard, Article or section?
[9]:MDN, <section>: The Generic Section element
[10]:MUKI, 淺談 section 運用以及與 outline 間的關聯


上一篇
[Day06] 幫網頁劃出界線──HTML的語意化結構元素
系列文
前端迷走中:從零開始的新手之路7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言