我們都熟悉將樣式表鏈接到 HTML 文檔的<head>
的標準方式,但這只是我們編寫 CSS 的幾種方式之一。而在單頁應用程序 (SPA) 中又是怎麼編寫樣式的呢,比如在 React
項目中。
事實證明,有多種方法可以在 React 應用裡編寫 CSS。有的和傳統方式很像,但有的差距卻很大。所以接下來統計一下我們可以使用的方式有哪些。
導入外部樣式表#
顧名思義,React 可以導入 CSS 文件。該過程類似於我們在 HTML<head>
中鏈接 CSS 文件的方式:
- 在項目目錄中創建新的 CSS 文件。
- 寫 CSS。
- 將其導入 React 文件。
比如
import "./style.css";
通常,這個導入位於文件頂部。
import { React } from "react";
import "./App.css";
function App() {
return (
<div className="main">
</div>
);
}
export default App;
在上面這個例子中,一個名為App.css
的文件被引入了App.jsx
頂部。
編寫內聯樣式#
你過去可能聽到內聯樣式對於可維護性等來說並不是那麼好,但在某些情況它肯定是有意義的。並且可維護性在 React
中不是問題,因為 CSS
通常已經位於同一個文件中了。
下面是在 React
裡很簡單的一個內聯樣式的寫法:
<div className="main" style={{ color: "red" }}>
但是,更好的方式是傳入一個對象:
- 首先,創建一個包含不同元素樣式的對象。
- 然後使用
style
屬性將其添加到元素中。
import { React } from "react";
function App() {
const styles = {
main: {
backgroundColor: "#f1f1f1",
width: "100%",
},
inputText: {
padding: "10px",
color: "red",
},
};
return (
<div className="main" style={styles.main}>
<input type="text" style={styles.inputText}></input>
</div>
);
}
export default App;
實例包含一個styles
對象,該對象包含另外兩個對象,一個是應用到 .main
class 的元素,另一個用於input
元素,其中包含類似於我們希望在外部樣式表中看到的樣式規則。 然後將這些對象應用於返回標記中元素的style
屬性。
此示例包含一個樣式對象,該對象包含另外兩個對象,一個用於 .main 類,另一個用於文本輸入,其中包含類似於我們希望在外部樣式表中看到的樣式規則。然後將這些對象應用於返回標記中元素的樣式屬性。
請注意,在引用樣式時使用大括號而不是我們通常在純 HTML 中使用的引號。
使用 CSS Modules#
CSS Modules,它具有局部作用域變量的優勢,可以與 React
一起使用。 但是,它到底是什麼?
引用文檔裡的話來說
CSS Modules works by compiling individual CSS files into both CSS and data. The CSS output is normal, global CSS, which can be injected directly into the browser or concatenated together and written to a file for production use. The data is used to map the human-readable names you've used in the files to the globally-safe output CSS.
翻譯過來即是:
CSS 模塊通過將單個 CSS 文件編譯成 CSS 和數據來工作。 CSS 輸出是正常的全局 CSS,可以將其直接注入瀏覽器或連接在一起並寫入到一個文件以供生產使用。 該數據用於將您在文件中使用的可讀名稱映射到全局安全的輸出 CSS。
簡單來說,CSS Modules
允許我們在多個文件中使用相同的類名而不會發生衝突,因為每個類名都有一個唯一的程序名稱。這在大型應用程序中特別有用。每個類名都在本地作用於導入它的特定組件。
CSS 模塊樣式表類似於常規樣式表,僅具有不同的擴展名(例如styles.module.css
)。這是他們的設置方式:
- 創建一個以
.module.css
作為擴展名的文件。 - 將該模塊導入
React
應用程序(就像我們之前看到的那樣) - 將
className
添加到元素或組件,並從導入的樣式中引用特定樣式。
簡單例子:
@tab styles.module.css
/* styles.module.css */
.heading {
color: #f00;
font-size: 20px;
}
@tab App.jsx
import { React } from "react";
import styles from "./styles.module.css";
function App() {
return (
<h1 className={styles.heading}>Hello World</h1>
);
}
export default App;
使用 styled-components#
你用過 styled-components
嗎?它非常流行,允許您在 JavaScript 中使用實際的 CSS 構建自定義組件。styled-component
基本上是一個帶有樣式的 React
組件。它包括獨特的類名、動態樣式和更好的 CSS
管理,每個組件都有自己獨立的樣式。
在命令行中安裝 styled-components
npm 包:
npm install styled-components
接下來,將其導入 React App:
import styled from 'styled-components'
創建一個組件並為其分配樣式屬性。請注意在 Wrapper
對象中使用反引號表示的模板文字:
import { React } from "react";
import styled from "styled-components";
function App() {
const Wrapper = styled.div`
width: 100%;
height: 100px;
background-color: red;
display: block;
`;
return <Wrapper />;
}
export default App;
上述 Wrapper
組件將被渲染為包含這些樣式的div
。
條件樣式#
styled-components
的優點之一是組件本身是功能性的,因為您可以在 CSS
中使用 props
。這為條件語句和基於state
或props
改變樣式打開了大門。
這裡是個代碼演示:
import { useState } from "react";
import styled from "styled-components";
function App() {
// display state
const [display, setDisplay] = useState(true);
return (
<>
<Wrapper $display={display} />
<button onClick={() => setDisplay(!display)}>Toggle</button>
</>
);
}
// the wrapper styled component
const Wrapper = styled.div`
width: 100%;
height: 100px;
background-color: red;
display: ${(props) => (props.$display ? "block" : "none")};
`;
export default App;
在這裡,我們操作 div
的display
屬性。此狀態由一個按鈕控制,單擊該按鈕會切換 div
的狀態。 反過來,這會在兩種不同狀態的樣式之間切換。
在內聯 if
語句中,我們使用 ?
而不是通常的 if/else
語法。 else
部分在分號之後。記住始終在初始化後調用或使用狀態。 例如,在最後一個演示中,狀態應該位於 Wrapper
組件的樣式之上。
收尾#
我們研究了幾種在 React
應用程序中編寫樣式的不同方法。並不是說一個比其他的好;當然,您使用的方法取決於具體情況。
希望現在你已經對它們有了很好的理解,並且知道你的 React
樣式庫中有一堆工具。