CSS語法與規則 — 重學CSS

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我是"},{"type":"text","marks":[{"type":"strong"}],"text":"三鑽"},{"type":"text","text":",一個在"},{"type":"text","marks":[{"type":"strong"}],"text":"《技術銀河》"},{"type":"text","text":"中等你們一起來終生漂泊學習。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"點贊是力量,關注是認可,評論是關愛!下期再見 👋"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入重學 CSS 的第一步,首先需要找到一些線索。我們在前面的課程中講學習方法的部分也講過,要想建立知識體系骨架,我們需要一個完備性更權威,更全的線索。但是 CSS 現在標準的狀態非常複雜,所以我們沒有辦法找到一份像 JavaScript 或者 HTML 中比較完備的現形標準,能把 CSS 的一切都濃縮在內。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不過這種情況也是我們平時學習知識的一種常態,知識並不是有人給我們總結好一本書,或者能有一個地方包含了所有的知識。一般來說知識都會分佈在各種不同的文檔當中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根據 Winter 老師比較喜歡學習一個線索,凡是對於編程語言,都會先從它的語法去了解它。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 CSS 也不例外,它也有自己的一套語法體系。但是 CSS 標準是分散開的,我們想找到它完整的語法非常的不容易的。所以我們這裏先從 CSS 2.1 語法標準開始。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS 2.1 語法標準"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CSS 2.1 確實是一個比較老的版本了,但是它有一個好處,在 2.1 的版本的時候建立了一個 Snapshot,也就是說沒有其他版本去替代它。所以 CSS 2.1 的 Grammar Summary 部分是當時一個比較完整的一份語法列表。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然現在我們已經大量的引入了 CSS3 了,所以這裏面會有一些語法差異和不全。但是總體來講是一個不錯的起點,讓我們可以先開始認識 CSS 的語法基礎。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏的語法是使用 “"},{"type":"text","marks":[{"type":"strong"}],"text":"產生式"},{"type":"text","text":"” 來表達的。但是這裏會有一些 CSS 中特別的表達方式和標準:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"[ ]"}]},{"type":"text","text":" —— 方括號代表組的概念"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"?"}]},{"type":"text","text":" —— 問號代表可以存在和不存在"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"|"}]},{"type":"text","text":" —— 單豎線代表 “或” 的意思"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"*"}]},{"type":"text","text":" —— 星號代表 0 個或 多個"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"CSS 總體結構"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"@charset"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"@import"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"rules —— 多個規則,這裏面的規則沒有順序要求"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + @media"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + @page"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + rule —— 這裏基本上就是我們平時寫的 CSS 樣式規則部分"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們平時寫都是在寫普通的 CSS 規則,"},{"type":"codeinline","content":[{"type":"text","text":"charset"}]},{"type":"text","text":" 我們基本都不會用,一般我們都會用 "},{"type":"codeinline","content":[{"type":"text","text":"UTF-8"}]},{"type":"text","text":"。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏講到的是 CSS 2.1 的 CSS 結構,在 CSS3 中我們有更多的 "},{"type":"codeinline","content":[{"type":"text","text":"@"}]},{"type":"text","text":" 規則 和 CSS 規則,我們首先要在 CSS3 中找到這兩塊的所有內容,然後補充道這個總體結構中,那麼我們就可以形成 CSS 的總體結構。這時候我們對 CSS 的語法認識就有完備性了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS @ 規則研究"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@charset"}]},{"type":"text","text":": https://www.w3.org/TR/css-syntax-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 CSS syntax 3 中在 CSS 2.1 中做了一個重新的定義"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是相對 CSS 2.1 基本沒有什麼變化"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@import"}]},{"type":"text","text":": https://www.w3.org/TR/css-cascade-4/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後 import 就在 css cascade 4 的規範裏面"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲 CSS 的全稱就是 Cascade Style Sheet(級聯表)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 import 屬於級聯規則之一"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@media"}]},{"type":"text","text":": https://www.w3.org/TR/css3-conditional/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Media 不是在我們的 media query 標準裏"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它在 CSS3 的 conditional 標準裏"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是在 media 的 conditional 標準中又去引用了 media query,規定了 media 後面的一部分的查詢規則"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我們常常去講 media query 是一個新特性,其實它並不是,它是類似一個預置好的函數的一個規範"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"真正把 Media 特性真正引入到 CSS3 當中,是通過 CSS3 中的 conditional 標準"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼 Conditional,就是 “有條件的”,顧名思義就是用來控制一些規則在有效條件下才會生效"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" @page"}]},{"type":"text","text":": https://www.w3.org/TR/css-page-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"page 是有一份單獨的 CSS3 標準來表述它"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"就是 css page 3 它主要是給我們需要打印的頁面所使用的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"理論上這個叫做分頁媒體,其實主要的分頁媒體就是打印機"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們的頁面是不會有分頁的"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@counter-style"}]},{"type":"text","text":": https://www.w3.org/TR/css-counter-styles-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們平時寫列表的時候會有一個 counter"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是列表最前面的那個 “小黑點” 或者是 “小數字”"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@keyframes"}]},{"type":"text","text":": https://www.w3.org/TR/css-animations-1/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"keyframes 是用於我們的動畫效果定義的"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@fontface"}]},{"type":"text","text":": https://www.w3.org/TR/css-fonts-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"fontface 就是我們使用 web font 功能時候用到的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它可以用來定義一切字體"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由此延伸出一個技巧叫 Icon font"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@supports"}]},{"type":"text","text":": https://www.w3.org/TR/css3-conditional/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個同樣是來自於 conditional 的標準"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是用來檢查某些 CSS 的功能是否存在的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"supports 是一個比較尷尬的存在,自己就是隸屬於 CSS3,所以它本身是有兼容性問題的導致沒辦法用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以現在基本上不推薦使用 support 來檢查 CSS 兼容性"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲我們檢查的那個屬性,比我們 support 這個規則兼容性要更好,所以根本檢查不了"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"估計可能 4~5年後,CSS 新出來的新特性我們再用 support 來檢查會更好一點"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@namespace"}]},{"type":"text","text":": https://www.w3.org/TR/css-namespaces-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在 HTML 裏面除了 HTML 命名空間,還引入了 SVG、MathML 等這樣的其他的命名空間的標記和標籤"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 CSS 裏面有了對應的設施,其實主要是 一個完備性的考量,並不是一個特別重要的規則"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏不是完整的列表,還有 3 個規則,因爲 它們本身狀態太年輕在討論狀態,要不就是已經沒有瀏覽器支持了,或者是已經被廢棄了。分別有 "},{"type":"codeinline","content":[{"type":"text","text":"document"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"color-profile"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"font-feature"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"然後最常用的有三種:"},{"type":"codeinline","content":[{"type":"text","text":"@media"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"@keyframes"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"@fontface"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS 規則結構"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏我們選中了 HTML 所有的 DIV 並且給予它們一個 "},{"type":"codeinline","content":[{"type":"text","text":"blue"}]},{"type":"text","text":" 的背景顏色。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"css"},"content":[{"type":"text","text":"div {\n background-color: blue;\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過以上代碼示例,我們看到一段 CSS 代碼是有分爲 "},{"type":"codeinline","content":[{"type":"text","text":"選擇器"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"聲明"}]},{"type":"text","text":" 兩部分的。在我們《實戰中理解瀏覽器原理》的文章中,我們編寫我們的 "},{"type":"codeinline","content":[{"type":"text","text":"CSS parsor"}]},{"type":"text","text":" 的時候,就是把 CSS parse 成 selector 部分和 declaration 部分。我們這裏也會按照這個方法來理解 CSS 規則。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇器 —— selector ("},{"type":"codeinline","content":[{"type":"text","text":"div"}]},{"type":"text","text":")"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"聲明 —— declaration"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Key —— 鍵 ("},{"type":"codeinline","content":[{"type":"text","text":"background-color"}]},{"type":"text","text":")"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Value —— 值 ("},{"type":"codeinline","content":[{"type":"text","text":"blue"}]},{"type":"text","text":")"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"CSS 規則標準"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Selector 選擇器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Level 3"},{"type":"text","text":" —— https://www.w3.org/TR/selectors-3/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Selectors_group —— 選擇器組:用逗號分隔"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Selector —— 選擇器:需要用 combinator (組合器) 把多個簡單選擇器拼在一起的"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Combinator —— 組合器:"},{"type":"codeinline","content":[{"type":"text","text":"+"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":">"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"~"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"空格"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Simple"},{"type":"text","marks":[{"type":"italic"}],"text":"selector"},{"type":"text","text":"sequence —— 簡單選擇器:"},{"type":"codeinline","content":[{"type":"text","text":"類型選擇器"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"*"}]},{"type":"text","text":" 一定會在最前面,然後可以是 "},{"type":"codeinline","content":[{"type":"text","text":"ID"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"class"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"attr"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"pseudo"}]},{"type":"text","text":"等選擇器"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Level 4"},{"type":"text","text":" —— https://www.w3.org/TR/selectors-4/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Level 4 和 Level 3 是非常的相似的,但是它的選擇器更復雜"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 增加了很多的僞類選擇器、“或” 和 “與” 的關係"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 而且它的 NOT 也更強大"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Level 4 的話我們看一看拓展思路就可以了,因爲從 2018年12月 開始也沒有再更新了"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 所以目測是遇到問題了,處於比較難推動的階段,所以投入使用還有很漫長的路要走"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Key"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Properties|性質"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Variables|CSS 變量—— https://www.w3.org/TR/css-variables/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 可以聲明一個雙減號開頭的變量:"},{"type":"codeinline","content":[{"type":"text","text":"--main-color: #06c"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 然後我們可以在子元素中使用這些 CSS 變量了 "},{"type":"codeinline","content":[{"type":"text","text":"color: var(--main-color)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 可以跟其他的函數進行嵌套:"},{"type":"codeinline","content":[{"type":"text","text":"--accent-background: linear-gradient(to top, var(--main-color), white);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 使用 "},{"type":"codeinline","content":[{"type":"text","text":"var()"}]},{"type":"text","text":" 函數的時候是可以給默認值的,傳入第二個參數就是默認值:"},{"type":"codeinline","content":[{"type":"text","text":"var(--main-color, black)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + CSS 變量處理可以用作 value,還可以用作 key:先聲明瞭"},{"type":"codeinline","content":[{"type":"text","text":"--side: margin-top"}]},{"type":"text","text":" 然後就可以這樣使用 "},{"type":"codeinline","content":[{"type":"text","text":"var(--side): 20px"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Value"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Level 4 —— https://www.w3.org/TR/css-values-4/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 它也是 working draft (工作草稿) 狀態,但是實現狀態非常的好"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 而且這個版本一直有保持更新,最後一次更新是 2019年1月份"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 數字類型有:"},{"type":"codeinline","content":[{"type":"text","text":"整型"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"百分比"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"浮點型"}]},{"type":"text","text":"還有"},{"type":"codeinline","content":[{"type":"text","text":"帶維度 (Dimensions)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 長度單位有:"},{"type":"codeinline","content":[{"type":"text","text":"相對單位 (em, ex, cap, ch ... )"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"視口單位 (vw, vh, vi, vb, vmin, vmax)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"絕對單位 (cm, mm, Q, in, pt, pc px)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 其他單位:"},{"type":"codeinline","content":[{"type":"text","text":"弧度單位 (deg, grad, rad, turn)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"時間單位 (s, ms)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"頻率單位 (Hz, kHz)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"分辨率單位 (dpi, dpcm, dppx)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 數據類型:"},{"type":"codeinline","content":[{"type":"text","text":"顏色 "}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"圖片 "}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"2D 位置 "}]},{"type":"text","text":" 等類型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 函數:"},{"type":"codeinline","content":[{"type":"text","text":"計算 cal()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"最小值 min()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"最大值 max()"}]},{"type":"text","text":" 、"},{"type":"codeinline","content":[{"type":"text","text":"範圍剪切 clamp()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"切換value toogle()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"屬性引用 attr()"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"使用爬蟲收集整套 CSS 標準"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過上面講到的幾個部分,我們已經瞭解了整個 CSS 的架構。但是我們發現整個的 CSS 標準是散落在幾份標準當中的,爲了我們更好的閱讀標準,我們想拿到一份比較完整的標準列表是需要我們做一些工作的。很多時候我們都是需要在零散的標準裏面,去搜集一些共性的內容。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來我們來做一個小實驗,通過類似爬蟲的方法,在 W3C 網站上抓取標準的內容。然後我們對他進行一些處理,方便我們後續的一些工作。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我們打開 W3C 的標準和草稿的列表頁:https://www.w3.org/TR/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏我們可以看到所有的 W3C 的標準和草稿,但是這裏我們只需要 CSS 部分的。如果我們檢查元素中查看,我們可以看到其實所有的數據都已經掛載在 DOM 上了,只是前端做了篩選分頁而已。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我們就可以用一段代碼,直接複製到瀏覽器的 "},{"type":"codeinline","content":[{"type":"text","text":"console"}]},{"type":"text","text":" 中運行就可以篩選出所有 CSS 相關的文章列表了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"// 獲取 CSS 相關的標準列表\nJSON.stringify(\n Array.prototype.slice\n .call(document.querySelector('#container').children)\n .filter(e => e.getAttribute('data-tag').match(/css/)) // 找到有 CSS tag 的\n .map(e => ({ name: e.children[1].innerText, url: e.children[1].children[0].href })) // 只獲取標題名字和鏈接\n);"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最終輸入的內容如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6f/6f09cb26270a1e6b317337241ac92f3c.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後我們點擊下方的 \""},{"type":"codeinline","content":[{"type":"text","text":"Copy"}]},{"type":"text","text":"\" 即可複製,把這個 JSON 內容保存在一個 JavaScript 文件裏面,並且賦予一個變量叫 "},{"type":"codeinline","content":[{"type":"text","text":"standards"}]},{"type":"text","text":"。在我們後面的爬蟲代碼中需要用到。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 這裏我們用一個簡單的方法來獲取爬取信息,就是在 W3C 原本的頁面上開啓一個 "},{"type":"codeinline","content":[{"type":"text","text":"iframe"}]},{"type":"text","text":",這樣我們就可以忽略掉跨域的問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"let standards = [...] // 這裏面的內容就是我們剛剛從 W3C 網頁中爬取到的內容\n \nlet iframe = document.createElement('iframe');\ndocument.body.innerHtml = '';\ndocument.body.appendChild(iframe);\n\nfunction happen(element, event) {\n return new Promise(function (resolve) {\n let handler = () => {\n resolve();\n element.removeEventListener(event, handler);\n };\n element.addEventListener(event, handler);\n });\n}\n\nvoid (async function () {\n for (let standard of standards) {\n iframe.src = standard.url; // 讓 Iframe 跳轉到每個 standards 中的詳情頁面\n console.log(standard.name); \n await happen(iframe, 'load'); // 等待 iframe 中的頁面打開完畢\n }\n})();"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後我們需要的信息就是屬性表格中的內容:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/df/df54bdfd5e69cdccc018c344200127a4.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我們看一下這個 table 的 HTML 代碼,我們會發現這個 table 都是有一個 class 名叫 "},{"type":"codeinline","content":[{"type":"text","text":"propdef"}]},{"type":"text","text":" 的。我們就可以用這個特性來獲取這個表格中的內容了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我們就可以在 "},{"type":"codeinline","content":[{"type":"text","text":"await happen(iframe, 'load')"}]},{"type":"text","text":",後面添加一行代碼來答應這個表格的 DOM 元素來看一下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"let iframe = document.createElement('iframe');\ndocument.body.innerHTML = '';\ndocument.body.appendChild(iframe);\n\nfunction happen(element, event) {\n return new Promise(function (resolve) {\n let handler = () => {\n resolve();\n element.removeEventListener(event, handler);\n };\n element.addEventListener(event, handler);\n });\n}\n\nvoid (async function () {\n for (let standard of standards) {\n iframe.src = standard.url;\n console.log(standard.name);\n await happen(iframe, 'load');\n console.log(iframe.contentDocument.querySelectorAll('.propdef')); // 這裏答應出表格的內容\n }\n})();"}]},{"type":"heading","attrs":{"align":null,"level":1}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d0/d06f14bbb80ef4c8388a1e33bb8cd840.gif","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章