這個章節我們將探討HTML最基本的部分。首先 ,我們會解釋元素(elements)、屬性(attributes)以及其他你可能聽過的重要名詞,然後講解該如何使用它們。 我們也會告訴你該如何建構HTML元素、建構典型的HTML頁面以及解釋其他重要基礎的語言特色。在這個學習的過程中,我們會提供一些HTML範例來增加樂趣!
Prerequisites: | Basic computer literacy, basic software installed, and basic knowledge of working with files. |
---|---|
Objective: | To gain basic familiarity with the HTML language, and get some practice writing a few HTML elements. |
什麼是HTML?
HTML (Hypertext Markup Language) 並不是一種程式語言,而是一種用來告訴瀏覽網頁的人該如何組織該網頁的標記式語言(markup language),它可以依照網頁開發者的意願變得困難或簡單。HTML包含一系列的元素( elements )讓你圍住、包裹或標記不同部分的內容,使得它們得以呈現出不同的風格樣式。被標籤(tags)包住的內容會變成超連結,或者斜體字,以及諸如此類的功能。舉例來說,請看下列內容:
My cat is very grumpy
如果我們想要讓這行字獨立出來,不讓它跟其他東西排在一起,我們可以用段落標籤( paragraph tag <p>
)讓它自成段落:
<p>My cat is very grumpy</p>
注意:
在HTML中元素是不區分大小寫的。
例如 : <title>
這個元素可以被撰寫成<title>
, <TITLE>
, <Title>
, <TiTlE>
,之類的
,都可以正常運作。
但請培養良好的習慣,所有的元素請用小寫,
為了保持一致性跟可讀性還有其他可能的原因。
分析HTML元素
讓我們更深入的探索段落中的元素:
元素中主要的內容有:
- 起始標籤(opening tag):
起始標籤包含了這個元素的名字(在這裡是 p),夾在 <、> (angle brackets) 中間。
它標示出這個元素開始的地方—例如上面例子中表示這個段落的開始。 - 結束標籤(closing tag):
結束標籤和起始標籤長得差不多,
不過在名字前面多了一條斜線 (forward slash) 。
結束標籤表示這個元素結束的地方—例如上面例子中表示這個段落的結束。
初學者常常會忘記加上結束標籤,因而導致奇怪的結果。 - 內容(content): 這個元素的內容。上面例子中就是一段字。
- 元素(element): 以上三者加起來就是元素。
不要光是看: 創造你的第一個HTML元素
編輯下面輸入區域中的文字,嘗試用 <em>
和 </em>
標籤包裹住文字(把 <em>
放在文字前面來起始元素,把 </em>
放在後面來結束元素) ,這會使得文字變成斜體字。你可以在下面的輸出區域看到更新後的變化。
如果你不小心打錯了,你可以用"Reset"鍵重置。如果你卡關了,請點擊"Show solution"鍵來偷看答案。
Playable code
<h2>Live output</h2> <div class="output" style="min-height: 50px;"> </div> <h2>Editable code</h2> <p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> <textarea id="code" class="playable-code" style="min-height: 100px;width: 95%"> This is my text. </textarea> <div class="controls"> <input id="reset" type="button" value="Reset" /> <input id="solution" type="button" value="Show solution" /> </div>
html { font-family: 'Open Sans Light',Helvetica,Arial,sans-serif; } h2 { font-size: 16px; } .a11y-label { margin: 0; text-align: right; font-size: 0.7rem; width: 98%; } body { margin: 10px; background: #f5f9fa; }
var textarea = document.getElementById('code'); var reset = document.getElementById('reset'); var solution = document.getElementById('solution'); var output = document.querySelector('.output'); var code = textarea.value; var userEntry = textarea.value; function updateCode() { output.innerHTML = textarea.value; } reset.addEventListener('click', function() { textarea.value = code; userEntry = textarea.value; solutionEntry = htmlSolution; solution.value = 'Show solution'; updateCode(); }); solution.addEventListener('click', function() { if(solution.value === 'Show solution') { textarea.value = solutionEntry; solution.value = 'Hide solution'; } else { textarea.value = userEntry; solution.value = 'Show solution'; } updateCode(); }); var htmlSolution = '<em>This is my text.</em>'; var solutionEntry = htmlSolution; textarea.addEventListener('input', updateCode); window.addEventListener('load', updateCode); // stop tab key tabbing out of textarea and // make it write a tab at the caret position instead textarea.onkeydown = function(e){ if (e.keyCode === 9) { e.preventDefault(); insertAtCaret('\t'); } if (e.keyCode === 27) { textarea.blur(); } }; function insertAtCaret(text) { var scrollPos = textarea.scrollTop; var caretPos = textarea.selectionStart; var front = (textarea.value).substring(0, caretPos); var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); textarea.value = front + text + back; caretPos = caretPos + text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } // Update the saved userCode every time the user updates the text area code textarea.onkeyup = function(){ // We only want to save the state when the user code is being shown, // not the solution, so that solution is not saved over the user code if(solution.value === 'Show solution') { userEntry = textarea.value; } else { solutionEntry = textarea.value; } updateCode(); };
巢狀元素(Nesting elements)
你可以把元素放進另一個元素裡面 — 我們叫它巢狀.
假如你想要強調我的貓咪 very 兇 ,
我們可以把 "very" 這個字包在 <strong>
元素裡面 ,
它可以標註我想要強調的字:
<p>My cat is <strong>very</strong> grumpy.</p>
但是你要確定你的元素巢狀得當 :
在上述範例中我們先用了 p
元素 , 然後才用 strong
元素 ,
所以我們必須先關 strong
元素 , 然後再關 p
.
下面這是錯誤示範:
<p>My cat is <strong>very grumpy.</p></strong>
這些元素必須正確地開啟與關閉,所以它們在元素內部或者外部都要是相當明確的。如果它們像上面的範例這樣相互重疊,你的網頁瀏覽器將會盡力猜出你試著在說什麼,而你將很有可能得到一個不如預期的結果。所以,別這樣做!!
區塊級元素 vs. 內聯元素(Block versus inline elements)
在HTML中有兩個你應該要知道的、重要的元素類別—塊元素(block-level elements)以及內聯元素(inline elements)。
- 區塊級元素來自於它們是一個頁面中一個個可見的區塊。任何經過區塊元素的內容,不論從前面或者後面經過,都會出現在新的一行。在頁面中,區塊級元素更加傾向於結構化元素(structural elements),舉例來說,比如圖片、清單、導航選單(navigation menus)、置底(footers)等等。一個區塊級元素不應該被放在內聯元素的巢狀結構中,但區塊級元素有可能被放在同為區塊級元素的巢狀結構當中。
- 內聯元素指的是放在區塊級元素中的那些元素,而且這些元素只被一小部分的文件內容圍繞而非一整段而且群聚的內容。一個內聯元素不會在文件中產生新的一行,內聯元素只會普通的出現在一段文字中,舉例來說比如
<a>
element (hyperlink) 或者斜體,比如說<em>
或<strong>
.
以下是一個例子:
<em>first</em><em>second</em><em>third</em> <p>fourth</p><p>fifth</p><p>sixth</p>
<em>
是一個內聯元素,所以你可以看到下面的例子中,前三個元素互相緊鄰在同一行,兩兩中間並無任何空白。而 <p>
是一個塊元素,所以每個元素都自成一行,並且上下都有一些空間。(這些空間是由於瀏覽器套用預設的CSS styling到這些段落上的緣故).
Note: HTML5 redefined the element categories in HTML5: see Element content categories. While these definitions are more accurate and less ambiguous than the ones that went before, they are a lot more complicated to understand than "block" and "inline", so we will stick with these throughout this topic.
Note: You can find useful reference pages that include lists of block and inline elements — see Block-level elements and Inline elements.
空元素(Empty elements)
不是所有元素都是起始標籤、內容、結束標籤的格式。有些元素只有一個標籤,這些標籤通常用來在文件中插入/嵌入物件。例如 <img>
元素是用來嵌入圖片檔。
<img src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png">
上面的原始碼會導致下面的結果:
Note: 空元素有時也被稱作 void elements。
屬性(Attributes)
你也可以在元素中加入屬性,像是:
屬性攜帶著額外的資訊關於那些你不想要顯示實際內容的元素。在這個例子裏面 class
屬性允許你給予元素一個辨識名稱而可以在之後被用於指定這個元素的風格訊息(style information)以及其他的東西。
一個屬性應該要有:
- 一個空白在屬性跟元素名稱之間 (或者在屬性跟前一個屬性之間,如果這個元素已經有一個或者很多個屬性的話)
- 屬性名稱以及一個等號在屬性名稱的後面
- 一個屬性值以及開啟和關閉的引號包著它
主動學習: 在元素中加入屬性
我們再舉另外一個元素的例子 <a>
,a代表anchor(錨),而這個元素則是會讓被它包裹住的內容變成超連結。它可以和很多種屬性搭配,以下舉出幾種:
href
: 這個屬性用來設定你想要的超連結網址,當連結被點擊時,瀏覽器會導向的網站。例如: ,href="https://www.mozilla.org/"
.title
:title
屬性用來附加有關連結的其他資訊,像是連結到的網站名稱。例如:title="The Mozilla homepage"
。當游標移動到連結上時,就會以提示的方式顯示。target
:target
屬性用來規定要在哪裡打開網頁。例如:target="_blank"
會開啟新分頁。如果你想要在目前的分頁開啟網站,只要忽略這個屬性即可。
編輯下面輸入區的文字使它變成一個連結連到你最喜歡的網站。首先,加入<a>
元素。再來,加入 href
屬性以及 title
屬性。最後,指定 target
屬性將這個連結在新的分頁中開啟。你能在底下的輸出區域裡面即時的看到你的改動產生的變化。你應該能看到一個連結,當你滑過時連結顯示 title
屬性的內容,並且當你按下時導向到 href
元素中的網址。切記,你需要一個"空白"夾在元素名字以及各個屬性中間。
如果你不小心打錯了,你可以用"Reset"鍵重置。如果你卡關了,請點擊"Show solution"鍵來偷看答案。
Playable code2
<h2>Input</h2> <textarea id="code" class="input"><p>A link to my favourite website.</p></textarea> <h2>Output</h2> <div class="output"></div> <div class="controls"> <input id="reset" type="button" value="Reset" /> <input id="solution" type="button" value="Show solution" /> </div>
body { font-family: 'Open Sans Light',Helvetica,Arial,sans-serif; } .input, .output { width: 90%; height: 2em; padding: 10px; border: 1px solid #0095dd; } button { padding: 10px 10px 10px 0; }
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");
function drawOutput() {
output.innerHTML = textarea.value;
}
reset.addEventListener("click", function() {
textarea.value = code;
drawOutput();
});
solution.addEventListener("click", function() {
textarea.value = '<p>A link to my <a href="https://www.mozilla.org/
" title="The Mozilla homepage" target="_blank">favourite website</a>.</p>';
drawOutput();
});
textarea.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
布林屬性(Boolean attributes)
你有時會看到一些沒有值的屬性,這完全是被允許的。它們叫做布林屬性,他們只能附帶一個值,而這個值一般來說會和屬性類別一樣。以 disabled
屬性來說,你可以把它指派為input元素的屬性,使得輸入文字的框框變得不能輸入文字。
<input type="text" disabled="disabled">
你可以把它寫得更簡短(下面的例子中,我們也寫出了沒有disabled屬性的input元素供你參考,讓你更了解兩者的差別):
<input type="text" disabled> <input type="text">
結果 :
忘記加屬性值的引號
當你看遍全世界的網頁,你會發現各種千奇百怪的標記方式(markup style),包括沒加引號的屬性值。這在某些情況是被允許的,但在其他情況下則會使屬性結果不如預期。用我們前面的例子來說,我們先只用 href
屬性,如下:
<a href=https://www.mozilla.org/
>favourite website</a>
此時並沒有影響,但是,當我們加上 title
屬性時,就會造成錯誤的結果:
<a href=https://www.mozilla.org/
title=The Mozilla homepage>favourite website</a>
此時瀏覽器會誤解你的標記,認為 title
屬性其實是三個屬性,一個含有"The"的title屬性,以及兩個布林屬性 Mozilla
和 homepage
。這絕對不是你想要的結果,而且會導致錯誤或沒有預期到的動作。你可以看看下面的示範,把你的游標移到連結上,看看會出現什麼提示!
我們建議不管怎樣都要加屬性引號,避免這些錯誤,同時增加原始碼的可讀性。
要用單引號還是雙引號? (Single or double quotes?)
在這個章節中,你會發現所有的屬性都是使用雙引號,而你可能會發現其他人的HTML中使用的是單引號。這純粹是個人風格,你可以依照你個人的喜好去使用它們。下面兩行的意思是相同的:
<a href="http://www.example.com">A link to my example.</a> <a href='http://www.example.com'>A link to my example.</a>
但是,你應該確認你沒有混用它們。下面這行則會造成錯誤!
<a href="http://www.example.com'>A link to my example.</a>
如果你在你的HTML中使用其中一種引號,你就可以包裹另外一種引號:
<a href="http://www.example.com" title="Isn't this fun?">A link to my example.</a>
不過,如果你想要包裹相同種類的引號,請參考此連結: use HTML entities。
解析HTML文檔
以上包含了HTML個別元素的基礎知識,但若單獨使用這些元素,並不能發揮它們最大的效用。現在就讓我們來看看這些個別的元素如何與整個HTML結合吧!
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My test page</title> </head> <body> <p>This is my page</p> </body> </html>
我們有:
<!DOCTYPE html>
: 文件類型(doctype)。 在漫漫時間中,當HTML還年輕的時候(約莫1991左右),文件類型表示它連結到一系列的規範中,遵守這些規範才會被當作是好的HTML,比如自動化錯誤檢查以及其他有用的東西。它們習慣使某些東西看起來像這樣:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
然而,現在已經沒有人真正在乎它們了,而它們也確實只是個歷史產物,將它們包含在原始碼中,確保所有事情都正常執行。<!DOCTYPE html>
是字數最少的有效doctype。而你也只需要知道這些就夠了。<html></html>
:<html>
元素包裹住頁面的所有內容,有時也被稱作根元素(root element)。<head></head>
:<head>
元素放的是你想涵括的重要資訊,但不會顯示於網頁瀏覽者眼前的。例如,顯示於搜尋結果的關鍵字、頁面說明、CSS等等。你會在這個系列的下個章節中學到更多有關這部分的知識。<meta charset="utf-8">
: 這個元素指定了你的文件使用utf-8這種字元編碼, 建議大家都要使用這個元素,它會幫助你免去許多文字無法正確呈現的煩惱。<title></title>
:<title>
元素是用來設定網頁名稱的,它會顯示在分頁標籤上,當你將該網頁加入書籤或加入最愛時,則是用來形容這個網站。<body></body>
:<body>
元素含括了所有你想要給網頁瀏覽者看到的內容,不管是文字、圖片、遊戲、可以播放的音樂或其他物件。
主動學習: 在HTML文檔中加入一些特徵
如果你想試試看在你的電腦上寫一些HTML,你可以:
- 複製上面的HTML範例。
- 開啟一個新的text檔案(文字文件)。
- 將剛複製的HTML範例貼到新開的text檔案裡。
- 將檔案存為
index.html
。
Note: 你也可以在這找到基本的HTML範本: MDN Learning Area Github repo.
接著你就可以用網頁瀏覽器將你的檔案打開,看看這些原始碼會顯示什麼樣的結果,然後編輯原始碼並重新整理瀏覽器,看看會變成怎樣。 目前的原始碼會顯示:
在這個練習中,你可以在自己的電腦中編輯程式碼,像上面寫的一樣,或者你可以在底下的範例視窗中進行編輯(可編輯的範例視窗顯示
<body>
元素的內容,在這個範例中) 我們希望你依照以下的步驟逐步前行:
- 在最開始的標籤
<body>
元素之前,加入這個文件的主要的標題。這應該被一個<h1>
開始標籤以及一個</h1>
結束標籤包著。 - 編輯段落的內容,這些內容包含一些文字,它跟那些你有興趣的事物相關
- 讓其中重要的部分以粗體顯示讓它們更加顯眼,你可以用一個
<strong>
開始標籤以及一個</strong>
結束標籤包著它們來達成這件事情。 - 加入一個連結到你的文章段落中,像前面所講過的那樣。
- 在這文字段落的下面,加入一個圖片到你的文件裡面,像這篇文章前面所說的那樣。如果你可以連結不同的圖片(不論是在你的電腦中或者在網頁的其他地方),你可以得到額外的加分!!
如果你不小心打錯了,你可以用"Reset"鍵重置。如果你卡關了,請點擊"Show solution"鍵來偷看答案。
Playable code3
<h2>Input</h2> <textarea id="code" class="input"> <p>This is my page</p></textarea> <h2>Output</h2> <div class="output"></div> <div class="controls"> <input id="reset" type="button" value="Reset" /> <input id="solution" type="button" value="Show solution" /> </div>
body { font-family: 'Open Sans Light',Helvetica,Arial,sans-serif; } .input, .output { width: 90%; height: 10em; padding: 10px; border: 1px solid #0095dd; } img { max-width: 100%; } .output { overflow: auto; } button { padding: 10px 10px 10px 0; }
var textarea = document.getElementById("code"); var reset = document.getElementById("reset"); var code = textarea.value; var output = document.querySelector(".output"); var solution = document.getElementById("solution"); function drawOutput() { output.innerHTML = textarea.value; } reset.addEventListener("click", function() { textarea.value = code; drawOutput(); }); solution.addEventListener("click", function() { textarea.value = '<p>I really enjoy <strong>playing the drums</strong>. One of my favourite drummers is Neal Peart, who\ plays in the band <a href="https://en.wikipedia.org/wiki/Rush_%28band%29" title="Rush Wikipedia article">Rush</a>.\ My favourite Rush album is currently <a href="http://www.deezer.com/album/942295">Moving Pictures</a>.</p>\ <img src="http://www.cygnus-x1.net/links/rush/images/albums/sectors/sector2-movingpictures-cover-s.jpg">'; drawOutput(); }); textarea.addEventListener("input", drawOutput); window.addEventListener("load", drawOutput);
HTML中的空格(Whitespace)
在上面的範例中,你可能會發現原始碼中有許多空格,其實這完全不必要,下面兩段原始碼會有相同的結果:
<p>Dogs are silly.</p> <p>Dogs are silly.</p>
不管你用多少空格 ,包括空白鍵、換行,HTML的語法分析器都只會留下一個空格。所以說,何必用這麼多空格呢? 其實是為了增加可讀性,適當的排版會使得你的原始碼更容易被理解,千萬不要把你的原始碼擠成一團,讓它們變得雜亂無章。在我們的HTML中,我們將每個巢狀的元素都用兩個空格的方式縮排。原始碼的排版可依照個人喜好使用,例如要用多少空格,但你應該要慎選排版方式。
實體引用(Entity references): 引用HTML中的特殊字元
在HTML中, <
、 >
、 "
、 '
和 &
是特殊字元,它們是HTML語法的一部份。該如何引用這些特殊字元呢? 假如你真的很想要用 &
(ampersand)或小於符號 <
(less than sign),而你不想要它們被瀏覽器當成原始碼的時候該怎麼辦呢?
這時候我們就需要用到字元引用(character references),他們是特別的原始碼,用來表示字元,並且專門在這些情況下使用。每個字元引用都是以&(ampersand)開頭,並以分號 ; (semi-colon)做結尾。
字元 | 相應的字元引用 |
---|---|
< | < |
> | > |
" | " |
' | ' |
& | & |
在下面的範例中,你可以看到兩段敘述網頁技術的段落:
<p>In HTML, you define a paragraph using the <p> element.</p> <p>In HTML, you define a paragraph using the <p> element.</p>
看到下面的輸出結果,你會發現第一個段落是錯誤的,因為瀏覽器認為第二個 <p>
是要開啟新段落。而第二個段落看起來不錯,因為我們將小於及大於符號(angle brackets)換成了字元引用。
Note: 你可以在維基百科中找到完整的HTML字元實體引用對照表: List of XML and HTML character entity references。
HTML 註解
在HTML中,就像大部分的程式語言,提供了一種方式讓我們可以在原始碼中加入註解,註解是會被瀏覽器忽略,並且不會被使用者看到的,目的是要讓你在原始碼中加入註解以說明你的原始碼是如何運作的、各個部分原始碼的作用等等。當你已經六個月沒有編輯某個網頁程式碼,而你完全想不起來你做了什麼的時候,或是當你把你的原始碼交給別人修改時,註解將會是你的好朋友!
試著將你HTML檔案中的一部份內容變成註解,你需要將內容包裹在特殊的符號 <!--
和 -->
之中,例如:
<p>I'm not inside a comment</p> <!-- <p>I am!</p> -->
如你所見,在下方的範例中,第一個段落出現在輸出結果中,但第二個段落並沒有出現。
總結
恭喜你看完了這個章節,我們你能享受這個學習基礎HTML的旅程! 目前,你應該已經了解HTML長什麼樣子、它最基本的運作方式,並且能夠寫出一些元素和屬性。基礎HTML大致上就到這裡結束,在單元接下來的章節中,我們將會更深入探討本章節學到的內容以及介紹一些HTML的其他特色。千萬別轉台!
Note: 目前,在你要開始學更多有關HTML的知識時,你可能也想要探索基礎 CSS(Cascading Style Sheets)。CSS是一種用來為你的網頁增添花樣的語言,例如改變字型、顏色,或改變頁面的布局。你很快就會發現,同時使用HTML和CSS會帶來很棒的效果。