Categories
通風報信

CSS 奇技淫巧十八招

開始覺得自己會寫 CSS 也算有一段時間了,常常遇到一些非常實用的技巧不斷地反覆使用,但是有不少是我個人覺得對初學者來說很難從樣式作用上自己發現可以如此的用法。
例如border-radius: 50% 現在已經成了大家隨手都會用來搓圓仔的標準寫法了,但我一開始也是不知道可以這樣直接設百分比從正方形變成圓形。
正好最近在教人學習 CSS ,把這些技巧整理下來分享,也方便自己備忘參考。

設定 margin 讓區塊置中

對,擺在第一個的就是大家再熟悉不過的 margin: 0 auto,為什麼列進來是因為只看 margin 的作用定義並無法得知瀏覽器會有這樣平均分配的行為,我自己一開始學的時候也完全不知道。
另外 margin 能設定負值也算是這種沒看到過會意料不到,但用起來就會覺得幸好可以如此的特性。
至於 margin-top 跟 margin-bottom 如果設定百分比的話,是以上一層的 width 為基準(padding亦同)這點就更要小心了。

用 position 作相對基準

一樣也是很基本,但是 position: absolute 會以上層中最靠近的 position: relative 區塊為基準去定位,這就我來看也有點符合上述的定義,所以一起擺進來,當然以上這兩個其實比較算是初學者教材。

用 item + item 避開第一個項目

有時候清單項目之間會用框線做裝飾分隔,例如說用 li { border-top: 1px solid black } 加上 li:first-child { border: none },但其實可以直接 li + li { border-top: 1px solid black },也是很常用。

用 border 畫三角形

直接看 Creating Triangles in CSS,常搭配在 pseudo-elements 上使用。

用 text-indent 做圖片取代

直接看 Replacing the -9999px hack (new image replacement),近兩年才開始廣為人知的新技巧。

用 counter 裝飾有序清單

搭配 pseudo-elements 來裝飾無序清單是常見的作法,至於有序清單就得用上 counter 來填入數字了,Automatic Numbering With CSS Counters 這篇有 counter 的用法介紹。

用 pseudo-elements 做 drop shadow

直接看 CSS drop-shadows without images

用 flexbox 讓 footer 置底

直接看 Sticky Footer,flexbox 帶來的新可能性之一。

用 background-attachment: local 做捲動陰影

出自 Pure CSS scrolling shadows with background-attachment: local,搭配多重背景去覆蓋做出的效果,所以缺點是不能使用透明背景。

根據內容項目總數做樣式變化

出自 Styling elements based on sibling count,我想到的用法是可以在資訊圖表上做數量級標示。另外一個我實際用過的變化技巧是用來處理最後一行排不滿的項目,像下面這樣就能做到當一行有三項,但最後一行如果不滿三項時,項目會被隱藏起來。

ul li:nth-child(3n + 1):nth-last-child(1),
ul li:nth-child(3n + 2):nth-last-child(1),
ul li:nth-child(3n + 1):nth-last-child(2) {
display: none;
}

用 pointer-event: none 讓目前選單連結失效

一般提到 pointer-event: none 都是用來做點擊穿透,但因此也有讓連結失效的作用,可以用在導覽選單的當前頁面項目上。例如:nav li.current a { pointer-event: none }

用 overflow 來清除 float

出自 Overflow – a secret benefit,可以直接參考 OOCSS 相當出名的典範:Media Object

用 text-align: justify 分散排版

在之前的那篇 CSS 分散對齊橫列選單項目有提過這個技巧,原理請看 Text-align: Justify and RWD,由於選單用 flexbox 來排版會更適合,這個方法我通常用在一左一右兩個動作按鈕這類開門式的排列上。

用 linear-gradient 作格線背景以及替代框線

參考 CSS3 Patterns Gallery 上的 Lined paper,可以搭配 background-origin: padding-box 來校正,也可以用來輔助檢測 Vertical Rhythm 。

或是搭配 calc() 用來繪製框線,可以避開使用 border 的一些限制:

background: linear-gradient(red .5em, transparent .5em, transparent calc(100% - .5em), red calc(100% - .5em));

設定 animation-delay 為負值來製造動畫系列

直接看 CSS Animation Tricks: State Jumping, Negative Delays, Animating Origin, and More,不然真的從來不知道可以使用負值。

用 :checked 狀態改造表單元素

以單選項目為例:

<input type="radio" /><label>Yes</label>
input[type="radio"] { display: none }
input[type="radio"] + label::before {
content: '';
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid black;
}
input[type="radio"]:checked + label::before { background-color: black }

還有一個常見到的用法是拿來做導覽區塊的開關按鈕,參考 Pure CSS Off-screen Navigation Menu,當然其它表單元件也可根據不同狀態做出變化。

用 :target 狀態來切換顯示

參考 Creating a modern modal with CSS ,也很常搭配 Absolute Centering in CSS 的技巧加上極大的 box-shadow 數值來做出光箱效果。

如果支援 Selector Level 4 的 Relational pseudo class 也可以搭配 visibility 來操作突顯:

#block:has(:target) {
  visibility: hidden;
}

#block :target {
  visibility: visible;
}

在多行文字上模擬 text-overflow: ellipsis

直接看CSS Ellipsis: How to Manage Multi-Line Ellipsis in Pure CSS,利用 float 區塊達成的實用技巧。

再來一個 BONUS:

單一邊緣的 box-shadow

看到 CSS Box Shadow 的最後,藉由 spread 給負值達成的效果。
除此之外,使用 inset 的內部陰影也可以做出單邊效果,

border-bottom: 1px solid #fff;
box-shadow: inset 0 -1px 0 0 #dcdcdc;

來讓特定邊緣的框線產生層次感。

以上就是目前我列出的十八招,也歡迎各位提供符合上述特點的實用技巧,希望我往後也會不斷更新這份清單。

One reply on “CSS 奇技淫巧十八招”