譯文:在JavaScript應用程式中包含CSS的多種方法

2021-02-25 Duing

原文連結:https://css-tricks.com/the-many-ways-to-include-css-in-javascript-applications/,作者:Dominic Magnifico

如有翻譯不準確,請多指正。

歡迎來到這個在前端開發領域極具爭議性的話題!我相信讀到這篇文章的大多數人都曾遇到過關於#如何在JavaScript應用程式中處理CSS#相關的熱門問題。

在這篇文章之前,我想聲明一句:沒有什麼硬性標準可以確定在React、Vue或Angular應用程式中處理CSS的哪一種方法是最好的。每個項目都是不同的,每個方法都有自己的優點!這樣說好像有點含糊不清,但我知道的是,我們所處的開發社區中有很多人去不斷尋求新信息,他們希望以更加有意義的方式推動web向前發展。

暫且把關於這個主題先入為主的概念放在一邊,讓我們來看看迷人的CSS體系結構世界吧!

首先讓我們一起來盤點一下這些方法

簡單地搜索「如何將CSS添加到[在此處插入框架]」就能出現一系列關於如何將樣式應用於項目的意見。為了幫助大家進行篩選摘除,我們將從各更高級的角度研究一些常用的方法及其目的。

選項1:傳統樣式表

我們完全可以用一種熟悉的方式開始:一個傳統樣式表,完全可以在應用程式之中連結一個外部樣式表,這樣就可以完工了。

我們可以按照我們的習慣編寫CSS,然後繼續我們的生活。這根本沒有什麼問題,但是隨著應用程式越來越大、越來越複雜,維護單個樣式表就越來越難了。解析數千行CSS(這些CSS負責設計整個應用程式的樣式)對於從事該項目的任何開發人員來說都是一件痛苦的事情。

樣式級聯看起來很美好但它也變得很難管理,因為你或項目上的其他開發者編寫的一些樣式會在應用程式的其他部分引入回歸。我們之前也遇到過這些問題,並且引入了Sass之類的東西(以及最近的PostCSS)來幫助我們處理這些問題。

我們可以繼續沿著這條路走下去,利用PostCSS的強大功能來編寫非常模塊化的CSS部分,這些部分通過@import規則串在一起。這需要在webpack配置中進行一些工作才能正確設置,但這些事情大家肯定可以處理!

無論你決定用哪種編譯器,你都可以通過標題中的標記獲得一個包含應用程式所有樣式的CSS文件。根據應用程式的複雜程度,這個文件可能會變得非常臃腫,難以異步加載,並且應用程式的其餘部分會出現租用者阻塞。(當然,阻塞並不總是一件壞事,但是為了所有的意圖和目的,我們將在這裡泛化一點,儘可能避免渲染阻塞腳本和樣式。)

這並不是說這種方法毫無優點,對於小型應用程式,或者由不太關注前端的團隊構建的應用程式,單個樣式表可能是一個不錯的選擇。它在業務邏輯和應用程式風格之間提供了清晰的分離,而且由於它不是由我們的應用程式生成的,因此完全在我們的控制範圍內,以確保我們編寫的內容與輸出的內容完全一致。此外,瀏覽器緩存單個CSS文件相當容易,因此返回的用戶在下次訪問時不必重新下載整個文件。

但是假設我們正在尋找一個更健壯的CSS架構,它允許我們利用工具的強大功能。它可以幫助我們管理一個需要更多微妙方法的應用程式,輸入CSS模塊。

選項2:CSS模塊

單個樣式表中的一個相當大的問題是回歸的風險。編寫使用相當非特定選擇器的CSS可能最終會改變應用程式中完全不同區域的另一個組件。這就是所謂的「作用域樣式」派上用場的地方。

帶作用域的樣式允許我們以程序化的方式生成特定於組件的類名。因此,將這些樣式限定到該特定組件,以確保其類名是唯一的。這將導致自動生成的類名,例如header__2lexd。最後一點是一個哈希值,它是唯一的,因此即使你有另一個名為header的組件,也可以對其應用標題類,並且我們的作用域樣式將生成一個新的哈希後綴,如下所示:header__15qy_。

CSS模塊提供了控制生成的類名的方法(具體取決於實現),但是我將把這個問題留給CSS模塊文檔來討論。

所有這些都完成之後,我們仍然在生成一個CSS文件,該文件通過<link>標頭中的標記傳遞給瀏覽器。這帶來了同樣的潛在缺點(渲染阻塞、文件大小膨脹等),當然也有好處主要是緩存作用。但是,由於這種方法的作用域樣式附帶了另一個警告:刪除全局作用域——至少在最初是這樣。

假設你想使用.screen-reader-text全局類,該類可以應用於應用程式中的任何組件。如果使用CSS模塊,則必須使用:global偽選擇器,該選擇器將其中的CSS明確定義為可被應用程式中其他組件全局訪問的對象。只要將包含global聲明塊的樣式表導入到組件的樣式表中,就可以使用該全局選擇器。這不是一個很大的缺點,但是需要逐漸適應。

這是一個:global偽選擇器的示例:

你可能會冒著將一堆用於字體,表格以及大多數站點的通用元素的全局選擇器放到一個單獨的global選擇器中的風險。幸運的是,通過諸如PostCSSNested或Sass之類的魔術,你可以將部分代碼直接導入選擇器中,以使事情更簡潔:

這樣,你可以不使用:global選擇器來編寫局部文件,而直接將其直接導入到主樣式表中。

需要習慣的另一點是如何在DOM節點中引用類名。我將在這裡以Vue,React和Angular的各個文檔為例。我還將為你提供一些示例,說明這些類引用在React組件中的使用方式:

同樣,CSSModules方法具有一些很好的用例。對於希望利用範圍樣式,同時保持靜態但已編譯樣式表的性能優勢的應用程式,CSS模塊可能是最適合你的選擇!

在這裡也要注意,CSS模塊可以與你喜歡的CSS預處理功能結合使用。Sass,Less,PostCSS等都可以使用CSS模塊集成到構建過程中。

但是,假設你的應用程式可以通過包含在JavaScript中而受益。也許獲得對組件各種狀態的訪問權並根據不斷變化的狀態做出反應也將是有益的。如果你也想輕鬆地將關鍵CSS集成到的應用程式中去,那就輸入CSS-in-JS吧。

選項3:CSS-in-JS

CSS-in-JS是一個相當廣泛的主題。有幾個包可以使CSS-in-JS的編寫變得儘可能輕鬆。像JSS、Emotion和樣式組件之類的框架只是構成本主題的眾多包中的一小部分。

作為大多數這些框架的粗略解釋,CSS-in-JS基本上以相同的方式運行。你編寫與單個組件關聯的CSS,並且構建過程將編譯該應用程式。發生這種情況時,大多數CSS-in-JS框架只會輸出在任何給定時間在頁面上呈現的組件的關聯CSS。CSS-in-JS框架通過在應用程式的<head>中的<style>標記內輸出該CSS來實現此目的。這為你提供了一個非常重要的CSS加載策略!另外,很像CSS模塊,樣式是作用域的,並且類名是散列的。

當你在應用程式中導航時,已卸載的組件將從<head>中刪除其樣式,而已裝入的傳入組件將在其位置附加其樣式。這為你的應用程式提供了性能優勢的機會。它刪除一個HTTP請求,不會阻止渲染,並確保你的用戶在任何給定時間僅下載他們需要的內容以查看該頁面。

CSS-in-JS提供的另一個有趣的機會是能夠引用各種組件狀態和功能以呈現不同的CSS。這可能很簡單,例如根據某些狀態變化來複製類切換,也可能像主題化一樣複雜。

因為CSS-in-JS是一個相當熱門的話題,所以我意識到人們正在嘗試採用許多不同的方法。現在,我分享了許多其他人對CSS的高度評價,尤其是在利用JavaScript編寫CSS方面。我對這種方法的最初反應是相當負面的。我不喜歡交叉汙染兩者的想法,但我想保持開放的態度。

讓我們來看看我們作為前端開發人員需要的一些功能,甚至可以考慮採用這些方法。

1. 如果我們要編寫CSS-in-JS,則必須編寫真實的CSS。多個軟體包提供了編寫模板文字CSS的方法,但是要求你用駝峰式大小寫屬性-即padding-left變成paddingLeft。那不是我個人願意犧牲的東西。

2. 某些CSS-in-JS解決方案要求你在要設置樣式的元素上內聯編寫樣式。這樣做的語法,尤其是在複雜的組件中,開始變得非常忙碌,而這又不是我願意犧牲的東西。

3. 使用CSS-in-JS必須為我提供強大的工具,否則這些工具很難通過CSS模塊或dangol的樣式表來完成。

4. 我們必須能夠利用具有前瞻性的CSS(例如嵌套和變量)。我們還必須能夠合併Autoprefixer之類的東西以及其他附加組件,以增強開發人員的體驗。

對於框架,有很多要求,但是對於那些一生中大部分時間都圍繞著我們喜歡的語言來研究和實現解決方案的人來說,我們必須確保我們能夠繼續以最好的語言編寫相同的語言我們可以快速瀏覽一下使用樣式化組件的React組件的外觀:

我們還需要解決CSS-in-JS解決方案的潛在缺點——而且絕對不要試圖引發更多的鬧劇。使用這樣的方法,我們很容易陷入一個陷阱,這會導致我們得到一個膨脹的JavaScript文件,其中可能包含數百行CSS——而這一切甚至在開發人員看到任何組件的方法或其HTML結構之前就已經出現了。

然而,我們可以將此視為一個機會,來非常仔細地檢查我們是如何以及為什麼以這種方式構建組件的。通過更深入地考慮這一點,我們可以潛在地利用它,並使用更多可重用組件編寫更簡潔的代碼。

此外,此方法絕對模糊了業務邏輯和應用程式樣式之間的界限。但是,有了一個有據可查且經過深思熟慮的體系結構,該項目中的其他開發人員可以輕鬆地採用這種想法,而不會感到不知所措。

寫在最後

有多種方法可以處理任何項目上的CSS體系結構的難題,並且可以在使用任何框架時進行處理。作為開發人員,我們擁有如此眾多的選擇,這既令人興奮,又令人難以置信。但是,我認為,最終我們會在超短的社交媒體對話中迷失的首要原因是——每種解決方案都有其優點和效率低下的弊病。這是關於我們如何謹慎,周到地實施使我們自己/或其他可能接觸代碼的開發人員的系統的感謝,感謝我們花時間建立該結構。

相關焦點

  • 利用CSS、JavaScript及Ajax實現圖片預加載的三大方法
    Perishable Press網站近日發表了一篇文章《3 Ways to Preload Images with CSS, JavaScript, or Ajax》,分享了利用CSS、JavaScript及Ajax實現圖片預加載的三大方法。下面為譯文。預加載圖片是提高用戶體驗的一個很好方法。
  • JavaScript中的CSS: CSSX
    另外不是所有屬性樣式都可以放到內聯樣式中,比如說媒體查詢和偽類。我的目標就變成了如何解決這兩個問題,剛開始我整理了一個解決方案。下圖演示了如何在JavaScript中寫CSS:在把你的代碼和實際樣式應用到頁面之間有一個庫,它的主要責任就是創建一個虛擬的樣式表,並將其和<style>標記關聯起來。然後,它將提供一個PAI來管理CSS規則。
  • 如何正確地在XHTML文檔中使用JavaScript和CSS
    正確的XHTML格式是一個XML程序並且在書寫的時候需要按照以下的嚴格規則:1.字符<和&不允許出現在XHTML文檔內容中,除非它們被包含在CDATA標籤中(<![CDATA[...]]>)2.注釋標籤(<!--...-->)內容中不能包含兩個連續的橫槓(--)3.包含在注釋標籤(<!--...
  • 網頁性能之html css javascript
    前言html css javascript可以算是前端必須掌握的東西了,但是我們的瀏覽器是怎樣解析這些東西的呢 我們如何處理html css javascript這些東西來讓我們的網頁更加合理,在我這裡做了一些實驗,總結起來給大家看看。
  • [分享]Rhino使JavaScript應用程式更靈動
    JavaScript一直是腳本語言中的領頭羊,它是一門具有非常豐富特性的語言。除了瀏覽器之外,JavaScript也可以應用在其他場合,比如伺服器端程序中。Rhino是使用Java語言實現的JavaScript 引擎,本文將介紹如何利用Rhino來使您的應用程式提供JavaScript腳本的支持。
  • Css語法特點是什麼?Css和html、javascript的關係是什麼?
    CSS是英文Cascading Style Sheets首字母的簡寫,翻譯成中文是層疊樣式表,簡單理解它是html語言的一個應用,css可以修飾各種動態和靜態頁面,對頁面中的元素進行精準控制(是像素為單位的),css的誕生是為了解決html的顯示功能,它解決了html顯示雜亂和臃腫的問題
  • ASP、PHP與javascript根據時段切換CSS皮膚的代碼
    首頁 > 教程 > 關鍵詞 > php最新資訊 > 正文 ASP、PHP與javascript根據時段切換CSS皮膚的代碼
  • HTML+CSS+JavaScript網頁設計課程的教與學
    掌握網站規劃、設計、製作、管理、發布的相關技術及網頁製作的操作技能;並熟練運用HTML中的文字、連結、列表、表格、表單、圖像、多媒體、框架標記及屬性設計出框架網頁、表單網頁、多媒體動態網頁;掌握使用css技術進行網頁布局的基本方法。
  • 翻譯 | 《JavaScript Everywhere》第18章 帶Electron的桌面應用程式(^_^)
    目前,該應用程式將是一個簡單的實現,它將我們的Web應用程式包裝在桌面應用程式shell中。以這種方式開發我們的應用程式將使我們能夠快速將桌面應用程式發送給感興趣的用戶,同時為我們提供了以後為桌面用戶引入自定義應用程式的靈活性。
  • CSS中behavior屬性語法簡介
    作者:52css來源:52css.com|2010-09-01 11:00
  • Message 類的使用方法和效果
    > 看了Ext的API 文檔後,開始自己嘗試做一些修改,並安裝自己項目所需寫一個小的Demo程序,再以後開發的時候可以很方便的引用進來。效果如下:這些信息窗口涉及到了Ext.MessageBox 類下的show方法中title、msg、closable屬性的設置。Ext.MessageBox 可以簡寫為Ext.Msg 這個類下面的方法和屬性設置還是挺豐富的。但是我們一般比較常用的就是show。在這個程序中我們還用到了JS的計時函數在執行關閉。
  • 網頁布局:CSS控制表格嵌套
    網頁設計應用中,當我們不能完全放棄表格的使用時,為了達到預期的效果,不免要用到表格嵌套(特別是多層嵌套)方式來進行布局。可能很多同仁都遇到過這樣的問題,對了達到顯示效果要為每一個(每一層)的表格寫不同的CSS代碼或加不同的屬性值。這樣寫出來的代碼可讀性非常差,不便修改和管理。學會用CSS中的偽類這個問題就迎刃而解了,看一看我的處理方法吧。
  • 不要再在JavaScript中寫 CSS了
    為了完全透明,我還要指出我是 react-css-modules 和 babel-plugin-react-css-modules 的作者。 隨著發展,JavaScript 拓展、轉變,有了新的應用場景。 Ajax 的出現(2005)是一個重要的裡程碑。這時 Prototype、jQuery、MooTools 等庫已經吸引了大量的擁護者,共同解決後臺跨瀏覽器數據獲取問題。這又引發了新的問題:如何管理數據? 到了 2010 年,Backbone.js 出現,成為了應用狀態管理的行業標準。
  • 不要再在 JavaScript 中寫 CSS 了
    和 babel-plugin-react-css-modules 的作者。隨著發展,JavaScript 拓展、轉變,有了新的應用場景。Ajax 的出現(2005)是一個重要的裡程碑。這時 Prototype、jQuery、MooTools 等庫已經吸引了大量的擁護者,共同解決後臺跨瀏覽器數據獲取問題。這又引發了新的問題:如何管理數據?到了 2010 年,Backbone.js 出現,成為了應用狀態管理的行業標準。
  • 網頁設計HTML_CSS_JavaScript語言_外部文件
    獨立文件CSS與獨立文件JavaScript描述—代碼HTML文件代碼<html><head><title>網頁的CSS和JavaScript外部文件</title><link href="External_1.CSS"rel="stylesheet" type="text/css
  • JavaScript能應用在哪些方向?未來前景怎麼樣?
    網頁開發css,javascript,html。移動應用僅需要一套代碼就可以在各個環境裡暢行無阻曾經是人們夢寐以求的,現在這個夢想成為了現實,只需要js,你就能輕鬆開發出適合各個平臺的應用。伴隨著小程序,pwa等等新技術的發展,JavaScript在移動領域方面也有了更加充足的話語權。
  • 5個開發桌面應用程式的JavaScript框架
    5個開發桌面應用程式的JavaScript框架 很久以前,開發客戶端桌面程序需要我們掌握各種複雜的技術,不過現在,我們只需要使用js就可以開發出桌面應用程式,下面我們盤點5個開發桌面應用程式的框架。
  • 前端面試題(理論知識+HTML+CSS+JavaScript)襲來,請接招!【附答案】
    一個程序至少有一個進程,一個進程至少有一個線程b. 線程的劃分尺度小於進程,使得多線程程序的並發性高c. 進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率d. 每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個線程執行控制e.
  • 使用JavaScript,也能在 Web 應用中實現人臉檢測功能?!
    在本文中,我們將以 JavaScript 庫 pico.js 為依託,手把手教你如何為一款應用添加面部檢測功能。作者 | Jonathan Freeman譯者 | 彎月,責編 | 屠敏以下為譯文:在本文中,我們將使用pico.js添加簡單的面部檢測。
  • 5種你未必知道的JavaScript和CSS交互的方法
    我們的網頁中都有.js文件和.css文 件,但這並不意味著CSS和js是獨立不能交互的。下面要講的這五種JavaScript和CSS共同合作的方法你也許未必知道!用JavaScript獲取偽元素(pseudo-element)屬性大家都知道如何通過一個元素的style屬性獲取它的CSS樣式值,但能獲取偽元素(pseudo-element)的屬性值嗎?