些情況下,我需要用一種簡單的方法來創建網格布局。例如,每次我改變主意時,在不修改CSS的情況下快速畫出五列網格。在本文中,我們一起探索一些用例,并思考如果實現及使用它們。
在深入探討這些概念之前,首先我們來回顧一下 CSS 變量的基礎知識, 我們也可以將它稱為“自定義屬性”。
所有主流瀏覽器都支持CSS變量,下面是各個瀏覽器的支持情況:
如果要定義CSS變量是全局變量,則需要將其添加到:root聲明中(:root等效于<html>)。如果該變量特定于組件,則可以在該組內聲明中定義它。
在下面的例子中,我定義了一個全局變量--size,它用于square 元素的寬度和高度。
:root {
--size: 50px;
}
.square {
width: var(--size);
height: var(--size);
}
如果--size沒有定義,要怎么辦呢?在傳遞的變量無效的情況下,CSS 支持定義默認變量或回退變量。
在下面的例子中的 var(--size, 10px)。如果--size無效,則寬度和高度值將為10px。
.square {
width: var(--size, 10px);
height: var(--size, 10px);
}
除此之外,還可以在內聯CSS樣式中使用CSS變量。例如
HTML
<div class="elem" style="--background: red;"></div>
CSS
.elem {
background: var(--background);
}
接著, 我們以上述這些概念,還演示一些事例。
在此設計中,我將CSS網格用于以下各項:
側邊欄的寬度是固定的,主內容是變化。假設側邊欄的寬度是240px。
1.邊欄和主菜單
Html
<div class="o-grid" style="--columns: 240px 1fr">
<aside></aside>
<main></main>
</div>
Html
.o-grid {
display: grid;
grid-template-columns: var(--columns);
}
2. 表單項
按照設計,每行有兩列,html 結構如下:
Html
<div class="o-grid" style="--columns: 1fr 1fr">
<div class="form-group"></div>
<div class="form-group"></div>
<div class="form-group"></div>
<div class="form-group"></div>
</div>
CSS
.o-grid {
display: grid;
grid-template-columns: var(--columns);
}
3. 三列布局
在下面的示例中,我添加了--repeat-number:3和--gap:8px作為內聯CSS。這些變量將添加到o-grid類,網格的設置將基于這些變量。
HTML
<div class="o-grid" style="--repeat-number: 3; --gap: 8px;">
<div></div>
<div></div>
<div></div>
</div>
CSS
.o-grid {
display: grid;
grid-template-columns: repeat(var(--repeat-number), 1fr);
grid-gap: var(--gap, 0);
}
我喜歡在CSS變量中添加默認值,以防變量沒有被設置。在上面的代碼中,我使用了var(--gap, 0),如果使用者沒有提供--gap變量,則其默認值將為0。
對我來說,這是一個廣泛使用的用例,并且非常重要。我經常使用Grid minmax,但是當我在多個頁面上使用它時,我遇到了一個問題。
讓我們舉一個不使用 CSS 變量的基本示例。
在 CSS 中,我使用minmax為每個網格項目定義最小寬度250px。
CSS
.o-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr);
grid-gap: 16px;
}
現在,如果設計要求網格項目的寬度至少為300px,應該怎么做?我需要創建類似以下版本嗎?
.o-grid--2 {
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
}
想象一下,有五個不同的網格,每個網格具有不同的項目寬度,所以以上不是正確的解決方案。
使用CSS變量,我可以執行以下操作
.o-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--item-width), 1fr);
grid-gap: var(--gap);
}
在HTML中,就可以在標簽上設置 CSS 變量:
<!-- Example 1 -->
<div class="o-grid" style="--item-width: 250px;">
<div></div>
<div></div>
<div></div>
</div>
<!-- Example 2 -->
<div class="o-grid" style="--item-width: 350px;">
<div></div>
<div></div>
<div></div>
</div>
<!-- Example 3 -->
<div class="o-grid" style="--item-width: 150px;">
<div></div>
<div></div>
<div></div>
</div>
事例源碼:https://codepen.io/shadeed/pen/7d3e0d575a5cecb86233fc7d72fa90d4
在示例中,有一個文章標題,其中包含作者姓名和標簽。這些在頁面中的排布方式是動態變化,所以需要一種快速切換這些布局方式的方法 。
HTML
<div class="article-header">
<h2>Article title</h2>
<div class="article-header__meta" style="--justify: space-between;">
<p>By Ahmad Shadeed</p>
<p>Published under: CSS, Design</p>
</div>
</div>
CSS
.article-header__meta {
display: flex;
justify-content: var(--justify);
}
有了它,我可以調整內聯樣式以將值更改為另一個關鍵字。我發現這在進行快速原型制作甚至是制作網站時很有用。
CSS 變量也適用于按鈕元素。假設有一個帶有兩個input字段和一個按鈕的表單。
我的目的是通過使用內聯CSS變量來控制按鈕的寬度。有時,按鈕應占據其父控件的100%寬度。
html
<button class="c-button" style="--width: 100%;">Submit</button>
css
.c-button {
/* Other styles */
width: var(--width, initial);
}
另一個有用的用途是當有重影按鈕(輪廓按鈕)時。按鈕的顏色可以是任何顏色,通過使用CSS變量,可以輕松更改顏色。
HTML
<button class="c-button c-button--ghost" style="--color: #5e35b1;">Save Edits</button>
<button class="c-button c-button--ghost" style="--color: #ec2828;">Delete</button>
CSS
.c-button--ghost {
/* Other styles */
background: transparent;
color: var(--color, #000);
border-color: currentColor;
}
CSS 變量同樣適合懸停效果。懸停時,按鈕背景將變為純色,并且字體顏色為白色。
事例源碼:https://codepen.io/shadeed/pen/f8e6969d5145d4dcd81aacf7a037c995
每個角色的大小都不同,這非常適合用 CSS 變量來解決。假設有四個不同大小的用戶頭像。
在CSS中,定義了以下樣式:
.c-avatar {
display: inline-block;
margin-right: 2rem;
width: calc(var(--size, 1) * 30px);
height: calc(var(--size, 1) * 30px);
object-fit: cover;
border-radius: 50%;
box-shadow: 0 3px 10px 0 rgba(#000, 0.2);
}
通過使用Calc()函數,我可以傳遞一個--size 變量,它將乘以一個基本寬度值,在HTML中定義 --size變量:
<img src="user.jpg" alt="" class="c-avatar" style="--size: 1">
<img src="user.jpg" alt="" class="c-avatar" style="--size: 2">
<img src="user.jpg" alt="" class="c-avatar" style="--size: 3">
<img src="user.jpg" alt="" class="c-avatar" style="--size: 4">
事例源碼:https://codepen.io/shadeed/pen/cdaac5ff667e1f7d9c8241655441f10d
人才們的 【三連】 就是小智不斷分享的最大動力,如果本篇博客有任何錯誤和建議,歡迎人才們留言,最后,謝謝大家的觀看。
作者:Ahmad shaded 譯者:前端小智 來源:sitepoint
原文:https://css-tricks.com/patterns-for-practical-css-custom-properties-use/
家好,在本篇文章中,我們將深入了解JavaScript變量的方方面面。無論你是初學者還是有一定經驗的開發者,本文都將為你揭開JavaScript變量的奧秘,讓你輕松掌握這門重要的編程語言。
在JavaScript中,變量是存儲數據的容器,它們允許你在程序中存儲和操作各種類型的值。使用變量可以使你的代碼更加靈活和可維護,因為你可以在程序中多次使用同一個值,而不需要重復輸入。通俗的理解變量就是使用【特定符號】來代表【特定數據】。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>變量</title>
</head>
<body>
<script>
x = 1
y = 2
// x和y兩個符號分別表示了數字1和2
//舉例:使用變量記錄數據
// 將用戶輸入的內容保存在 num 這個變量(容器)中
num = prompt('請輸入一數字!')
// 通過 num 變量(容器)將用戶輸入的內容輸出出來
alert(num)
document.write(num)
</script>
</body>
</html>
要使用變量,首先需要聲明它。在JavaScript中,有三種聲明變量的方式:使用var、let和const關鍵字。這些關鍵字的選擇取決于變量的作用域和是否允許重新賦值。
關鍵字也叫保留字,是 JavaScript 中內置的一些英文詞匯(單詞或縮寫),它們代表某些特定的含義。以下是JavaScript常見的一些關鍵字。
case else new var
catch export return void
class extends super while
const finally switch with
continue for this yield
debugger function throw
default if try
enum await implements protected
interface public package static
import from as
這些關鍵字在JavaScript的語法中有特定的用途,例如:
聲明變量:關鍵字+變量名
賦值:變量名 = XX數據
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>變量聲明和賦值</title>
</head>
<body>
<script>
// 聲明(定義)變量有兩部分構成:聲明關鍵字、變量名(標識)
// let 即關鍵字,所謂關鍵字是系統提供的專門用來聲明(定義)變量的詞語
// age 即變量的名稱,也叫標識符
let age
// 賦值,將 25 這個數據存入了 age 這個“容器”中
age = 25
// 這樣 age 的值就成了 25
document.write(age)
// 也可以聲明和賦值同時進行
let str = '你好,謐夜星球!'
alert(str);
</script>
</body>
</html>
作用域:
變量提升:
變量重復聲明:
可變性:
全局對象屬性:
初始化:
適用場景:
綜上所述,let 和 const 是在現代 JavaScript 中更常見和推薦的變量聲明方式,可以更好地控制作用域、避免一些潛在問題,并提高代碼的可讀性和可維護性。
在命名變量時,需要遵循一些規則:
變量的作用域指的是變量在代碼中的可訪問范圍。JavaScript中有兩種主要的作用域:全局作用域和局部作用域。
概念:使用 const 聲明的變量稱為“常量”。
使用場景:當某個變量永遠不會改變的時候,就可以使用 const 來聲明,而不是let。
命名規范:和變量一致
const PI = 3.14
注意: 常量不允許重新賦值,聲明的時候必須賦值(初始化)
本文深入介紹了JavaScript變量的各個方面,從聲明變量到變量的作用域、命名規則以及使用方法等。通過學習這些基礎知識,你將能夠更好地理解和運用JavaScript變量,為你的編程之路鋪平道路。
希望本文能夠幫助你更深入地理解JavaScript變量,讓你在編程的旅程中游刃有余。如果你有任何關于JavaScript變量的疑問,歡迎在評論區提出,我將竭誠為你解答!
感謝閱讀本文,希望能夠對你有所幫助。記得點贊、分享!持續更新中!
自 IOS 13.0 支持深色模式 (DarkMode) 后,多主題逐漸流行起來,用戶可以手動或自動切換到自己喜歡的主題色,本篇文章詳細介紹下前端頁面如何實現多主題適配。
Mac 系統支持的淺色和深色主題示意圖:
在具體實施多主題方案之前,首先要了解兩個問題
?? 為什么會出現深色模式?
?? 我應該去實施深色主題的適配嗎?
相關研究調查數據顯示,超過 80% (在 Mac 上,而不是在 iOS 上,但這給出了一個趨勢),盡管這個數字可能被高估了,但這意味著有很大比例的人在使用它。所以對于使用深色模式的用戶來說,切換到不支持的應用真的很不爽,他們很可能會為此刪除掉應用或關掉頁面。
多主題成為用戶體驗提升基本手段,現在化前端都應該支持此場景,接下來會深入講解多主題在 WEB 場景中如何適配。
瀏覽器基于操作系統支持淺色深色兩種風格,但是前端頁面的多主題需要開發者具體開發才可以實現主題切換。
做具體實現之前,了解下系統層次支持暗黑模式的支持情況:
在現代化設備中,系統層都支持了深色和淺色主題,所以無論是新項目還是已經跑了多年的老項目都應該去做這件事。
頁面基本是由自定義樣式 + UI庫來呈現整體視覺。 先從自定義樣式說起:自定義樣式使用CSS變量控制多主題(CSS變量基本使用在此不再過多贅述,入門請參考阮一峰老師寫的CSS 變量教程)
<!-- html 節點添加主題自定義屬性 -->
<html data-theme="light">
<!-- 使用CSS變量控制樣式 -->
<body style="background: var(--body-background)"></body>
</html>
// 跟主題無關的變量放到root里
:root {
--border-radius-base: 6px;
}
// 跟主題相關變量,通過屬性選擇器提升優先級
html[data-theme='default']:root {
--body-background: #efefef;
}
html[data-theme='dark']:root {
--body-background: #000;
}
開源社區提供的UI庫主題適配方案比較流行的就是通過CSS變量,但是由于CSS變量形成規范較晚,所以較老的項目是不支持的。Vue 的 Element UI 和 React 的 Ant Design 是社區發展較好的兩個 UI 庫,因為項目較老的原因都不支持CSS變量主題方案。
拿Ant Design來說,內部實現多主題是通過定義 less 變量,這樣的做法是無法動態切換主題(下面會具體討論動態切換主題)
Ant Design 目前正在著手將所有組件支持CSS變量,詳細進展可以參考這里。
但是我們不能等官方支持后在著手做適配工作,需求不等人,以 antd 為例,適配淺色和深色主題目前可以通過分別構建不同主題樣式,通過添加屬性選擇器前綴來控制antd樣式的優先級,以達到適配主題的目的。
<html data-theme="light"></html>
html[data-theme='light'] .ant-button {color: #fff}
html[data-theme='dark'] .ant-button {color: #000}
頁面切換主題具體需要從下面三個維度來考慮:
切換主題的核心思路是通過控制CSS變量,在不同主題下顯示不同的樣式。
?? 系統主題切換
瀏覽器暴露主題切換接口:
CSS | 媒體查詢 @media(prefers-color-scheme: dark) |
JavaScript | window.matchMedia("(prefers-color-scheme: dark)") |
api支持程度:
???? 通過CSS媒體查詢控制CSS變量:
body {
background: var(--body-background);
transition: background 0.3s;
}
@media (prefers-color-scheme: light) {
:root {
--body-background: #efefef;
--text-color: #333;
}
}
@media (prefers-color-scheme: dark) {
:root {
--body-background: #000;
--text-color: #ededed;
}
}
優點是實現簡單,識別交給瀏覽器去做,簡單頁面直接使用這個方案即可。
缺點是不利于擴展,后續支持用戶主動切換主題比較乏力,所以我們下面按照屬性選擇器加CSS變量實現控制。
???? 通過JS暴露接口:
通過JS識別當前系統主題,對于CSS變量的控制不應該使用JS去寫,因為當主題色多的話,需要對每個屬性都執行這行代碼:
document.documentElement.style.setProperty('--theme-color', '#YOURCOLOR');
JS控制CSS變量不利于后續擴展。
較合適的方案是上面提到的:通過屬性選擇器控制根節點CSS變量
/* 淺色模式 */
html[data-theme="light"]:root {
--body-background: #efefef;
--text-color: #333;
}
/* 深色模式 */
html[data-theme="dark"]:root {
--body-background: #000;
--text-color: #ededed;
}
JS通過識別系統主題,設置頁面主題標識
// 給HTML DOM節點添加自定義主題,標識當前主題
const toggleTheme = (isDarkMode) => {
htmlEl.setAttribute("data-theme", isDarkMode ? "dark" : "light");
};
const themeMedia = window.matchMedia("(prefers-color-scheme: dark)");
// 頁面初始化切換
toggleTheme(themeMedia.matches);
// 監聽系統切換
themeMedia.addListener((e) => {
toggleTheme(e.matches);
});
?? 頁面提供切換按鈕,用戶主動切換
需要在html節點添加自定義屬性,并根據當前主題色通過CSS變量控制。
點擊切換按鈕后設置自定義屬性值即可。
/* 淺色模式 */
html[data-theme="light"]:root {
--body-background: #efefef;
}
/* 深色模式 */
html[data-theme="dark"]:root {
--body-background: #000;
}
body {
background: var(--body-background);
transition: background 0.3s;
}
const htmlEl = document.documentElement;
const buttonEl = document.getElementById("btn");
buttonEl.addEventListener("click", () => {
const currentTheme = htmlEl.getAttribute("data-theme");
const nextTheme = currentTheme === "dark" ? "light" : "dark";
htmlEl.setAttribute("data-theme", nextTheme);
});
?? 通過URL控制當前主題
頁面加載后根據URL query參數動態添加到html節點自定義屬性,并根據當前主題色通過CSS變量控制。
const search = new URLSearchParams(location.search);
const theme = search.get("theme") || "light";
document.documentElement.setAttribute("data-theme", theme);
上面三種場景結合起來,基本滿足目前多主題所有需求。
在線DEMO: codesandbox.io/s/multiple-…
如果項目中沒有使用UI庫或使用了支持CSS變量主題適配的UI庫,可以本章內容,請直接參考上面技術方案探索。
根據上面「多主題技術方案探索」結論,我們從「UI庫適配」和「自定義樣式適配」來介紹下頁面如何從0到1實現多主題適配。
先放一張最終實現效果圖,源碼已放到 github 倉庫,有條件的看官可以邊看源碼,邊閱讀下面的示例代碼
基于Ant Design具體講UI庫如何實現多主題方案。對于其他不支持的UI庫(Element UI等等),實現的思路大致相同。
共分為三個步驟:
通過配置深色和淺色兩套主題文件,分別對需要自定義樣式的less變量賦值。最終構建兩套主題樣式,分別加上屬性選擇器前綴。
# 文件目錄結構
.
├── src
│ └── theme
│ ├── antd.css # 構建產物
│ ├── antd.custom.variable.less # 自定義antd less變量
│ ├── antd.dark.base.less # 自定義 antd 深色主題
│ ├── antd.light.base.less # 自定義 antd 淺色主題
│ ├── antd.less # 構建入口文件
└── theme.sh
構建兩套樣式無疑增加了構建產物大小,最終構建兩套樣式文件大小約為1.4M,gzip后300K左右。
如果你的項目是剛啟動并且比較小,可以使用支持CSS變量的UI庫。
如果項目預期會很龐大,而且希望使用antd周邊生態比較完善的庫,那么我建議你做這件事情。
?? 配置多主題樣式
antd.custom.variable.less 自定義antd less變量文件
為什么要單獨設置一份antd的less變量設置,由于上面提到過的:antd作為老項目基本都支持CSS變量,主題方案是通過less變量實現的,所以我們要自己設置不同主題的less變量。
@live-primary-color: #ff0040;
// default
@live-body-background: #efefef;
@live-text-color: #666;
// dark
@live-body-background-dark: #000;
@live-text-color-dark: #bfbfbf;
antd.dark.base.less 自定義 antd 深色主題
@import './antd.custom.variable.less';
@import '../../node_modules/antd/lib/style/themes/dark.less';
@import '../../node_modules/antd/dist/antd.less';
// 覆蓋antd less變量值
@primary-color: @live-primary-color;
@body-background: @live-body-background-dark;
antd.light.base.less 自定義 antd 淺色主題
@import "./antd.custom.variable.less";
@import "../../node_modules/antd/lib/style/themes/default.less";
@import "../../node_modules/antd/dist/antd.less";
// 覆蓋antd less變量值
@primary-color: @live-primary-color;
@body-background: @live-body-background;
構建:分別構建淺色和深色主題
# '編譯暗黑主題樣式'
npx lessc --js ./src/theme/antd.dark.base.less ./src/theme/antd.dark.base.css
# '編譯白色主題樣式'
npx lessc --js ./src/theme/antd.default.base.less ./src/theme/antd.default.base.css
構建產物:antd.dark.base.css antd.default.base.css
?? 自定義UI庫樣式
variable.css 自定義CSS變量
此文件用于自定義樣式和UI庫樣式的CSS變量合集
:root {
--live-primary-color: #ff0040;
--live-font-size-base: 14px;
--live-font-size-lg: 16px;
--live-font-size-sm: 12px;
}
html[data-theme="default"]:root {
--live-body-background: #efefef;
}
html[data-theme="dark"]:root {
--live-body-background: #000;
}
ant.less 自定義UI庫樣式文件
@import (less) "./variable.css";
html[data-theme="default"] {
@import (less) "./antd.default.base.css";
}
html[data-theme="dark"] {
@import (less) "./antd.dark.base.css";
}
html[data-theme="dark"],
html[data-theme="default"] {
.ant-btn {
font-size: var(--font-size-lg);
&-lg {
font-size: 18px;
}
&-sm {
font-size: var(--font-size-base);
}
}
}
構建:給淺色和深色分別添加作用域,并加入自定義UI樣式。
因為我們整體的切換主題要結合html標簽的自定義屬性 data-theme 的值為 light 或 dark 來實現,所以要結合構建的淺色和深色的的兩份主題文件添加作用域。
npx lessc --js -clean-css ./src/theme/antd.less ./src/theme/antd.css
構建產物: antd.css ,在項目head標簽中引入,就完成了UI庫的主題適配。
因為「UI庫主題適配實現」中,variable.css設置了CSS變量,所以自定義樣式的節點上直接使用var(CSS變量)即可。
<div style="color: var(--text-color)"></div>
本篇文章重點講「不支多主題的UI庫」適配,相信未來所有的UI庫都會支持CSS變量實現多主題切換,目前antd正在做這件事,等完全支持后,多主題適配需要關心的是自定義UI庫樣式和自定義樣式主題適配。
如果你有更好的主題適配方案,歡迎一起討論。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。