《css揭祕》中講了47個css技巧,其中有不少平常編碼中並不會用到,本文除了將書中部分實用技巧羅列出來以外,還嘗試用幫助讀者搞明白background
、animation
等經常使用可是卻掌握不牢固的知識點。因此閱讀本文不只能夠學習一些實用技巧,也能夠鞏固本身的 css 基礎知識。css
全名Don't Repeat Yourself
,該原則適用於全部編程語言而不限於css。html
.expand-range {
position: relative;
}
.expand-range:after {
content: '';
position: absolute;
top: -10px; right: -10px; bottom: -10px; left: -10px;
}
複製代碼
推薦使用scss:前端
@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {
position: $position;
&:after {
content: '';
position: absolute;
top: $top;
right: $right;
bottom: $bottom;
left: $left;
}
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }
複製代碼
z-index: -1
特性實現僞元素覆蓋背景同時又不會遮擋文字(具體實現原理參考這裏 )。這是一個很是經常使用又好用的技巧,善加利用能夠達到不少意想不到的效果。地址position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;
複製代碼
clip-path
clip-path
能夠實現區域裁剪,如今瀏覽器支持較好的有三個函數:clip-path: circle(50px at 50px 50px)
以 50px 50px
的地方爲圓心裁剪一個半徑 50px 的圓;clip-path: ellipse(30px 40px at 50px 50px)
以 50px 50px
的地方爲圓心裁剪一個橫向半徑 30px,縱向半徑 40px 的橢圓;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)
按照多個座標剪裁一個多邊形,此處是菱形。有了 clip-path
,就能夠輕易的實現任意多邊形了:地址border-radius
border-radius
居然能夠設置 8 個角的半徑~ 其中水平方向(對角線上下有弧度的地方)和垂直方向(對角線左右有弧度的地方)各四個,能夠用 /
分割。若是水平或垂直方向指定的值少於四個,則會按照和 margin、padding
同樣的規則重複。若是隻指定來水平方向的,那麼垂直方向的跟水平方向的同樣。border-radius: 5em 1em; /*至關於border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/
複製代碼
min-content
關鍵字display: inline-block
的包裹特性實現一個不徹底的版本:地址 這種方法的缺陷是文本脫離了文檔流,高度未計入包含塊。可是若是利用 min-content
關鍵字,能夠一行代碼實現且無反作用:地址width: min-content;
複製代碼
box-shadow
的inset
box-shadow
能夠模擬實現多重邊框,可是因爲陰影不佔空間,因此沒法觸發點擊事件,鼠標hover邊框時沒法出現小手,因此須要配合inset
關鍵字使用:地址height: 200px;
background: cyan;
box-shadow: 0 0 0 5px #000 inset,
0 0 0 10px #555 inset,
0 0 0 15px #999 inset;
複製代碼
box-shadow
box-shadow
前兩個參數指定陰影的x、y偏移量,注意若爲正數時總體向右/向下偏移,那麼相應的左方/上方會空出一部分來(能夠用來隱藏模糊半徑或擴張半徑),負數相反;第三個參數是陰影模糊半徑,即高斯模糊多增長出來的過分顏色;第四個參數是陰影擴張半徑,表示陰影增長的尺寸,能夠是負數,表示陰影縮短的尺寸:地址box-shadow: 0 5px 4px -4px black;
複製代碼
第二個參數使陰影總體下移 5px ,第三個參數使陰影四周多了 4px 的高斯模糊(注意因爲總體下移了 5px,因此此時上方仍是沒有陰影露出的),第四個參數又把陰影總體縮小了 4px,,因此左右兩邊纔沒有出現模糊半徑致使的高斯模糊陰影色,從而實現單側投影。css3
還能夠逗號分隔設置多個陰影色,好比下面的兩側投影效果:地址git
box-shadow: 5px 0 5px -5px black,
-5px 0 5px -5px black;
複製代碼
filter: drop-shadow()
box-shadow
不能透過透明背景顯示出來,不能越過僞元素/子元素顯示出來,而這些drop-shadow
能作到。(但不管哪一種投影都會被clip-path
剪裁掉~~)地址filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));
複製代碼
前端開發大都瞭解糊濾的高斯模鏡效果是filter: blur()
實現的,可是卻不多使用濾鏡的其餘幾個調色效果。filter
的值有blur()
、drop-shadow()
、url()
、brightness()
、contrast()
、grayscale()
、hue-rotate()
、invert()
、opacity()
、saturate()
、sepia()
~~可使用複合形式如:filter: sepia(1) saturate(4)
等。下面是filter屬性值大集合:地址github
餅圖的 css 實現方案很是奇怪,因此我忽略之。推薦使用 svg 的實現方案,很是簡單,先來個基本教學吧~面試
先畫個圓:編程
<svg width="100" height="100">
<circle r="25" cx="50" cy="50" />
</svg>
複製代碼
這裏 r="25"
是半徑25, cx cy
分別表示圓心的 x y
座標。segmentfault
circle {
fill: yellowgreen;
stroke: #666;
stroke-width: 50;
}
複製代碼
這裏給圓形定義了一個寬度 40 的描邊:瀏覽器
再把描邊設爲線段長度 20 間隔 10 的虛線:
circle {
...
stroke-dasharray: 20 10;
}
複製代碼
當把虛線的間隔設定爲大於等於圓周時,虛線的線段長度就是一個扇形區域(當線段長度等於圓周時扇區達到100%):
給 svg 設置圓角和背景色,並旋轉 -90deg ,就能夠實現一個餅圖:地址(使用currentColor
關鍵字和color: inherit
是爲了實現DRY原則。)
可是這樣的餅圖其扇區大小是不易計算的,爲了方便計算,可讓虛線的線段長度同時也是圓周無限接近100,這樣就能夠更方便的設置扇區的百分比。圓周是 2πr ,因此 100 = 2πr
,計算得出半徑 r 近似值 16。再利用 svg 的 viewBox 屬性,實現自適應容器大小的餅圖:地址
這種方法有個弊端,就是當設置 stroke-dasharray: 100 100
時會有一條縫,這是取近似值沒法避免的。
background
background
是咱們最經常使用的屬性之一,但做爲一個老前端,我也只能羞恥的說我目前並無徹底掌握這個屬性。
background
是一個簡寫屬性,能夠包括多個屬性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment
。接下來咱們一個個來看看這些屬性的做用:
background-color
最經常使用的屬性,默認不繼承(background
的全部屬性都默認不繼承),初始值爲 transparent
;有時候使用默認繼承能夠實現一些好玩的效果,好比倒影;backgroundo-image
背景圖片,能夠逗號分割設置多個,能夠是圖片url或者漸變色;background-clip
背景剪裁,能夠逗號分割設置多個,值能夠爲 broder-box
(初始值)、padding-box
、content-box
、text
(新,將背景被文字剪裁);background-origin
設置背景起始點的相對區域,搭配 background-position
使用,能夠逗號分割設置多個,值能夠是border-box
、padding-box
(初始值)、content-box
;background-position
設置背景的起始點,能夠逗號分割設置多個,值能夠是 10px 20px
、center center
、left 10px bottom 20px
等等,很是靈活;background-size
設置背景的大小,能夠逗號分割設置多個,值能夠是數字值如30px 40px
、auto auto
(初始值)、conver
、contain
;background-repeat: repeat
就是根據這個尺寸大小來重複的。background-repeat
設置背景的重複方式,初始值爲 repeat
,常使用值的還有no-repeat
;background-attachment
設置背景圖像的位置是在視口內固定,仍是隨着包含它的區塊滾動。能夠逗號分割設置多個,值有scroll
(初始值)、local
、fixed
。詳情查看MDN簡寫時 background-size
只能緊接着 background-position
出現,以 / 分割,如: "center / 80%"。
background-clip
background
屬性默認會覆蓋整個盒模型包括邊框border
,因此設置border-color: rgba(0, 0, 0, .5)
時會透出背景色,達不到半透明邊框的效果。css3增長了background-clip
屬性,定義背景填充的裁剪區域。設置padding-box
即可以實現半透明邊框:地址border: 10px solid rgba(255, 255, 255, .5);
background: white;
background-clip: padding-box;
複製代碼
backgrond-position
background-origin
background-position
能夠定位背景圖片等位置,可是都是相對padding-box
的左上角開始等。css3 容許這樣寫:background-position: right 10px bottom 20px
,同時 css3 還支持background-origin
,其默認值如同其表現border-box
,支持設爲padding-box
和content-box
:地址height: 200px;
padding: 10px;
border: 5px solid cyan;
background: lightblue;
background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;
background-origin: content-box;
複製代碼
background-position
設爲百分比值較爲複雜。百分比值實際上執行了如下的計算公式:
(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)
複製代碼
由計算公式可知:當值爲0%時,實際偏移值爲0px,此時圖片的左邊界(或上邊界)和容器的左邊界(或上邊界)重合;當值爲50%時,實際偏移值爲容器減圖片剩餘空間的一半,圖片左右邊界(或上下邊界)距離容器左右邊界(或上下邊界)相等,此時圖片的中點和容器的中點重合。當值100%時,實際偏移值爲容器減圖片的剩餘空間,因此此時圖片的右邊界(或下邊界)和容器的右邊界(或下邊界)重合。兩者之差爲負值時一樣有效。地址
background-image
lienar-gradient
的第一個參數是漸變的角度,能夠是方向關鍵字to top
(初始值,可忽略不寫)等,也能夠是角度90deg
等;#fb3 50%
指的是色標和終點位置值;這裏linear-gradient
的第二個位置值設置爲0會被解析爲前一個色標的位置值即50%,這樣寫更加符合DRY
原則。background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;
複製代碼
也能夠設置爲垂直條紋背景:
background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;
複製代碼
還能夠設置爲斜向條紋:
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
複製代碼
斜向條紋須要設置四條條紋才能在平鋪到時候作到無縫拼接。
更好的斜向條紋:(這裏必須設置起始值#fb3 0
)
background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);
複製代碼
background-image
、background-size
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),
linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;
複製代碼
更好的網格:
background: #58a;
background-image: linear-gradient(white 2px, transparent 0),
linear-gradient(to right, white 2px, transparent 0),
linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),
linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;
複製代碼
background-image
、background-size
、background-position
background: #eee;
background-image:
linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),
linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
複製代碼
到這裏 background
屬性基本講完了,光看無用,多動手實踐吧。
background:
radial-gradient(tan 30%, transparent 0),
radial-gradient(tan 30%, transparent 0);
background-color: #666;
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
複製代碼
clip-path
、徑向漸變clip-path
均可以輕鬆實現,可是對於圓形的切角,使用徑向漸變是最好的選擇。可是若是有弧形的切角呢?radial-linear
第一個參數指定漸變的起始點點(默認爲中心點),同時可指定漸變類型是橢圓仍是圓;地址background:
radial-gradient(circle at top left, transparent 15px, blue 0) top left,
radial-gradient(circle at top right, transparent 15px, cyan 0) top right,
radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,
radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
複製代碼
background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);
複製代碼
animation
animation
屬性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state
屬性的一個簡寫屬性形式。
animation-name
指定動畫的名稱,能夠逗號分割設置多個(如下皆可);animation-duration
指定動畫運行的時間;animation-delay
指定動畫執行前的延時;animation-timing-function
指定動畫執行的速度函數,如linear
、ease
(默認)、ease-in-out
等,也可用貝塞爾函數cubic-bezier()
;animation-iteration-count
指定動畫的運行的次數,默認爲1,能夠爲Infinite
無限次;animation-direction
指定動畫是否反方向播放,normal
正常的順序,alternate
交替運行,reverse
反向運行,alternate-reverse
反向交替運行;animation-fill-mode
設置CSS動畫在執行以前和以後的樣式,none
不設置,forwards
保留最後一幀動畫的樣式,backwards
當即應用第一個關鍵幀中定義的值,並在animation-delay期間保留此值,both
同時應用forwards
和backwards
的規則;animation-play-state
定義一個動畫是否運行或者暫停,值爲running
、paused
。如何給動畫加上回彈效果呢?這裏介紹一種最便利的方法:
cubic-bezier(x1, y1, x2, y2)
上圖圖橫軸爲時間,縱軸爲動畫進度。圖中貝塞爾曲線有兩個控制手柄,x1, y1
控制第一個錨點,x2, y2
控制第二個錨點。其中 x1 、x2
不能大於/小於 1,可是y1, y2
能夠。當 y2
大於 1 時,就會產生提早到達終點,而後超過終點,而後再返回終點的效果,像回彈同樣。地址
animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);
複製代碼
transition
屬性是 transition-property、transition-duration、transition-timing-function、transition-delay
的一個簡寫屬性。使用 transition
一樣能夠實現回彈效果:地址
p {
transform-origin: 1.4em -.4em;
transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}
input:not(:focus) + p {
transform: scale(0);
transition: transform 300ms; /*此處是爲了縮小時重置transition-timing-function,不觸發回彈*/
}
複製代碼
animation
、background-position
background-position
設爲100% 0%
,動畫便會將背景位置從最初的0% 0%
向最後的100% 0%
過分:地址div {
width: 150px; height: 150px;
background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');
background-size: auto 100%;
animation: panoramic 10s linear infinite alternate;
}
div:hover {
animation-play-state: paused;
}
@keyframes panoramic {
to { background-position: 100% 0; }
}
複製代碼
animation
transform-origin
transform-origin
爲大圓容器中心點,同時利用兩個元素在向不一樣方向旋轉時旋轉角度互相抵消的原理,實現圖像沿環形路徑旋轉同時保持自身角度的不變。注意小圓距離大圓的距離由大圓的padding
屬性控制,調整padding
時須要調整小圓的旋轉原點transform-origin
以保持環形路徑的正確:地址@keyframes spin {
to { transform: rotate(1turn); }
}
.avatar {
animation: spin 3s linear 2s infinite;
transform-origin: 110px 110px;
}
.avatar > img {
animation: inherit;
animation-direction: reverse;
}
複製代碼
其實如今社區已經不乏介紹 css 技巧的好文,這裏推薦幾篇我以爲寫的極好的css技巧文章(固然可能你們也看過,很慚愧我其實如今也沒看完):
整體來講,《css揭祕》這本書並無給我帶來太大驚喜,我的感受不如閱讀《css世界》帶來的收穫多。固然了,這本書屬於純技巧型的,並無講述不少原理知識,因此也不能苛責吧。有興趣的同窗能夠跟着我學習一波 css世界,相信確定會有更大的收穫~