CSS Protips
一個技巧合集,幫助你提升 CSS 技能。每個條目都是一個獨立的模式——選擇最適合你當前問題的來應用。
使用 CSS Reset
CSS reset 有助於強制不同瀏覽器之間的樣式一致性,為樣式元素提供一個乾淨的起點。有許多 reset 模式可以找到,或者你也可以使用更簡化的 reset 方法:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
現在元素將被剝離 margin 和 padding,而 box-sizing 讓你可以使用 CSS 盒子模型來管理佈局。
Demo
[!TIP] 如果你遵循下面的繼承
box-sizing技巧,你可能選擇不在 CSS reset 中包含box-sizing屬性。
繼承 box-sizing
讓 box-sizing 從 html 繼承:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
這使得在插件或其他利用不同行為的組件中更改 box-sizing 變得更容易。
Demo
謹慎使用 all: unset 進行組件重置
在重置元素的屬性時,你可以單獨重置每個屬性:
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}
或者使用 all 簡寫與 unset。all: unset 重置幾乎所有屬性(除了 unicode-bidi、direction 和自定義屬性)——繼承的屬性恢復為繼承值,其他屬性恢復為初始值。一個 <button> 將變成 display: inline 並失去其原生的盒子,因此在取消設置後總是恢復佈局和焦點。
button.reset {
all: unset;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
button.reset:focus-visible {
outline: 2px solid currentColor;
outline-offset: 0.15em;
}
[!TIP] 要恢復用戶代理樣式表而不是空白狀態,請使用
all: revert——請參閱現代 CSS 部分中的重置意圖:unsetvsrevert。
使用 :not() 在導航上應用/取消應用邊框
與其添加邊框...
/* 添加邊框 */
.nav li {
border-right: 1px solid #666;
}
...然後在最後一個元素上移除它...
/* 移除邊框 */
.nav li:last-child {
border-right: none;
}
...不如使用 :not() 偽類僅應用到你想要的元素:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
這裡,CSS 選擇器的讀法就像人類描述它一樣。
Demo
檢查字體是否本地安裝
你可以在遠程獲取字體之前檢查它是否本地安裝,這也是一個很好的性能提示。
@font-face {
font-family: "Dank Mono";
src:
/* 全名 */ local("Dank Mono"), /* Postscript 名稱 */ local("Dank Mono"),
/* 否則,下載它! */ url("//...a.server/fonts/DankMono.woff");
}
code {
font-family: "Dank Mono", system-ui-monospace;
}
感謝 Adam Argyle 分享這個技巧和演示。
將 line-height 添加到 body
你不需要將 line-height 分別添加到每個 <p>、<h*> 等元素。相反,將其添加到 body:
body {
line-height: 1.5;
}
這樣,文本元素可以輕鬆地從 body 繼承。
Demo
為表單元素設置 :focus
有視力的鍵盤用戶依賴焦點來確定鍵盤事件在頁面中的位置。使表單元素的焦點比瀏覽器的默認實現更突出和一致:
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus {
box-shadow: none;
outline: #000 dotted 2px;
outline-offset: 0.05em;
}
Demo
[!TIP] 在現代代碼中,優先使用
:focus-visible,這樣鍵盤用戶可以獲得清晰的焦點環,而不會在每次鼠標點擊時都顯示焦點樣式。
垂直置中任何東西
在移動設備上,優先使用帶有動態視口單元的 Grid——100vh 映射到大視口,當瀏覽器工具欄顯示/隱藏時可能會表現失常。使用邏輯屬性時,使用 100dvb(動態視口塊)。
.center-page {
min-block-size: 100dvb;
display: grid;
place-items: center;
}
一旦父元素具有定義的塊大小,Flexbox 的工作方式相同:
html,
body {
min-block-size: 100%;
}
body {
align-items: center;
display: flex;
justify-content: center;
}
[!NOTE] 舊式模式:
height: 100vh+place-items: center仍然出現在較舊的教程中。在移動設備上,對於全視口佈局,優先使用dvh/dvb/svh/lvh——請參閱 MDN 關於視口相對長度的說明。
[!TIP] 想要置中其他東西?CSS-Tricks 有一篇很好的文章介紹如何做到這一切。
Demo
使用 aspect-ratio 代替 Height/Width
aspect-ratio 屬性允許你輕鬆調整元素大小並保持一致的寬高比。這在響應式網頁設計中非常有用,可以防止佈局偏移。將其與 object-fit 一起使用,以防止在圖像的高度/寬度值更改時破壞佈局。
img {
aspect-ratio: 16 / 9; /* 寬度 / 高度 */
object-fit: cover;
}
在此 web.dev 文章 中了解更多關於 aspect-ratio 屬性的信息。
Demo
逗號分隔的列表
使列表項看起來像一個真正的逗號分隔列表:
ul > li:not(:last-child)::after {
content: ",";
}
使用 :not() 偽類,最後一個項目將不會添加逗號。
[!NOTE] 這個技巧可能不適合無障礙性,特別是屏幕閱讀器。而且從瀏覽器複製/粘貼無法處理 CSS 生成的內容。請謹慎使用。
使用負的 nth-child 選擇項目
在 CSS 中使用負的 nth-child 來選擇第 1 到第 n 個項目。
li {
display: none;
}
/* 選擇第 1 到第 3 個項目並顯示它們 */
li:nth-child(-n + 3) {
display: block;
}
或者,既然你已經學了一點關於使用 :not() 的知識,試試這個:
/* 選擇除了前 3 個之外的所有項目並顯示它們 */
li:not(:nth-child(-n + 3)) {
display: block;
}
Demo
對圖標使用 SVG
沒有理由不對圖標使用 SVG:
.logo {
background: url("logo.svg");
}
SVG 可以很好地縮放以適應所有分辨率類型,並且在所有瀏覽器中支持到 IE9。拋棄你的 .png、.jpg 或 .gif-jif-whatev 文件。
[!NOTE] 如果你為有視力的用戶提供了僅 SVG 圖標的按鈕,而 SVG 加載失敗,這將有助於保持無障礙性:
.no-svg .icon-only::after {
content: attr(aria-label);
}
使用「Lobotomized Owl」選擇器
它可能有一個奇怪的名字,但使用通用選擇器 (*) 和相鄰兄弟選擇器 (+) 可以提供強大的 CSS 功能:
* + * {
margin-top: 1.5em;
}
在此示例中,文檔流中所有跟隨其他元素的元素都將接收 margin-top: 1.5em。
[!TIP] 有關「lobotomized owl」選擇器的更多信息,請閱讀 Heydon Pickering 在 A List Apart 上發表的文章。
Demo
使用 max-height 實現純 CSS 滑塊
使用帶有 overflow hidden 的 max-height 實現僅 CSS 的滑塊:
.slider {
max-height: 200px;
overflow-y: hidden;
width: 300px;
}
.slider:hover {
max-height: 600px;
overflow-y: scroll;
}
元素在懸停時擴展到 max-height 值,並且滑塊由於溢出而顯示。
等寬表格單元格
表格可能很難處理。嘗試使用 table-layout: fixed 來保持單元格等寬:
.calendar {
table-layout: fixed;
}
無痛的表格佈局。
Demo
使用 Flexbox 擺脫 Margin Hack
在處理列間距時,你可以通過使用 flexbox 的 space-between 屬性來擺脫 nth-、first- 和 last-child hack:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}
現在列間距總是均勻分佈。
對空鏈接使用屬性選擇器
當 <a> 元素沒有文本值但 href 屬性有鏈接時顯示鏈接:
a[href^="http"]:empty::before {
content: attr(href);
}
這非常方便。
Demo
[!NOTE] 這個技巧可能不適合無障礙性,特別是屏幕閱讀器。而且從瀏覽器複製/粘貼無法處理 CSS 生成的內容。請謹慎使用。
使用 :is() 更好地控制特異性
:is() 偽類用於同時定位多個選擇器,減少冗餘並提高代碼可讀性。這對於以更緊湊的形式編寫大型選擇器非常有用。
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) {
color: green;
}
上面的規則集等同於以下數量選擇器規則...
section h1,
section h2,
section h3,
section h4,
section h5,
section h6,
article h1,
article h2,
article h3,
article h4,
article h5,
article h6,
aside h1,
aside h2,
aside h3,
aside h4,
aside h5,
aside h6,
nav h1,
nav h2,
nav h3,
nav h4,
nav h5,
nav h6 {
color: green;
}
Demo
設置「默認」鏈接的樣式
為「默認」鏈接添加樣式:
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}
現在,通過 CMS 插入的鏈接(通常沒有 class 屬性)將具有區別,而不會普遍影響級聯。
固有比例盒子(舊式回退)
[!NOTE] 僅舊式。 對於新代碼,優先使用
aspect-ratio(Baseline 廣泛可用)。僅當你必須支持非常舊的瀏覽器或需要一個早於aspect-ratio的模式時,才保留這個 padding hack。
要創建一個具有固有比例的盒子,請對一個 div 應用頂部或底部 padding:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
使用 20% 的 padding 使盒子的高度等於其寬度的 20%。無論視口寬度如何,子 div 都將保持其寬高比(100% / 20% = 5:1)。
Demo
設置損壞圖像的樣式
使用一點 CSS 使損壞的圖像更美觀:
img {
display: block;
font-family: sans-serif;
font-weight: 300;
height: auto;
line-height: 2;
position: relative;
text-align: center;
width: 100%;
}
現在添加偽元素規則以顯示用戶消息和損壞圖像的 URL 引用:
img::before {
content: "We're sorry, the image below is broken :(";
display: block;
margin-bottom: 10px;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}
[!TIP] 在 Ire Aderinokun 的文章中了解有關此模式樣式的更多信息。
全局大小使用 rem;局部大小使用 em
在根元素設置基本字體大小後(html { font-size: 100%; }),為文本元素設置 em 字體大小:
h2 {
font-size: 2em;
}
p {
font-size: 1em;
}
然後為模塊設置 rem 字體大小:
article {
font-size: 1.25rem;
}
aside .module {
font-size: 0.9rem;
}
現在每個模塊變得劃分開來,更容易設置樣式,更易於維護和靈活。
隱藏未靜音的自動播放視頻
這是一個用於自定義用戶樣式表的好技巧。避免用戶在頁面加載時被自動播放的視頻聲音淹沒。如果聲音未靜音,則不顯示視頻:
video[autoplay]:not([muted]) {
display: none;
}
再次,我們利用了 :not() 偽類。
使用 :root 實現靈活的排版
響應式佈局中的排版字體大小應該能夠隨每個視口進行調整。你可以使用 :root 根據視口高度和寬度計算字體大小:
:root {
font-size: calc(1vw + 1vh + 0.5vmin);
}
現在你可以根據 :root 計算的值使用 root em 單位:
body {
font: 1rem/1.6 sans-serif;
}
Demo
在表單元素上設置 font-size 以獲得更好的移動體驗
為了避免移動...
… [已截斷以進行翻譯]