有一次我花了大約四十分鐘嘗試匹配 Figma 檔案中的陰影。設計師給了我一種顏色、X 和 Y 偏移量、模糊和擴展,這就是你需要的一切,但我仍然無法讓它看起來正確。瀏覽器中的陰影比模型更重、更平坦,我不斷地上下推動模糊半徑,就像這樣可以修復它一樣。
它不會,因為模型有兩個陰影堆疊在一起。用於接觸的緊密的深色層,用於環境光的寬而柔軟的層。 Figma 將它們顯示為面板中的單獨層,我已經折疊了。一旦我將它們寫成逗號分隔的對,匹配就立即生效。
這就是本指南中 CSS 屬性的問題。它們都不複雜。所有這些都有一個或兩個從語法上看不明顯的行為,你可能會因為其中任何一個而損失一個下午的時間。本指南是那些寫下來的行為。
此處連結的每個產生器都在您的瀏覽器中運行,在拖曳時更新即時預覽,並將 CSS 交給您。我在 [toolz。dev] 建立它們(/並不斷使用它們,主要是因為閱讀四值速記比查看矩形更難。
TL;DR: 使用 盒子陰影 為了深度, 文字陰影 對於發光和輪廓, 邊框半徑 對於包括橢圓形角在內的角 CSS 過濾器 用於模糊、亮度和色彩效果, 玻璃態 對於磨砂板, 新態性 對於柔軟凸起的表面, 梯度 對於背景,和 CSS單元轉換器 當您需要 px in rem 時。所有這些都在客戶端運行並提供即時預覽。值得攜帶的兩個規則:真實的陰影是分層的,並且
backdrop-filter需要背後有東西來模糊。
我需要哪台產生器?
| 你想要 | 財產 | 工具 |
|---|---|---|
| 從頁面上取下的卡片 | box-shadow |
盒子陰影 |
| 發光、勾勒或壓花文字 | text-shadow |
文字陰影 |
| 圓角或藥丸狀角 | border-radius |
邊框半徑 |
| 使元素模糊、變暗、去飽和或著色 | filter |
CSS 過濾器 |
| 照片上的磨砂面板 | backdrop-filter |
玻璃態 |
| 看起來壓在表面上的柔軟按鈕 | 分層 box-shadow |
新態性 |
| 顏色過渡背景 | linear-gradient |
梯度 |
| 將 24px 變成 rem | 沒有 | 單位轉換器 |
本指南的其餘部分是每個人所做的事情以及咬人的地方。
箱形陰影如何運作?
速記是五個值和一個顏色:
box-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.15);
/* │ │ │ │ └ colour */
/* │ │ │ └ spread: grow or shrink */
/* │ │ └ blur: 0 is a hard edge */
/* │ └ vertical offset */
/* └ horizontal offset */
偏移移動陰影。 Blur 軟化其邊緣,在每個方向上向外擴展大約一半的模糊值。在施加模糊之前,展開會增長或縮小陰影,而負展開是隱藏在元素下方而不是將其光暈的陰影的技巧。
人們錯過的部分:陰影堆疊。 以逗號分隔的清單從後到前呈現,頂部第一個陰影:
box-shadow:
0 1px 2px rgb(0 0 0 / 0.20), /* contact: tight, darker */
0 8px 24px rgb(0 0 0 / 0.12); /* ambient: wide, lighter */
這對設計師'的影子看起來比你的好。一個影子讀作貼紙。兩個讀作有重量的物體。這 盒子影子產生器 讓您添加圖層並單獨拖曳每個圖層,這是調整它們的唯一明智方法。
inset 移動邊框內的陰影,這就是獲得看起來凹進的輸入或新形態表面的內半部的方式。
一張在真實專案中讓我感到困擾的表演筆記:動畫 box-shadow 強制重新繪製每一幀。如果您想要一張卡在懸停時升起,請設定動畫 transform 並交叉淡入淡出第二個元素,該元素包含更大的陰影。這 MDN 盒陰影參考 完整記錄語法。
除了陰影之外,文字陰影還有什麼用呢?
同樣的想法,少一個價值。 text-shadow 沒有傳播:
text-shadow: 1px 1px 2px rgb(0 0 0 / 0.5);
它的有趣用途根本不是陰影。
大綱。 四個硬陰影零模糊,每個對角線一個,偽造文字周圍的一筆。它比重 -webkit-text-stroke 但它到處都有效,並且呈現字形之外而不是分割差異:
text-shadow: 1px 1px 0 #000, -1px 1px 0 #000,
1px -1px 0 #000, -1px -1px 0 #000;
發光。 零偏移、大模糊、飽和顏色,重複兩到三次以建立強度。
圖像上的易讀性。 當背景是您無法控制的照片時,白色文字下的一個柔和的暗影會為您帶來對比。它不能取代適當的稀鬆布,並且不會挽救失敗的對比度,但它可以阻止下降部分消失成明亮的斑塊。
將這三個都建立在 文字陰影產生器. 如果您正在追逐對比度要求而不是效果,請檢查結果 世界汽車協會 與 色彩對比度檢查器 而不是盯著它看。
為什麼邊界半徑取八個值?
大多數人使用一種。完整的形式是兩組,每組四組,用斜線分隔:
border-radius: 20px 40px 60px 80px / 40px 20px 80px 60px;
/* ─────horizontal──── ──────vertical───── */
斜線之前:每個角的水平半徑,從左上角順時針方向。之後:垂直半徑。給兩個角,每個角變成一個橢圓形而不是四分之一圓。這就是沒有 SVG 的有機斑點形狀的方法。
有兩種行為值得了解。
百分比針對不同的軸解析。 水平半徑為 % 是元素的百分比's 寬度,垂直的高度之一。所以 border-radius: 50% 矩形上給出的是橢圓形,而不是圓角矩形,這第一次讓人感到驚訝。
當瀏覽器重疊時,它們會向下縮放半徑。 如果兩個相鄰半徑加起來超過它們共享的一側,則所有半徑都會按比例減少,直到它們適合為止。你不能溢出形狀,這就是原因 border-radius: 9999px 可靠地生產藥丸。
的 邊框半徑產生器 使用每個角滑桿公開所有八個值,並發出最短的有效速記,這是值得擁有的,因為用手寫斜線形式確實令人不快。
CSS 過濾器可以做什麼?它們的成本是多少?
filter 將圖形操作應用於元素及其內部的所有內容:
filter: blur(4px) brightness(1.1) saturate(1.2);
函數由左到右組成,順序改變結果。先模糊再增亮與先增亮再模糊不同。
| 功能 | 做 | 留意 |
|---|---|---|
blur() |
高斯模糊 | 大半徑昂貴;向外模糊邊緣 |
brightness() |
多重輕盈 | 上面 1 個剪輯高光變白 |
contrast() |
從中灰色推送值 | 快速粉碎細節 |
grayscale() |
消除飽和度 | 比重複資產便宜 |
sepia() |
溫暖色調地圖 | 結合 hue-rotate() 對於其他色調 |
hue-rotate() |
色調改變一個角度 | 不保留感知的輕盈感 |
drop-shadow() |
跟隨阿爾法的影子 | 與 box-shadow,遵循實際形狀 |
最後一行是值得記住的一行。 box-shadow 為邊框框加陰影,因此徽標的透明 PNG 會得到矩形陰影。 filter: drop-shadow() 追蹤 alpha 通道並陰影徽標本身。
成本是真實的。過濾器將元素推到自己的合成層上,並且 blur() 尤其是在大面積範圍內價格昂貴。按鈕上很好。在低階手機的整頁覆蓋上三思而後行。 MDN's 過濾器參考 列出每個函數及其插值行為。
嘗試組合 CSS過濾器產生器,它並排顯示預覽和確切的聲明。
如何建構有效的玻璃態面板?
磨砂玻璃是這項工作的一種特性:
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
border: 1px solid rgb(255 255 255 / 0.25);
backdrop-filter 過濾什麼 後面 元素而不是元素本身。由此得出三件事,它們幾乎佔了每一個 "為什麼我的玻璃看起來像一個灰色的盒子"問題。
它背後需要一些東西。 在平坦的背景顏色上,模糊的背景是相同的平坦顏色。此效果僅存在於照片、漸層或重疊內容上。
背景必須是半透明的。 完全不透明的背景完全隱藏了模糊的背景。通常的範圍是 10% 到 25% 之間的白色。
飽和度就是它的賣點。 真正的玻璃可以集中色彩。 saturate(180%) 除了模糊之外,還有磨砂玻璃和污跡之間的差異。
添加髮際線邊框,因為玻璃有邊緣,並在發貨前檢查對比度:模糊照片上的文字會根據照片而通過或失敗,而在下一張照片上完美讀取英雄圖像的面板可能無法讀取。
的 玻璃態發生器 預覽實際圖像,這比本指南中的任何其他效果更重要。
新態性值得使用嗎?
新態性或軟 UI 使元素看起來是從背景中擠出的,而不是漂浮在背景之上。兩個陰影,相對的角落,一個比表面淺,一個較暗:
background: #e0e5ec;
box-shadow: 8px 8px 16px #a3b1c6,
-8px -8px 16px #ffffff;
將它們替換為按下的狀態或使用 inset 兩者都雕刻而成。
該技術有一個硬約束: 元素及其背景必須具有相同的顏色. 效果完全是兩個陰影,因此不同背景上的新變形按鈕會停止讀取擠壓狀態並開始讀取損壞狀態。
它還存在一個值得誠實的無障礙問題。整個美觀與結構相比對比度較低,唯一能承受的是軟陰影的按鈕可能會失效 WCAG'非文字對比度要求 對於互動式組件。如果您使用它,請為按鈕提供不依賴陰影的真實邊框或焦點樣式。
的 新態生成器 從表面顏色中獲取兩種陰影顏色,這是手工製作的繁瑣部分。
我什麼時候需要單元轉換器?
頻率比您想像的要高,因為設計工具講 px,而良好的 CSS 通常不會。
rem 與根字體大小相關,因此當使用者變更瀏覽器時,rem 中的佈局會縮放's 預設文字大小。 em 是相對於 元素's 字體大小,這使得它對於應該追蹤自己的文字的填充非常有用,並且當它複合通過嵌套元素時很危險。
算術是微不足道的。在翻譯規格時執行四十次會導致錯誤蔓延,特別是當根大小不是 16px 時。這 CSS單元轉換器 採用可設定的根並同時顯示每個單元。
對於梯度, 梯度產生器 涵蓋線性、徑向和圓錐形,並且有更長的文字 CSS 梯度指南.
將它們放在一起:一張卡片,從開始到結束
這些屬性很少單獨使用。這是一張使用其中四個的卡片,按照我建造它的方式建造。
從形狀和靜止的陰影開始:
.card {
border-radius: 12px;
background: #fff;
box-shadow:
0 1px 2px rgb(0 0 0 / 0.06),
0 4px 12px rgb(0 0 0 / 0.08);
transition: transform 150ms ease, box-shadow 150ms ease;
}
又是兩個陰影,都亮了。休息卡幾乎不能舉起。將戲劇性留給懸停狀態。
.card:hover {
transform: translateY(-2px);
box-shadow:
0 2px 4px rgb(0 0 0 / 0.08),
0 12px 28px rgb(0 0 0 / 0.12);
}
的 translateY 做了大部分感知到的工作。運動比更大的陰影更令人信服地解讀為提升,而且它很便宜,因為變換是合成的而不是重新繪製的。
如果卡片位於照片而不是平面上,請將白色背景替換為玻璃:
.card {
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
border: 1px solid rgb(255 255 255 / 0.25);
}
注意發生了什麼變化,沒有發生什麼變化。半徑和陰影保持不變。只有表面處理有所不同,這是有用的心理模型:形狀和深度是一個決定,表面是另一個決定。
瀏覽器支援和後備怎麼樣?
其中大部分都是舊的且安全的。 box-shadow, text-shadow, border-radius 和 filter 多年來一直得到各地的支持,您可以毫不猶豫地寫下來。
backdrop-filter 例外情況值得處理嗎?現在支援很廣泛,但這裡的一個屬性在缺少時會產生真正破碎的結果:具有 15% 白色背景且沒有模糊的面板是照片上的蒼白污跡。守護它:
.glass {
background: rgb(255 255 255 / 0.85); /* readable fallback */
}
@supports (backdrop-filter: blur(1px)) {
.glass {
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
}
}
後備是一個大部分不透明的面板,這不是效果,但完全可用。增強版本僅適用於瀏覽器可以交付它的情況。 MDN's @supports 參考 涵蓋語法,並且值得在任何時候訪問具有視覺上損壞的故障模式而不僅僅是更簡單的故障模式的屬性。
如何使整個專案的效果保持一致?
真實程式碼庫上的失敗模式並不是一個壞影子。它有十四個略有不同的陰影,因為每個需要卡片的人都寫自己的。
將它們定義為自訂屬性一次並使用名稱:
:root {
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.06);
--shadow-md: 0 1px 2px rgb(0 0 0 / 0.06),
0 4px 12px rgb(0 0 0 / 0.08);
--shadow-lg: 0 2px 4px rgb(0 0 0 / 0.08),
0 12px 28px rgb(0 0 0 / 0.12);
--radius: 12px;
}
.card { border-radius: var(--radius); box-shadow: var(--shadow-md); }
.card:hover { box-shadow: var(--shadow-lg); }
三個影子步驟通常就足夠了。如果您發現自己添加了第四個,通常是因為組件需要不同的組件 海拔 而不是不同的影子,答案是重複使用現有的步驟。
這也使得黑暗模式變得容易處理。在白色上工作的陰影在黑暗表面上幾乎看不見,深度通常來自較淺的邊框或微妙的光芒。重新定義媒體查詢內的令牌,每個元件如下:
@media (prefers-color-scheme: dark) {
:root {
--shadow-md: 0 1px 2px rgb(0 0 0 / 0.4);
--shadow-lg: 0 8px 24px rgb(0 0 0 / 0.5);
}
}
使用上面的工具產生每個值一次,將其貼上到令牌區塊中,然後停止思考。這就是擁有生成器的全部意義:不是寫 CSS,你不能用手寫,而是停止將注意力集中在只需要決定一次的值上。
這些影響會導致可訪問性問題
本指南中的每個屬性都操縱對比度,而對比度是輔助功能要求主要涉及的內容。四個特定的陷阱。
互動式元件需要可見的邊界。 WCAG 2.2 需要 3:1 對比 對於控制項中識別它的部分。唯一邊緣是軟陰影的按鈕可能會失效,這是新同構的結構問題,也是邊界或實心焦點環不可選的原因。
玻璃面板繼承了它們的背景's 對比度問題。 磨砂面板上的文字是否清晰,取決於其後面的照片,並且照片經常發生變化。根據你最糟糕的形象進行測試,而不是你的英雄。提高面板'背景不透明度通常比讓文字更大膽更好。
過濾器靜默地改變對比度。 brightness() 和 contrast() 應用於容器也適用於容器內的文字。 A filter: brightness(1.15) 在卡片上使其彈出可以安靜地將您的正文推到 4.5:1 閾值以下。之後檢查 色彩對比度檢查器,不是在之前。
不要讓陰影成為唯一的狀態指示器。 如果懸停、對焦和按下僅因陰影深度而異,則鍵盤使用者和任何視力低下的人都會失去差異。將陰影變化與變換、輪廓或顏色變化配對。
所有這些都不會使效果無法使用。它使它們成為需要驗證的東西而不是假設的東西,這每個組件大約需要一分鐘,並且對比度檢查器打開。
這些工具會把我的工作送到任何地方嗎?
不。這裡的每個生成器都完全在瀏覽器中運行。沒有上傳步驟,也沒有伺服器往返,這就是為什麼它們在您拖曳滑桿時會立即回應。這與目錄的其餘部分離線工作的原因相同,包含在 資料隱私指南.
常見錯誤
- 一個影子而不是兩個。 手寫陰影和設計陰影之間最明顯的區別。
- 動畫化
box-shadow懸停時。 重新繪製每一幀。動畫transform並交叉淡入淡出。 backdrop-filter純色之上。 沒有什麼可以模糊的,所以什麼也不會發生。- 玻璃面板上的不透明背景。 隱藏你剛剛寫的效果。
- 不匹配背景上的新態。 幻覺取決於它們是相同的。
border-radius: 50%期待一個圓角矩形。 在非平方元素上,您得到一個橢圓。- 運送其中任何一個都無需對比檢查。 陰影和玻璃都會降低對比度,並且在良好的顯示器上很容易過度調諧。



