元素查詢,以及今天如何使用它們
已發表: 2022-03-10想一想一個物理結構。 如果你正在用薄弱的材料建造一座大型建築,則需要大量外部支撐來將其固定在一起,並且必須過度建造以保持堅固。 當您使用 HTML、CSS 和 JavaScript 構建網站時,這種外部支持可能看起來像框架、插件、預處理器、轉譯器、編輯工具、包管理器和構建過程。
我沒有在堆棧頂部添加另一個插件,而是想知道是否可以通過擴展其中一種核心語言 CSS來加強構建網站的材料,開發更好、更強大的網站,而這些網站需要更少的外部支持和工具建造。
元素查詢的當前狀態
使用諸如 CSS 預處理器之類的工具,我們以簡寫形式編寫 CSS,以便稍後擴展為完整形式(在瀏覽器中查看之前)。 插件能夠在頁面上與它們影響的元素一起操作,但要應用樣式,它們要么將 CSS 樣式直接寫入 HTML,要么切換應用不同 CSS 規則的類名。 在這兩種情況下,我們都需要在頁面實際加載之前編寫或生成我們需要的 CSS。
問題
這種方法的問題在於,即使是最好的插件也經常需要在您使用的每個佈局中進行自定義和配置。 此外,當 JavaScript 為您編寫樣式時,在重構或重用代碼時,很難將基於插件的邏輯和 CSS 樣式保持在一起。
預處理器的另一個問題是,一旦 CSS 擴展為完整形式,任何以簡寫形式編寫的錯誤都會迅速膨脹成更大的混亂。 使用插件時,我們會添加許多潛在的故障點。 我們可能會使用多個插件來完成一些不同的事情,如果 CSS 更強大一點,這些事情可能都是不必要的。 這給開發人員維護、瀏覽器渲染和用戶下載帶來了額外的負擔。
Web 開發的未來有希望嗎?
2013 年,Tyson Matanich 寫了一篇題為“Media Queries Are Not the Answer: Element Query Polyfill”的文章,向廣大受眾介紹了元素查詢的概念。 它引發了關於如何構建插件和 polyfill 以繞過 CSS 缺點的討論。
從那時起,在我們等待 CSS 功能發展的同時,已經發布了許多插件,允許開發人員以幾種不同的方式使用元素查詢。
什麼是元素查詢?
元素查詢類似於媒體查詢,只是它們的規則適用於實際元素的屬性,而不是瀏覽器視口的屬性。
EQCSS 是如何產生的
2013 年末,我發現自己正在開發一個 Ruby on Rails Web 應用程序的前端。 該應用程序需要向用戶顯示詳細信息,其目標是構建一個響應式界面,該界面在手機、平板電腦和桌面瀏覽器上表現同樣出色。 這帶來了一些挑戰,其中之一是要顯示的大部分重要內容最好顯示在表格中——是的,實際的table
元素(顯示金融交易、體育記錄等)。
我使用媒體查詢創建了響應式樣式,這些查詢為不同大小的瀏覽器正確顯示了table
元素。 但是,一旦其中一個響應式表格顯示在包含側邊欄的模板中,突然間我所有的響應式斷點都變成了響應式斷點。 他們根本沒有考慮到 200 像素寬的側邊欄,導致內容重疊並出現損壞。
另一個障礙:用戶名的長度從 3 到 20 個字符不等,我發現自己希望能夠根據每個用戶名包含的字符數自動調整每個用戶名的字體大小。 我需要將每個用戶名放在側邊欄中,要選擇一個小到足以容納 20 個字符的用戶名但又大到足以讓查看者看到 3 個字符的用戶名的字體大小是很棘手的。
為了解決這些問題,我經常發現自己複製了整個媒體查詢,複製了我的代碼庫的大部分,僅僅是因為我需要一種更智能的方法來在每個佈局中應用響應式樣式。 我依賴 JavaScript 作為另一種臨時解決方案,編寫了許多幾乎相同的函數來監視頁面並在 CSS 無法到達的地方應用樣式。 過了一段時間,所有這些重複代碼所增加的負擔開始拖累代碼庫,使更改變得困難。
我知道必須有更好的解決方案,過了一會兒我開始思考:我不需要媒體查詢——我需要的是元素查詢!
研究與開發
到 2014 年,我開始嘗試不同的方式來告知 CSS 元素出現在頁面上的屬性,以便我可以應用更好的樣式。 我希望找到一種方法,可以讓我編寫將 CSS 的美感與 JavaScript 的強大功能相結合的樣式。
我放棄的一些廢棄方法包括向 HTML 標記添加屬性以添加響應式支持,並嘗試找到將整個 CSS 代碼塊嵌入基於 JavaScript 的if
語句的方法,以產生某種從 JavaScript 拼湊在一起的科學怪人怪物和 CSS。
但是,我所有失敗的方法並沒有讓事情變得更容易,而是有一個共同點:它們增加了更多的工作! 我知道正確的解決方案會簡化並減少需要完成的工作,所以我一直在尋找。 通過這些實驗,我最終對元素查詢正常工作所需的語法類型有了一個改進的想法。
如前所述,對於由 HTML、CSS 和 JavaScript 構建的網站,外部支持以框架、插件、預處理器、轉譯器、編輯工具、包管理器和構建過程的形式出現。 我沒有在堆棧頂部添加另一個插件,而是想知道,通過擴展其中一種核心語言 CSS,我們是否可以加強構建網站的材料,構建更好、更強大的網站,需要更少的外部支持和構建工具。
語法的誕生
到 2014 年底,由於對所需語法有了更好的了解,我聯繫了一位出色的 JavaScript 代碼高爾夫球手 Maxime Euziere,並詢問了他對在運行時在瀏覽器中使用 JavaScript 擴展 CSS 的可能性的看法。 他不僅告訴我這是可能的,而且還主動提出幫助我做到這一點! 我們將語法命名為 EQCSS,是“元素查詢 CSS”的縮寫。 這個名字也是對“過剩”這個詞的一種認可,因為它所做的一切都超出了 CSS 所能做的。
需要
我對語法的要求是它盡可能接近 CSS——如此接近以至於語法高亮會被愚弄以為它是標準 CSS。 因此,我為有意義的元素查詢制定了 CSS 語法——人們感到驚訝的那種語法並不存在。
我知道如果我們要使用 JavaScript 擴展瀏覽器對 CSS 的支持,那麼插件需要盡可能輕量和簡單才能完成工作,這排除了使用 jQuery 等庫來構建插件的可能性。 我需要一個純 JavaScript 庫,它將將來我想要的功能添加到我今天必須支持的瀏覽器中。
這時候CSS社區的討論主要集中在自定義@
規則上,關於元素查詢的討論還處於初步階段。 對於此類功能,我們可能距離任何官方 CSS 規範還有好幾年的時間,即使在規範之後,我們仍然需要等待足夠的瀏覽器支持才能在網站中使用這些功能。
當我們今天需要這些功能來構建和修復網站時,等待這些功能添加到 CSS 中是沒有意義的。
結果
這項研究的結果是創建了一種語法,其中包括一組新的高級響應條件、範圍樣式和用於定位元素的新選擇器,以及一個名為 EQCSS.js 的純 JavaScript 庫。 另外,在可選的外部 polyfill 中提供了對 Internet Explorer (IE) 8 的支持。 插件和 polyfill 都在 MIT 許可下發布,所有人都可以免費使用。
元素查詢用例
插件開發者
在創建 UI 組件和小部件時,開發人員經常發現自己受到媒體查詢的限制。 我們經常不得不在構建許多不同的佈局之間做出選擇,這些佈局可以由使用插件的人進行配置,以及將界面簡化到可以構建一刀切的解決方案的地步。
但是在設計帶有元素查詢的插件和界面時,我們可以輕鬆地編寫響應式樣式來涵蓋我們預期的所有情況,從而使它們真正防彈,無論用戶在其中放置什麼內容或插件出現在哪裡。 假設我們可以為一個 150 到 2000 像素寬的佈局設置樣式。 然後,無論該小部件顯示在網站的哪個位置,它總是看起來很棒。
模板生成器
當您對網站進行原型設計時,通常會重新組織頁面上的設計元素並將設計視為模塊化組件的集合。 如果您編寫了 CSS 媒體查詢,有時這可能是過早優化的情況。 通過使用元素查詢進行設計,您可以保持響應條件與佈局無關,從而為您提供更大的靈活性來移動事物,而無需重新設計樣式。
我發現使用元素查詢設計或模擬特別有用的東西包括:
- 導航欄,
- 模態,
- 註冊和登錄表格,
- 頁腳,
- 定價圖表,
- 登陸頁面,
- 表,
- 標籤框,
- 手風琴,
- 側邊欄小部件,
- 媒體播放器,
- 推薦部分。
任何設計元素都可以被“限定”並移植到任何地方——頁面到頁面或網站到網站。
設備支持
在移動設備上支持 Web 時,您面臨的問題之一是大量的硬件。 設備市場比以往任何時候都更加分散,新設備每天都在出現。 我們無法再維護我們支持的瀏覽器和設備的列表,因此了解設計適用於任何地方至關重要,即使在尚未發布的設備上也是如此。
通過使用元素查詢,您可以以更好的方式設計網站並消除其中一些跨瀏覽器差異。
最近撰寫的許多關於元素查詢需求的文章都詳細說明了許多用例。 那麼,讓我們繼續了解如何使用它們吧!
如何編寫元素查詢
EQCSS 入門很容易。 開始使用 EQCSS 語法所需要做的就是在 HTML 的某處包含 JavaScript。
下載 EQCSS.js
如果你想從 GitHub 克隆 EQCSS 項目,你可以輸入:
git clone https://github.com/eqcss/eqcss.git
如果您使用 npm,您可以使用以下命令將 EQCSS 添加到您的項目中:
npm install eqcss
將 EQCSS.js 添加到您的 HTML
下載 EQCSS 後,您可以使用script
標籤將其添加到 HTML:
<script src="EQCSS.js"></script>
此文件 ( EQCSS.js
) 包括對所有當前瀏覽器的支持,包括 IE 9 及更高版本。 為了支持 IE 8,我們不得不使用很多其他的 polyfill。 請記住,IE 8 甚至不支持沒有 polyfill 的 CSS 媒體查詢,所以我們能夠讓元素查詢也在那里工作真是太神奇了。 要包含對使用 EQCSS 的網站的 IE 8 支持,請在指向主插件的鏈接之前添加以下鏈接:
<!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>
運行 EQCSS
默認情況下,EQCSS 插件將在頁面加載後計算它找到的任何樣式,並且每當它檢測到瀏覽器正在調整大小時,類似於媒體查詢。 您還可以隨時使用 JavaScript 手動調用EQCSS.apply()
以重新計算樣式,這在頁面上更新內容後會很有用。
編寫元素查詢 CSS
EQCSS.js 插件可以通過幾種不同的方式讀取樣式。 您可以在 HTML 頁面上的任何style
標籤中包含 EQCSS。 您還可以在外部 CSS 樣式表中編寫 EQCSS。
如果您想將 EQCSS 驅動的代碼與 CSS 分開,您可以使用類型設置為text/eqcss
的script
標籤加載 EQCSS 語法。 您可以在這樣的標記中內聯添加樣式,或者使用<script type=“text/eqcss” src=styles.eqcss></script>
鏈接到外部.eqcss
樣式表,這將加載名為styles.eqcss
的文件.
元素查詢剖析
樣式範圍
EQCSS 中用於編寫元素查詢的語法與 CSS 媒體查詢的格式非常相似,但我們以@element
開始查詢,而不是@media
。 我們需要提供的唯一其他信息是這些樣式應該應用於的至少一個選擇器。 以下是為名為<div class=“widget”>
的元素創建新範圍的方法:
@element '.widget' { }
引號之間的元素(在本例中為.widget
)可以是任何有效的 CSS 選擇器。 通過這個查詢,我們在.widget
元素上創建了一個新範圍。 我們還沒有為作用域包含任何響應條件,因此像這樣的查詢中的任何樣式都將始終應用於作用域元素。
如果無法將樣式範圍限定為一個或多個元素(而不是一次覆蓋整個頁面),我們將無法僅將響應式查詢應用於這些元素。 一旦我們創建了元素級別的範圍,使用 EQCSS 語法的更高級的特性就變得很容易了——例如$parent
元選擇器——因為 JavaScript 現在有一個參考點來計算像範圍的parentNode
這樣的東西元素。 這是巨大的!
確實,CSS 已經包含一個直接後代選擇器,帶有>
,它允許我們選擇作為指定元素的直接子元素的元素。 但是 CSS 目前沒有提供沿家族樹的另一個方向向上移動的方法,以選擇包含另一個元素的元素,人們將其稱為其父元素。 “CSS Selectors Level 4”規範現在包括一個:has()
選擇器,它的工作方式類似於 jQuery 的:has()
選擇器,但目前瀏覽器支持為零。 Scoped CSS 使不同類型的父選擇器成為可能。
現在我們已經在.widget
元素的上下文中打開了一個作用域,我們可以從它的角度編寫樣式來定位它自己的父元素:
@element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }
可以在任何元素查詢中使用的特殊選擇器的另一個示例是$prev
和$next
選擇器,它們表示前一個和下一個兄弟元素。 儘管 CSS 可以使用.widget + *
之類的選擇器到達我們小部件的下一個兄弟,但 CSS 中無法向後到達並選擇直接位於另一個元素之前的元素。
<section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>
元素查詢
開發人員最常使用 CSS 媒體查詢進行響應式設計,方法是根據瀏覽器視口的高度或寬度應用樣式。 EQCSS 語法支持許多新類型的響應條件。 除了單獨使用瀏覽器的寬度和高度之外,您還可以根據元素自身的屬性編寫適用於元素的樣式,例如元素包含多少子元素,或者元素中當前有多少字符或文本行.
將這些響應條件添加到您的作用域樣式類似於格式化媒體查詢的方式:您將為要檢查的每個條件添加and (condition: value)
。 在此示例中,我們將檢查是否有任何.widget
元素在頁面上顯示至少 500 像素寬。
@element '.widget' and (min‐width: 500px) { /* CSS rules here */ }
元素查詢的語法分解如下:
- 元素查詢
@element selector_list [ condition_list ] { css_code }
- 選擇器列表
" css selector [ "," css selector ]* "
- 條件列表
and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
- 數值
number [ css unit ]
- 查詢條件
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
- css 單位
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
作為另一個例子,下面是如何編寫一個查詢,當.widget
元素達到 500 像素寬時將body
元素變為紅色:
@element '.widget' and (min‐width: 500px) { body { background: red; } }
請注意,當.widget
達到一定寬度時, body
元素會發生變化,而不是.widget
元素本身!
元素查詢條件
以下是 EQCSS 支持的響應條件的完整列表。
基於寬度的條件
- 像素
min-width
演示,百分比的演示 - 像素
max-width
演示,百分比的演示
基於身高的條件
- 像素
min-height
演示,百分比演示 - 像素
max-height
演示,百分比演示
基於計數的條件
- 塊元素
min-characters
演示,表單輸入的演示 - 塊元素
max-characters
演示,表單輸入的演示 min-lines
演示max-lines
演示min-children
演示max-children
演示
基於滾動的條件
min-scroll-y
演示max-scroll-y
演示min-scroll-x
演示max-scroll-x
演示
您可以在元素查詢中組合任意數量的這些條件,以獲得真正的多維響應式樣式。 這使您可以更靈活地控制元素的渲染方式。 例如,當可顯示的空間少於 600 像素時,要縮小超過 15 個字符的標題的字體大小,您可以組合max‐characters: 15
和max‐width: 600px
的條件:
h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }
元選擇器
一旦開始編寫具有響應條件的作用域樣式,您可能會遇到的問題之一是,當同一選擇器的多個實例位於頁面上時,在元素查詢中使用該選擇器會將樣式應用於該選擇器上的所有實例任何一個符合條件的頁面。 以前面的.widget
示例為例,假設我們在頁面上有兩個小部件(可能一個在側邊欄中,另一個全寬顯示),我們這樣編寫元素查詢:
@element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }
這意味著當頁面上的任一.widget
元素至少有 500 像素寬時,該樣式將應用於這兩個.widget
元素。 在大多數情況下,這可能不是我們想要發生的。 這就是元選擇器的用武之地!
組成我們的元素查詢的兩個部分是選擇器和響應條件。 因此,如果我們只想定位頁面上同時匹配選擇器和響應條件的元素,我們可以使用元選擇器$this
。 我們可以重寫上一個示例,使樣式僅適用於匹配min‐width: 500px
條件的.widget
元素:
@element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }
EQCSS 語法支持許多不在常規 CSS 中的新選擇器。 以下是完整列表:
-
$this
演示 $parent
演示$root
演示$prev
演示$next
演示
這些選擇器僅適用於元素查詢。
打開 JavaScript 和 CSS 之間的門戶
eval(')
演示
EQCSS 的最後一個也是最後一個特性是最狂野的: eval(')
。 通過這個入口,可以從 CSS 訪問 JavaScript 的所有功能。 儘管 JavaScript 可以將樣式應用於元素,但它目前很難實現某些東西,例如:before
和:after
偽元素。 但是如果 CSS 可以從另一個方向到達 JavaScript 呢? 如果 CSS 可以感知 JavaScript,而不是 JavaScript 設置 CSS 屬性,那會怎樣?
這就是eval(')
用武之地。您可以訪問和評估任何 JavaScript,是否使用 CSS 中 JavaScript 變量的值來執行 JavaScript 單行(如eval('new Date().getFullYear()')
),以確定有關瀏覽器的值和 JavaScript 可以測量的其他元素(如eval('innerHeight')
)或運行 JavaScript 函數並使用它在 CSS 樣式中返回的值。 這是一個在<footer>
元素中輸出2016
的示例:
@element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }
在 eval(') 中使用 $it
在評估 JavaScript 時, eval(')
還可以在活動範圍元素的上下文中工作,即$this
的樣式適用於同一元素。 你可以在用eval(')
編寫的 JavaScript 中使用$it
作為作用域元素的佔位符,如果它可以幫助你構造代碼,但如果省略,它會以相同的方式工作。 例如,假設我們有一個div
,其中包含單詞“hello”。 以下代碼將輸出“hello hello”:
<div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>
在這裡, $it
指的是div
,因為它是當前作用域的選擇器。 您也可以省略$it
並編寫以下代碼來顯示相同的內容:
@element 'div' { div:before { content: "eval('textContent') "; } }
eval(')
在 CSS 不知道頁面加載後發生的測量或事件的情況下會很有幫助。 例如,用於嵌入 YouTube 視頻的 iframe 元素具有指定的寬度和高度。 雖然您可以在 CSS 中將寬度設置為auto
,但當視頻擴展以填充可用空間時,沒有簡單的方法來保持正確的寬高比。
在縮放時保持響應式縱橫比的常見解決方法是將需要保持其縱橫比的內容放置在包裝器中,然後使用基於您想要保持的寬高比的值向包裝器添加填充。 這可行,但需要您提前知道所有視頻的縱橫比,並且需要為每個要響應式嵌入的視頻添加更多 HTML 標記(包裝器元素)。 在每個具有響應式視頻的網站上乘以它,如果 CSS 稍微聰明一點,那就不需要存在很多麻煩了。
也許更好的響應式縱橫比方法是將每個視頻放在一個沒有填充的包裝器中,然後編寫一個 JavaScript 庫來計算它找到的每個視頻的縱橫比,並將正確的填充量應用於每個包裝器。
但是如果 CSS可以直接訪問這些測量值呢? 我們不僅可以將所有不同縱橫比的 CSS 合併到一個規則中,而且如果我們可以在頁面加載後對其進行評估,我們可以編寫一個規則來響應式地調整我們將來提供的任何視頻的大小。 我們可以在沒有任何包裝器的情況下完成這一切!
如果這看起來好得令人難以置信,請檢查一下。 以下是在 EQCSS 中編寫無包裝響應式調整 iframe 元素大小的簡單方法:
@element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }
這裡, width
和height
指的是 HTML 中 iframe 中的width=“”
和height=“”
屬性。 JavaScript 可以執行(width/height)
的計算,這給了我們縱橫比; 並將其應用於任何寬度,我們只需將 iframe 元素的當前寬度除以比率。
這具有 CSS 的簡潔性和易讀性,以及 JavaScript 的所有功能。 不需要額外的包裝器,不需要額外的類,也不需要額外的 CSS。
不過要小心eval(')
。 CSS表達式在過去被認為是危險的是有原因的,我們嘗試這個想法也是有原因的。 如果您不注意將它們應用到頁面上的元素數量或重新計算樣式的頻率,那麼 JavaScript 最終運行的東西可能比需要的多數百倍。 幸運的是,EQCSS 允許我們調用EQCSS.apply()
或EQCSS.throttle()
來手動重新計算樣式,這樣我們就可以更好地控製樣式何時更新。
危險地帶!
如果您創建具有衝突條件或樣式的查詢,則可能會出現其他問題。 EQCSS 和 CSS 一樣,使用特定的層次結構從上到下閱讀。 儘管 CSS 是一種聲明性語言,但它確實包含一些高級功能。 它距離圖靈完備的編程語言只有幾步之遙。 到目前為止,調試 CSS 是一件非常簡單的事情,但是 EQCSS 將 CSS 從簡單的解釋性聲明性語言轉變為動態樣式表語言,在 CSS 和瀏覽器之間增加了一個解釋層。 伴隨著這個新領域而來的是各種潛在的新陷阱。
這是 EQCSS 中的互惠循環的示例,普通的 CSS 媒體查詢在設計上是免疫的:
@element '.widget' and (min‐width: 300px) { $this { width: 200px; } }
我稱之為jekyll: hide;
CSS。 但除了一種風格不斷觸發自身之外,還有可能編寫多個相互觸發的查詢,在我們所說的“雙向倒數循環”中,這是最討厭的:
@element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }
從理論上講,那個不幸的小部件會卡在一個循環中,在 200 到 500 像素之間調整大小直到時間結束,無法確定寬度。 對於這樣的情況,EQCSS 只是按照評估順序計算規則,獎勵獲勝者並繼續前進。 如果你要重新排列這些規則出現的順序,如果它們具有相同的特異性,後一種風格總是會獲勝。
有人說創建循環(甚至是雙倒數倒數循環)的能力是一個設計缺陷,但為了防止循環成為可能,您需要限制 EQCSS 的功能,以消除大部分語法提供的值。 另一方面,在 JavaScript 中創建無限循環非常容易,但這並不被視為該語言的缺陷——它被視為其強大功能的證明! 元素查詢也是如此。
調試元素查詢
目前,調試元素查詢有點像在我們擁有像 web 檢查器這樣的工具來向我們展示在頁面上計算的樣式之前調試媒體查詢。 目前,調試和開發元素查詢需要開發人員維護一個應該發生的響應行為的心理模型。 未來可能會構建支持 EQCSS 的開發者工具,但目前所有主流瀏覽器的開發者工具都只知道 EQCSS 已經應用到頁面元素上的樣式,並不知道EQCSS 正在觀察的響應條件。
如何使用元素查詢進行設計
使用元素查詢的最簡單方法是將使用媒體查詢的現有設計轉換為元素查詢,從一個佈局中“解放”元素及其響應式樣式,並使其易於在其他頁面和項目中重用該代碼。 以下媒體查詢和元素查詢可能意味著相同的事情:
footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }
不同之處在於,在原始示例中,頁腳鍊接保持為display: block
直到瀏覽器至少有 500 像素寬。 第二個例子,使用元素查詢,看起來是一樣的,但前提是footer
元素是全寬的。
在將這種樣式從其原始媒體查詢中解放出來之後,我們現在可以將頁腳放置在任何寬度的容器中,並確保當頁腳需要應用響應式樣式時(即,當它小於 500 像素時),它將是應用。
- 確保
EQCSS.js
存在於目標文檔的 HTML 中。 - 在 CSS 中將
@media
替換為@element
。 - 將 CSS 選擇器添加到每個
@element
查詢的範圍內。 - 可選:在元素查詢中用
$this
替換出現的作用域元素。
除非您要轉換的設計組件最初設計為使用瀏覽器視口的全寬顯示,否則您可能必須在轉換為元素查詢後調整斷點。
避免鎖定
編寫 EQCSS 樣式的體驗與編寫常規 CSS 的體驗類似:所有您最喜歡的 CSS 屬性和技術仍然存在,只是有一些額外的功能可以幫助它們以新的方式協同工作。 因為 EQCSS 將標準 CSS 輸出到瀏覽器,所以您的瀏覽器內置支持的任何 CSS 功能在與 EQCSS 一起使用時都可以使用。 如果有一天元素查詢和範圍樣式等功能在 CSS 中指定並在瀏覽器中得到支持,那麼您將能夠立即開始在 EQCSS 代碼中使用它們,同時仍然依賴 EQCSS 來實現瀏覽器不支持的其他功能但原生支持。
因為您可以直接在 CSS 中以及在其自己的腳本中使用 EQCSS 語法,類型為text/eqcss
,如果 CSS 曾經為原生元素查詢開發過語法,您仍然可以將 EQCSS 作為腳本加載並避免衝突.
展望未來,瀏覽器開發人員目前正在試驗的一種解決方案是 Houdini,它將為插件開發人員打開以新方式擴展 CSS 的訪問權限,例如添加對瀏覽器本身的支持。 有一天,可能會編寫出更高效的插件來解釋 EQCSS 語法,並以比當前 JavaScript 庫所允許的更直接和高效的方式將這些功能帶到瀏覽器中。
那麼,我們還應該使用媒體查詢嗎?
是的,儘管元素查詢提供了許多新的和令人興奮的方式來定位具有樣式的元素,但媒體查詢(儘管有限)在瀏覽器中的運行速度總是比依賴 JavaScript 計算的樣式快。 然而,CSS 媒體查詢不僅僅是為屏幕設置 HTML 樣式。 CSS 媒體查詢還支持基於打印的查詢和網站顯示信息的其他方式。 EQCSS 可以與打印樣式等媒體查詢結合使用,因此無需因為元素查詢現在也可以使用而停用媒體查詢!
以20 ⁄ 20願景進行設計
對於 CSS 的未來,我們能做的最好的事情就是在今天盡可能多地嘗試這些想法。 再多的關於這些特性的頭腦風暴和理論分析都不會像實際嘗試實現它們並投入使用,發現使它們有用和強大的技術一樣有用。
除了為元素查詢提供解決方案之外,EQCSS.js 還有望成為擴展 CSS 的其他實驗的平台。 如果您對新的響應條件、新的 CSS 屬性或在代碼中使用的新選擇器有想法,則分叉 EQCSS.js 並對其進行修改以包含您的想法可以讓您輕鬆完成大部分工作。
模塊化設計
In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.
The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.
Thinking Element-First
Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.
For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”
<form> <input type=search> <input type=button value=Search> </form>
Desktop-First Approach
In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.
input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }
移動優先方法
In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.
input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }
Element-First Approach
In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form
element itself, writing a style like this:
input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }
The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.
Resources For Getting Started
EQCSS-Enabled Template
<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>
演示
- Responsive Aspect Ratio
- Sticky Scroll Header
- Blockquote Style
- 日曆
- Content Demo
- Counting Children Demo
- Date Demo
- Zastrow-style Element Query Demo Demo
- Flyout Demo
- Headline Demo
- Media Player Demo
- Message Style Demo
- Modal Demo
- Nav Demo
- Parent Selector Demo
- Pricing Chart Demo
- Responsive Tables Demo
- Scroll-triggered Blocker Demo
- Signup Form Demo
- Testimonials Block Demo
- Tweet-Counter Demo
- JS Variables Demo
- Responsive Scaling Demo
- Geometric Design Demo
- Responsive Order Form
- Element Query Grid
- JS Functions in CSS
- Responsive Content Waterfall
延伸閱讀
You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.
快樂黑客!