了解HTML的歷史和基本結構
HTML是由WHATWG(Web Hypertext Application Technology Working Group)定義的標準,這是一個由開發最受歡迎的網頁瀏覽器的人組成的組織。這意味著它基本上由Google、Mozilla、Apple和Microsoft控制。
過去,W3C(World Wide Web Consortium)負責創建HTML標準的機構。
隨著W3C推向XHTML的路線不被接受,控制權非正式地從W3C轉移到了WHATWG。
如果你從未聽說過XHTML,這裡有一個簡短的故事。在2000年初,我們都相信Web的未來是XML(當真的)。所以HTML從基於SGML的作者語言轉變為XML標記語言。
這是一個很大的改變。我們必須了解並遵守更多的規則。更嚴格的規則。
最終瀏覽器供應商意識到這不是Web的正確道路,他們進行反擊,創造了現在被稱為HTML5的東西。
W3C並不真正同意放棄對HTML的控制權,多年來我們得到了2個競爭的標準,每個標準都試圖成為官方標準。最終,W3C在2019年5月28日宣布,由WHATWG發布的“真正”的HTML版本被確定為官方版本。
我提到了HTML5。讓我解釋這個小故事。我知道,到現在為止,這可能有些混亂,當涉及到很多參與者時,生活中的很多事情也是如此,這也很迷人。
我們在1993年有了HTML版本1。[這裡是原始的RFC]。
1995年出現了HTML2。
我們在1997年1月獲得了HTML3,並於1997年12月推出了HTML4。
繁忙的時代!
20多年過去了,我們經歷了所有這些XHTML的事情,最終我們現在到達了這個“東西”HTML5,這實際上不僅僅是HTML。
HTML5現在定義了一整套技術,包括HTML,並添加了許多API和標准,如WebGL、SVG等。
在這裡需要理解的關鍵是:現在沒有HTML版本這樣的東西了。它是一個活標準。就像CSS一樣,我們稱之為3,但實際上它是一組獨立開發的模塊。就像JavaScript一樣,我們每年都有一個新版本,但這不再重要,重要的是引擎實現了哪些個別特性。
是的,我們稱之為HTML5,但HTML4來自1997年。時間對於任何事情來說都很漫長,想象一下對於Web來說有多長。
這是標準“居住”的地方:[https://html.spec.whatwg.org/multipage]。
HTML基礎
HTML是我們用來結構化Web上的內容的標記語言。
HTML以不同的方式提供給瀏覽器。
它可以由根據請求或會話數據構建它的服務器端應用程序生成,例如Rails、Laravel或Django應用程序。
或者它可以由JavaScript客戶端應用程序生成HTML。
或者,在最簡單的情況下,它可以存儲在文件中,並由Web服務器提供給瀏覽器。
讓我們深入研究這種情況,儘管實際上它可能是生成HTML的最不流行方式,但仍然有必要了解基本結構。
按照慣例,HTML文件以.html
或.htm
擴展名保存。
在此文件中,我們使用標籤來組織內容。
標籤封裝內容,每個標籤為其封裝的文本賦予特殊含義。
讓我們舉幾個例子。
此HTML片段使用p
標籤創建一個段落:
<p>A paragraph of text</p>
此HTML片段使用ul
標籤創建一個項目列表,其中ul
表示無序列表,li
標籤表示列表項:
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>
當瀏覽器提供HTML頁面時,標籤將被解釋,瀏覽器根據定義元素的規則呈現這些元素的外觀。
其中一些規則是內建的,例如列表的呈現方式。或者鏈接以藍色、底線顯示。
其他一些規則是由帶有CSS的指令集定義的。
HTML不是表現性的。它不關心事物的外觀,而是關心事物的含義。
由瀏覽器決定事物的外觀,由構建頁面的人定義的指令和CSS語言來決定事物的外觀。
現在,我所做的這兩個例子是在頁面上下文之外使用的HTML片段。
HTML頁面結構
讓我們舉一個正確的HTML頁面的例子。
其中一個重要開始的地方是文檔類型聲明(也稱為doctype),這是一種告訴瀏覽器這是一個HTML頁面,以及我們使用的HTML版本的方式。
現代HTML使用以下doctype:
<!DOCTYPE html>
然後我們有html
元素,它具有開始和結束標籤:
<!DOCTYPE html>
<html>
...
</html>
所有標籤都有開始和結束標籤,除了一些不需要結束標籤的自結束標籤,因為它們不包含任何內容。
結束標籤與開始標籤相同,只是多了一個/
。
html
起始標籤在文檔開頭使用,直接放在文檔類型聲明之後。
html
結束標籤是HTML文檔中的最後一個元素。
在html
元素內部,我們有2個元素:head
和body
:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
在head
內部,我們將擁有對創建網頁至關重要的標籤,例如標題、元數據和內部或外部CSS和JavaScript。主要是一些不直接顯示在頁面上,只幫助瀏覽器(或像Google搜索機器人這樣的機器人)正確顯示頁面的東西。
在body
內部,我們將擁有頁面的內容,也就是可見的內容。
標籤與元素
我提到了標籤和元素。有什麼區別?
元素具有開始標籤和結束標籤。
在這種情況下,我們使用p
開始和結束標籤創建一個p
元素。
<p>A paragraph of text</p>
因此,元素構成了整個封裝:
- 開始標籤
- 文本內容(可能還有其他元素)
- 結束標籤
如果元素沒有結束標籤,則只使用開始標籤寫,並且不包含任何文本內容。
也就是說,在書中我可能使用標籤或元素一詞來表示相同的含義,除非我明確提到開始標籤或結束標籤。
屬性
元素的開始標籤可以有我們可以附加的特殊信息片段,稱為屬性。
屬性具有key="value"
的語法:
<p class="a-class">A paragraph of text</p>
我們可以有多個屬性:
<p class="a-class" id="an-id">A paragraph of text</p>
有些屬性是布爾屬性,意思是你只需要鍵:
<script defer src="file.js"></script>
class
和id
屬性是你將遇到的最常用的兩個屬性。
它們具有特殊含義,在CSS和JavaScript中都很有用。
它們之間的區別在於id
在網頁上下文中是唯一的,不能重復。
而class
可以在多個元素上多次出現。
此外,id
只是一個值。class
可以包含由空格分隔的多個值:
<p class="a-class another-class">A paragraph of text</p>
使用破折號-
在類值中分隔單詞是常見的,但這只是一個慣例。
這些只是你可以有的多個可能屬性。有些屬性只用於一個標籤。它們非常專業化。
其他屬性可以以更一般的方式使用。你剛剛看到了id
和class
,但我們還有其他一些屬性,如style
,它可以用於在元素中插入行內CSS規則。
大小寫不敏感
HTML大小寫不敏感。標籤可以大寫或小寫。在早期,大寫是正常的。今天小寫是正常的。這是一個慣例。
通常寫成這樣:
<p>A paragraph of text</p>
而不是這樣:
<P>A paragraph of text</P>
空格
非常重要。在HTML中,即使在一行中添加多個空格,它也會被瀏覽器的CSS引擎折疊。
例如,此段落的呈現效果
<p>A paragraph of text</p>
與此段落的呈現效果相同:
<p> A paragraph of text</p>
以及這程式碼的呈現效果:
<p>A paragraph
of
text </p>
使用CSS的
white-space
CSS屬性可以更改事物的行為。關於CSS如何處理空格的更多信息,可以在CSS規範中找到更多信息。
我建議使用可以使事物在視覺上更有組織和易讀的語法,但您可以使用任何喜歡的語法。
我通常更喜歡
<p>A paragraph of text</p>
或
<p>
A paragraph of text
</p>
嵌套標籤應該縮進2個或4個字符,具體取決於您的首選:
<body>
<p>
A paragraph of text
</p>
<ul>
<li>A list item</li>
</ul>
</body>
注意:這意味著如果您想添加額外的空格,它可能會使您非常生氣。我建議在需要時使用CSS來添加更多空間。
注意:在特殊情況下,您可以使用
HTML實體(一個首字母縮寫,表示不斷行空格)-後面將談到更多HTML實體。我認為不應濫用這一點。在視覺呈現方面,始終優先考慮使用CSS。
文檔標題
head
標籤包含了定義文檔屬性的特殊標籤。
它始終在body
標籤之前的head
標籤之後編寫:
<!DOCTYPE html>
<html>
<head>
...
</head>
...
</html>
我們不在此標籤上使用屬性。我們不在其中編寫內容。
它只是其他標籤的容器。 在其中,根據需要,我們可以擁有各種標籤:
title
script
noscript
link
style
base
meta
title
標籤
title
標籤決定頁面標題。標題顯示在瀏覽器中,特別重要的是它是搜索引擎優化的關鍵因素之一。
script
標籤
此標籤用於將JavaScript添加到頁面中。
可以使用開始標籤、JavaScript代碼和結束標籤內聯包含它:
<script>
..一些JavaScript
</script>
或者可以使用src
屬性加載外部JavaScript文件:
<script src="file.js"></script>
關於此標籤,有一些重要的事情需要知道。
有時僅將此標籤用於頁面底部。為什麼?出於性能原因。
默認情況下,加載脚本會阻塞頁面的渲染,直到脚本被解析和加載為止。
這樣做,脚本在頁面解析和加載完成後才加載和執行,為用戶提供更好的體驗,而不是將其保留在head`標籤中。
我認為這現在是一種不良做法。讓script
存在於head
標籤中。
在現代JavaScript中,我們有一種更有效率的替代方案,而不是將腳本保留在頁面底部——即defer
屬性:
<script defer src="file.js"></script>
這就是觸發頁面加載速度更快、JavaScript加載速度更快的更快捷方案。
注意:
async
屬性類似,但在我看來比defer
更差。在https://flaviocopes.com/javascript-async-defer/頁面中詳細介紹了為什麼。
noscript
標籤
此標籤用於檢測瀏覽器中禁用腳本的情況。
根據放置在文檔頭部還是文檔正文中,使用方式略有不同。
我們現在談談文檔頭部的情況。首先介紹此用法。
在這種情況下,noscript
標籤只能包含其他標籤:
link
標籤style
標籤meta
元素
以更改由頁面提供的資源或在禁用腳本時的meta
信息。
在此示例中,我將具有no-script-alert
類的元素設置為在禁用腳本時顯示,因為它的默認為display:none
:
<!DOCTYPE html>
<html>
<head>
...
<noscript>
<style>
.no-script-alert {
display: block;
}
</style>
</noscript>
...
</head>
...
</html>
link
標籤
link
標籤用於設定文檔與其他資源之間的關係。
它主要用於連接外部CSS文件進行加載。
此元素沒有結束標籤。
使用方法:
<!DOCTYPE html>
<html>
<head>
...
<link href="file.css" rel="stylesheet">
...
</head>
...
</html>
media
屬性允許根據設備能力加載不同的樣式表:
<link href="file.css" media="screen" rel="stylesheet">
<link href="print.css" media="print" rel="stylesheet">
我們可以連接到不同於樣式表的其他資源。
例如,我們可以使用以下方式關聯一個RSS源:
<link rel="alternate" type="application/rss+xml" href="/index.xml">
我們可以使用以下方式關聯一個favicon:
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
此標籤也曾經用於多頁內容,使用rel="prev"
和rel="next"
指示先前和下一頁。主要是為了讓Google使用。2019年,Google宣布不再使用這個標籤,因為它可以在不使用該標籤的情況下找到正確的頁面結構。
style
標籤
此標籤可用於將樣式添加到文檔中,而不是加載外部樣式表。
使用方法:
<style>
.some-css {}
</style>
與link
標籤一樣,您可以使用media
屬性僅在指定的媒體上使用該CSS:
<style media="print">
.some-css {}
</style>
您還可以將此標籤添加到文檔正文中。說起來,非常有趣的一點是scoped
屬性,以僅將該CSS分配給當前文檔子樹。換句話說,避免將CSS泄露到父元素之外。
base
標籤
此標籤用於為頁面中的所有相對URL設置基本URL。
<!DOCTYPE html>
<html>
<head>
...
<base href="https://flaviocopes.com/">
...
</head>
...
</html>
meta
標籤
元標籤執行多種任務,它們非常重要。
特別是對於搜索引擎優化。
meta
元素只有起始標籤。
最基本的一個是description
元標籤:
<meta name="description" content="A nice page">
如果Google發現它更好地描述了頁面,它可能會將其用於生成搜索引擎結果頁面中的頁面描述(不要問我如何這樣做)。
charset
元標籤用於設置頁面的字符編碼。在大多數情況下,使用utf-8
:
<meta charset="utf-8">
robots
元標籤指示搜索引擎機器人是否索引頁面:
<meta name="robots" content="noindex">
或者他們是否應該跟隨鏈接:
<meta name="robots" content="nofollow">
您可以組合它們:
<meta name="robots" content="noindex, nofollow">
默認行為是index, follow
。
您可以使用其他屬性,包括nosnippet
,noarchive
,noimageindex
等等。
您也可以告訴Google而不是定位於所有搜索引擎:
<meta name="googlebot" content="noindex, nofollow">
其他搜索引擎可能也有自己的元標籤。
在談到搜索引擎時,我們可以告訴Google禁用某些功能。這將禁止搜索引擎結果中的翻譯功能:
<meta name="google" content="notranslate">
viewport
元標籤用於告訴瀏覽器根據設備寬度設置頁面寬度。
<meta name="viewport" content="width=device-width, initial-scale=1">
另一個相當流行的元標籤是http-equiv="refresh"
。此行告訴瀏覽器等待3秒,然後重定向到另一個頁面:
<meta http-equiv="refresh" content="3;url=http://flaviocopes.com/another-page">
將0替換為3將盡快重定向。
這不是一個完整的參考,還有其他不常用的meta標籤。
在介紹完文檔標題後,我們可以開始深入研究文檔主體。
文檔主體
在關閉head標籤之後,在HTML文檔中我們只能有一個內容:body元素。
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
就像head
和html
標籤一樣,在一個頁面中只能有一個body
標籤。
在body
標籤內部,我們擁有定義頁面內容的所有標籤。
從技術上講,起始和結束標籤是可選的。但是我認為將其添加是一種良好的實踐。僅出於清晰度。
在接下來的章節中,我們將定義您可以在頁面主體中使用的各種標籤。
但是,在此之前,我們必須介紹塊元素和內聯元素之間的區別。
塊元素vs內聯元素
視覺元素,即頁面主體中定義的元素,通常可以分為兩類:
- 塊元素(
p
,div
,標題元素,列表和列表項,…) - 內聯元素(
a
,span
,img
,…)
有什麼區別?
塊元素在頁面中定位時,不允許其他元素位於其旁邊。左邊或右邊。
內聯元素相反,可以位於其他內聯元素旁邊。
區別還在於通過CSS我們可以編輯的可視屬性。我們可以為塊元素更改寬度/高度,邊距,內邊距和邊框。對於內聯元素,我們不能這樣做。
請注意,使用CSS,我們可以更改每個元素的默認值,將
p
標籤設置為內聯元素,例如,或將span
設置為塊元素。
另一個區別是內聯元素可以包含在塊元素中。相反的情況不成立。
某些塊元素可以包含其他塊元素,但這取決於情況。例如,p
標籤不允許該選項。