《CSS揭秘》读书笔记
摘要
《CSS揭秘》主要是介紹了使用CSS的技巧,通過47個案例來靈活的使用CSS進行實現,同時在實現過程中注重CSS代碼的靈活性與健壯性。通過閱讀這本書有利于我們編寫高質量的CSS代碼以及打破使用CSS時的固定思維,能夠更加靈活的使用CSS。
《CSS揭秘》中的所有案例代碼均上傳到:play.csssecrets.io/。
關于《CSS揭秘》的讀書筆記主要是記錄通過閱讀書中的CSS案例所獲得啟發和對CSS樣式新的認知點。
第二章 背景與邊框
background-clip
background-clip屬性設置元素的背景(背景圖片或顏色)覆蓋到什么位置。
屬性值為:border-box(默認值) | padding-box | content-box | text
注:text屬性值是設置將背景被裁剪為文字的前景色(chrome瀏覽器支持需要添加-webkit-前綴;最新版本的火狐瀏覽器 [ 63.0.3 (64 位) ]直接支持background-clip: text 屬性)。
background-origin
background-origin規定了指定背景圖片background-image屬性的原點位置的背景相對區域。
屬性值為:border-box | padding-box(默認) | content-box
多重邊框
傳統做法:通過多重元素嵌套來生成多重邊框。
新的思路:
方法一:通過box-shadow的第四個參數可以讓投影面積增大或者縮小,設置box-shadow: 0 0 0 10px #809;得到的“投影”其實就像一道實線邊框,并且box-shadow支持逗號分割法,因此我們可以創建任意數量的投影。
缺點:邊框的樣式單一,只能夠是實線邊框。
方法二:通過outline描邊屬性來設置第二重邊框
缺點:只能夠適用于兩重邊框(border一重,outline一重),并且outline的描邊不能夠貼合border-radius的圓角,只能夠是矩形。
背景圖片的靈活定位
傳統做法:通過計算元素的大小,設置background-position的位置。
新的思路:
方法一:background-position屬性模式是通過左上角進行定位的,可以隨機指定距離任意角的偏移量,background-position:left 20px top 30px;
方法二:通過calc()函數來實時計算background-position的位置,background-position: calc(100% - 20px) calc(100% - 30px);
方法三:可以通過background-origin:content-box,使得background-position以內容區的左上角作為基準,圖片距離邊角的偏移量等于內邊距。
邊框內圓角(矩形容器,內側有圓角)
傳統做法:通過兩個div嵌套,內部的div設置為圓角,外部的div保持矩形邊框形狀。
新的思路:outline屬性結合box-shadow屬性。
1、通過outline可以為border-radius描邊,但是描邊為矩形,與圓角之前存在空白縫隙,通過box-shadow可以填充縫隙。
2、需要填充的縫隙大小為,圓角半徑為r,圓心到描邊頂角的距離為√2 r,因此填充的距離為(√2 - 1)r
缺點:因為box-shadow的寬度至少需要設置為(√2 - 1)r,如果描邊的寬度小于這個值,那么描邊將會被box-shadow遮住。
linear-gradient()
linear-gradient()函數創建一個漸變“圖像”
函數內容為:linear-gradient(direction, colorItem1,colorItem2...)
1、角度設置是根據時鐘順時針進行計算的;
2、下一個顏色開始位置與上一個顏色的結束位置一致,則不需要填充顏色之間空余的位置,形成不同的顏色條而非過渡條;
3、當后面顏色位置小于前面顏色位置時,瀏覽器之間將后面顏色位置更正為與前面顏色位置一致。
repeating-linear-gradient()
repeating-linear-gradient()創建一個重復線性漸變的“圖像”
函數內容為:repeating-linear-gradient(direction, colorItem1,colorItem2...)
每次重復時,色標位置的偏移量都是基準漸變長度(最后一個色標和第一個之間的距離)的倍數,因此要設置開始處(0位置)的顏色。
條紋背景
傳統做法:通過兩種顏色進行設置
新的思路:
方法一:首先通過background-color設置背景色,然后通過background-image:linear-gradient(rgba(0,0,0,0.2) 50%,transparent 50%);以及background-size:auto 2em;創建一個“黑白條”蓋在上面并且高度為2em(1em代表為1行)。
方法二:通過linear-gradient()直接設置兩種顏色,然后設置background-size 大小,根據background直接復制平鋪。
方法三:通過repeating-linear-gradient()直接設置顏色自動重復。
錯落相間的背景圖案
1、通過設置兩個linear-gradient(),然后各自設置其background-position,來使的背景圖案錯落開來。
2、矩形的背景圖案,可以通過linear-gradient()45deg的創建2個直角三角形拼接而成。
帶有圖案的邊框
傳統做法:通過創建兩個div,外層的div設置背景圖片,內層的div在背景圖片上覆蓋一層白色背景色,兩層之間的差距就形成了圖案邊框。
新的思路:
1、background可以設置多個背景,但是白色背景色會默認在最底層,無法上浮到圖片上方,所以白色背景色通過線性漸變來實現,并且將背景圖片的鋪蓋范圍設置為border-box。
2、background-origin默認值是padding-box,因此圖片默認是放置在padding-box的原點上,然后通過平鋪復制蔓延到border-box,因此border區域的圖片顯示異常,所以要將border-origin設置border-box。
注:除了圖片之外還可以通過漸變來實現有規律的邊框圖案。
第三章 形狀
半橢圓/四分之一橢圓/八分之一橢圓
通過border-radius可以分別設置每個角的水平和垂直圓形半徑,進而達到對每個角的變形設置。
平行四邊形
傳統做法:對元素添加skew()屬性進行變形。
缺點:元素的形狀是發生了改變,但是內部的文本和其他元素也都全部發生了變形。
新的思路:
方法一:通過嵌套元素,外部元素負責形狀的變形,內部元素進行反向變形,使元素恢復正常。如果需要圖片填充變形的形狀,除了對內部圖片進行反向變形外,還需要scale放大,填充滿整個變形圖案。
缺點:需要添加額外的html元素。
方法二:通過添加偽元素,讓偽元素來完成形狀的變形,元素本身不發生變化。
缺點:無法使圖片填充變形的形狀。
注:以上方法適用于任何我們想要變形一個元素而不想變形它的內容情況
菱形圖片
除了使用“平行四邊形”中的方法一來創建一個菱形圖片之外,還可以使用clip-path屬性來直接對圖片元素進行裁剪。
缺點:需要提前考慮clip-path屬性的兼容性。
切角效果
方法一:
1、切角效果的核心方式就是使用:linear-gradient(45deg, transparent 15px, red 0);通過漸變來實現一個透明的小角,導致視覺效果像切角了。
2、當對元素進行多個切角時,將背景進行劃分,每塊單獨做切角處理,然后定位每塊的位置,“拼接”成一個背景。
3、要實現弧形切角(內凹圓角)時,只需要將徑向漸變替換線性漸變即可。
div{background: #58a;background: radial-gradient(circle at top left, transparent 15px, #58a 0) top left,radial-gradient(circle at top right, transparent 15px, #58a 0) top right,radial-gradient(circle at bottom right, transparent 15px, #58a 0) bottom right,radial-gradient(circle at bottom left, transparent 15px, #58a 0) bottom left;background-size: 50% 50%;background-repeat: no-repeat; } 復制代碼缺點:只能是純色背景。
方法二:通過SVG畫一個切角效果的圖片,然后基于border-image的工作原理,將切角效果應用于border上。
div{border: 15px solid transparent;border-image: 1 url('data:image/svg+xml,\<svg xmlns="http://www.w3.org/2000/svg" width="3" height="3" fill="%2358a">\<polygon points="0,1 1,0 2,0 3,1 3,2 2,3 1,3 0,2" />\</svg>');background: #58a;background-clip: padding-box; } 復制代碼缺點:背景顏色只能是純色或者是邊緣接近純色的背景圖片。
方法三:使用clip-path對元素進行裁剪,裁剪出切角效果,無論你的背景是什么這種方法都能夠適用,但是要注意clip-path屬性的兼容性。
div {height:50px;background: #58a;-webkit-clip-path: polygon(20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),calc(100% - 20px) 100%,20px 100%, 0 calc(100% - 20px), 0 20px);clip-path:polygon(20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),calc(100% - 20px) 100%,20px 100%, 0 calc(100% - 20px), 0 20px); } 復制代碼梯形圖案
1、通過元素3D旋轉投影成2D的梯形形狀,然后通過scale將元素按照比例放大,彌補因為旋轉造成的高度縮小。
2、通過固定元素的transform-origin,選擇元素的哪幾條邊不需要變化。
3、使用添加偽元素變形方案,因為3D旋轉無法進行反向變形,因此不采納嵌套元素變形方案。
缺點:同種旋轉角度不同的寬度,梯形元素的傾斜角因為寬度原因會不相同。
餅狀圖
方法一:
步驟一:
1、通過創建一個陰陽圖,左邊為餅狀圖默認顏色,右邊為餅狀圖顯示顏色。
2、0~50%通過創建偽元素(顏色為默認顏色),擋住右邊的顯示顏色,通過旋轉(0~0.5turn),一點點將顯示顏色顯示出來。
3、50%~100%通過創建偽元素(顏色為顯示顏色),通過旋轉(0~0.5turn),一點點覆蓋左邊的默認顏色。
4、通過animation切換偽元素背景色與重置旋轉角度。
步驟二:
1、通過animation-delay將直接跳轉到動畫的指定時間點。
方法二:
1、使用SVG中的虛線描邊,將圓形描邊的大小設置為半徑的2倍,能夠完全覆蓋圓形。
2、設置虛線的間隔為圓形的周長,能夠保證只顯示一塊虛線。
3、設置虛線的長度為所占比例,顯示出我們所需要的餅狀圖。
總結
通過以上的案例發現,元素的變形主要通過以下幾種方式:
方法一:使用transform變形屬性對元素進行2D/3D變形,然后通過scale方法元素來彌補因為變形所造成的寬高損失。
方法二:使用clip-path屬性直接對元素進行裁剪。
方法三:使用linear-gradient()對元素進行處理。
第四章 視覺效果
單側投影/鄰邊投影/雙側投影
1、box-shadow的第四個參數,稱為擴張半徑,可以根據指定的值去擴大或者縮小投影的的尺寸。
2、根據擴張尺寸,投影時如果陰影在別的邊漫出來了,我們可以設置擴張尺寸為負,這樣就能夠在保留陰影效果的同時,將其他邊的陰影縮進去已到達去除陰影的效果。
不規則投影
1、box-shadow的投影無法作用于偽元素或者半透明的裝飾上(比如虛線中間的縫隙,切角效果)
方法一:使用CSS濾鏡filter屬性的drop-shadow()函數,它可以為任何非透明的地方添加上陰影,參數等同于box-shadow但是不支持inset關鍵字和擴張半徑。
缺點:drop-shaodow可以為任何非透明的地方添加上陰影,因此如果你的背景是透明的,則drop-shadow會為字體添加上陰影。
圖片染色效果
方法一:在圖片的上層覆蓋一層半透明的純色或者把圖片設為半透明并覆蓋在一層實色背景之上。
缺點:并不是真正的染色效果,并且削弱了圖片的對比度。
方法二:把圖片放置在<canvas>中,并利用腳本對其進行染色處理。
方法三:通過多個filter濾鏡組合對圖片進行處理。
img {// 根據需求自由組合濾鏡filter: sepia() // 將圖像轉換為深褐色saturate(4) // 轉換圖像飽和度hue-rotate(295deg); // 給圖像應用色相旋轉 } 復制代碼缺點:當添加動畫將img切換會原圖的效果時,切換效果不是一點點的漸變而是將濾鏡一個個剔除的過渡變化。
方法四:混合模式-mix-blend-mode,只需要把圖片包裹在一個容器中,并為這個容器的背景色設置為我們想要的主色調。
<div><img src='demo.jpg'/> </div> div {background:rgba(255,0,0,0.5); } img {mix-blend-mode:luminosity; } 復制代碼缺點:要注意屬性的兼容性,混合模式不支持動畫,可以將容器的背景色設置為透明來實現正常/染色的切換。
方法五:混合模式-background-blend-mode,只需要使用一個div元素,將第一層背景設置為要染色的圖片,將第二層背景設置為我們想要的主色調。
<div style="background-image:url(demo.jpg)"></div> div {width: 640px; height: 440px;background-size: cover;background-color: rgba(255,0,0,0.5);background-blend-mode: luminosity; } 復制代碼缺點:要注意屬性的兼容性,混合模式不支持動畫,可以將容器的背景色設置為透明來實現正常/染色的切換。
毛玻璃效果
1、背景圖片之上存在文字,文本層所覆蓋的那部分圖片區域作模糊處理。
方法一: 為文本層添加一個偽元素,偽元素的設置的背景圖片與之前的背景圖片一致,導致偽元素的背景圖片重疊在原背景圖片上方,然后只需要對偽元素背景圖片做模糊處理就可以了。
折角效果
1、使用漸變描繪一個空白的折角區域。
2、通過偽元素創建一個折角,通過三角函數來計算折角的大小,通過折角的角度來計算折角旋轉角度和偏移角度,來創造出合乎常理的折角效果。
缺點:只能夠對純色背景進行折角效果。
第五章 字體排印
插入換行
傳統做法:通過<br/>標簽來進行換行
新的思路:可以通過:before或:after偽類選擇器中的content設置為“\A”來進行換行,因為Unicode字符中代表換行符的為“0x000A”,在CSS中可以寫為“\000A”或者簡化為“\A”
div::after {content: "\A";white-space: pre; // 能夠保留源代碼中空白和換行符,否則content中的換行符將被忽略。 } 復制代碼tab-size屬性
在需要展示代碼的網頁上時,通過設置tab-size屬性能夠指定一個tab縮進幾個字符。
為某些字符單獨設置字體
傳統做法:為需要單獨設置字體的字符設置class,通過class為它們設置獨特的字體。
新的思路:@font-face中的unicode-range屬性可以設置字體的適用于哪些字符。
@font-face {font-family: demoFont;src: local('Baskerville-Italic'), local('GoudyOldStyleT-Italic'); /* 應用于指定字符的字體 */unicode-range: U+26; /* 設置生效字符,'&'的Unicode碼位,可以通過'&'.chatCodeAt(0).toString(16)獲取'&'的十六進制碼位'26',然后前面加上'U+'前綴 */ }p {font-family: demoFont, Helvetica; /* demoFont字體只應用于'&'字符,其他字符會適用后續的字體'Helvetica' */ } 復制代碼自定義文本下劃線
傳統做法:通過text-decoration:underline;
新的思路:
1、通過background與background-size設置一條自定義格式的下劃線;
2、通過text-shadow可以讓字符周圍出現一圈白邊,使的顯示為下劃線遇到字母的降部自動斷開避讓。
3、文本最好放置在行內元素內,這樣下劃線才能隨這文本的換行也進行換行。
空心字效果/文字外發光效果/文字凸起效果
通過text-shadow為文本添加效果來實現。
環形文字
1、通過SVG的path畫出一個圓形。
2、通過text與textPath添加文本,并通過xlink:href屬性將文本鏈接到路徑上。
注:這種方法不但適用于環形文字還適用于所有需要特殊路徑排序的文字。
第六章 用戶體驗
擴大用戶交互熱區
方法一:使用透明的border擴大交互熱區。使用background-clip重新定義背景的填充區域。
.demo1 {border:20px solid transparent;background-clip:padding-box;/* 實際border-radius效果值為border-radius減去border的值 */border-radius:25px;box-shadow: 0 0 0 1px rgba(0,0,0,0.3) inset; } 復制代碼注:
1、如果要設置border-radius的值時需要注意,實際border-radius效果值為border-radius減去border的值。
2、如果要設置邊框可以通過內嵌投影在模擬出一道實色邊框。
缺點:無法為元素設置box-shadow陰影效果,因為陰影效果時設置border-box外面的。
方法二:使用一個偽元素,擴大偽元素的范圍,偽元素的范圍也可以觸發熱區。通過偽元素可以隨意設置熱區的尺寸、位置、形狀。
.demo2 {position:relative; } .demo2:before {content:'';position:absolute;top:-10px;bottom:-10px;left:-10px;right:-10px; } 復制代碼自定義check樣式
使用label與checkbox進行相關聯,然后將checkbox隱藏起來,最后通過設置label偽元素的樣式來頂替checkbox的樣式。
創建蒙層
傳統做法:創建一個額外HTML元素來設置為蒙層。
新的思路:
方法一:通過body上的偽元素來設置為蒙層。
缺點:偽元素無法綁定獨立的JS事件處理函數以及對于元素的z-index設置可能會出現偏差。
方法二:通過box-shadow來設置蒙層。box-shoadow: 0 0 0 50vmax rgba(0,0,0,.8)
缺點:只能覆蓋當前窗口,頁面如果滾動就會露餡以及無法阻止用戶與頁面其他元素交互。
方法三:使用dialog元素backdrop偽元素可以只能蒙層。
缺點:要考慮backdrop偽元素的兼容性。
彈出窗口背景模糊
實現效果類似毛玻璃效果,只是模糊的不是一張背景圖片而是頁面上的任意元素。
方法一:頁面的元素全部包裹在一個div中,dialog與這個div同級,dialog彈出的時候,將這個div添加上模糊濾鏡blur().
滾動提示
方法一:
1、background-attachment:scroll可以使的背景圖片隨著元素滾動而固定在元素上,因此可以在滾動的時候創建一個漸變陰影。這樣滾動的時候上方都會存在一個陰影。
2、background-attachment:local可以使背景圖片相對于元素的內容固定,因此可以創建一個白色遮罩層當用戶滾動到頂部的時候遮擋住陰影。
交互式圖片對比
方法一:將兩張圖片重疊在一起,然后通過resize:horizontal來調節覆蓋在上層的圖片width。
<div class="image-slider"><div><img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e69b3ab1e4?w=400&h=400&f=jpeg&s=57981" alt="Before" /></div><img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e6a9e65856?w=400&h=400&f=jpeg&s=63250" /> </div>.image-slider {position:relative;display: inline-block; }.image-slider > div { /* 覆蓋在上層的圖片 */position: absolute;top: 0; bottom: 0; left: 0;width: 50%;max-width: 100%;overflow: hidden;resize: horizontal; }.image-slider img {display: block;user-select: none; } 復制代碼第七章 結構與布局
自適應內部元素
width與height中存在一些關鍵詞,其中width:min-content將會解析為這個容器內最大的不可斷行元素的寬度(即最寬的單詞、圖片和具有固有寬度的盒元素)
<figure><img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e6a9e65856?w=400&h=400&f=jpeg&s=63250" /><figcaption>The great Sir Adam Catlace was named after Countess Ada Lovelace, the first programmer ever.</figcaption> </figure>figure {max-width: 300px; /* 兼容回退處理 */max-width: min-content;margin: auto; }figure > img { max-width: inherit } 復制代碼精確控制表格樣式
通過table-layout:fixed能夠讓我們更加自由的控制表格中的種種樣式。
根據兄弟元素數量/范圍設置樣式
1、只有1個子元素
li:only-child { /* code */} 或 li:first-child:nth-last-child(1) {/* code */ } /* 元素是第一個元素同時也是最后一個元素,就等同于只有一個元素 */ 復制代碼2、判斷有多少個元素
li:first-child:nth-last-child(4) {/* code */ } /* 元素是第一個元素同時也是倒數第四個元素,就等同于一共有四個元素 */ li:first-child:nth-last-child(4)~ li {/* code */} /* 當列表只有4個元素時,為列表設置樣式 */ 復制代碼3、根據兄弟元素范圍
li:first-child:nth-last-child(n+4)~ li {/* code */} /* n可以為任何數,表示當列表至少含有4個元素時,為列表設置樣式 */ li:first-child:nth-last-child(-n+4)~ li {/* code */} /* n可以為任何數,表示當列表最多含有4個元素時,為列表設置樣式 */ li:first-child:nth-last-child(n+2):nth-last-child(-n+6)~ li {/* code */} /* n可以為任何數,表示當列表含有2~6個元素時,為列表設置樣式 */ 復制代碼滿幅的背景,定寬的內容
傳統做法:外層的html元素設置為滿幅的背景,然后內層html設置為定寬居中的內容。
缺點:需要額外一層html元素。
新的思路:通過calc()函數來設置內容的左右邊距,使其定寬居中。
outer {padding:0 calc(50% - 450px);/* 通過calc()函數計算內容居中時元素的左右邊距;450px為內容定寬900px/2計算得到 */ } 復制代碼垂直居中
CSS 技巧篇(七):設置元素居中
緊貼底部的頁腳
方法一:設置mai主體元素的min-height為窗口高度減去footer的高度。
.main {min-height:calc(100vh - 100px) /* 100px為footer的高度*/ } 復制代碼缺點:要求footer的高度必須是固定已知的。
方法二:將body元素設置為flexBox,然后設置main主體元素設置為flex:1。
body {display:flex;flex-flow:colum;min-height:100vh; } .main {flex:1; } 復制代碼第八章 過渡與動畫
緩動效果
在animation或者transition中的調速參數除了ease等關鍵詞之外,還可以通過cubic-bezier()函數自定義調速函數。
cubic-bezier()函數在線調試可以前往貝塞爾曲線在線調試。
逐幀動畫(以loading動畫為例)
傳統做法:設置為一張gif圖片。
缺點:gif無法設置為透明并且無法修改動畫的屬性。
新的思路:將動畫劃分為逐幀的圖片,然后通過animation對圖片進行過渡切換,steps()能夠將動畫切分為多幀,而且是幀與幀之間的硬切。
@keyframes loader {to { background-position: -800px 0; } }.loader {width: 100px; height: 100px;text-indent: 999px; overflow: hidden; /* Hide text */background: url(http://dabblet.com/img/loader.png) 0 0;animation: loader 1s infinite steps(8); } 復制代碼閃爍效果
方法一:動畫的50%設置為transparent,這樣動畫就形成了從有->無→有的變化。
@keyframes blink { 50% { color: transparent } } .blink-smooth {animation: 1s blink 3; } 復制代碼方法二:通過animation中的animation-direction:alternate屬性能夠設置動畫的循環周期。
@keyframes blink { to { color: transparent } } .blink-smooth {animation: .5s blink 6;animation-direction: alternate; } 復制代碼打字動畫
1、通過animation和steps控制width的值,將字符一個個的顯示出來;
2、通過border-right來創造光標;
3、ch可以表示為每一個字符的寬度。
沿環形路徑平移的動畫
方法一:在圖片外在包裹一層div,div為順時針圍繞一個大圓的圓心正常旋轉,而img則是相對自身中心逆時針旋轉來抵消外部旋轉。
<div class="path"><div class="avatar"><img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e684aa60d7?w=400&h=400&f=jpeg&s=63250" /></div> </div>@keyframes spin {to { transform: rotate(1turn); } }.avatar {animation: spin 3s infinite linear;transform-origin: 50% 150px; }.avatar > img {animation: inherit;animation-direction: reverse; }/* Anything below this is just styling */.avatar {width: 50px;margin: 0 auto;border-radius: 50%;overflow: hidden; }.avatar > img {display: block;width: inherit; }.path {width: 300px; height: 300px;padding: 20px;border-radius: 50%;background: #fb3; } 復制代碼方式二:通過translate的移動來頂替transform-origin的效果
<div class="path"><img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e684aa60d7?w=400&h=400&f=jpeg&s=63250" class="avatar" /> </div>@keyframes spin {from {transform: translateY(150px) translateY(-50%)rotate(0turn)translateY(-150px) translateY(50%)rotate(1turn)}to {transform: translateY(150px) translateY(-50%)rotate(1turn)translateY(-150px) translateY(50%)rotate(0turn);} }.avatar {animation: spin 3s infinite linear; }/* Anything below this is just styling */.avatar {margin: 0 auto;display: block;width: 50px;border-radius: 50%;overflow: hidden; }.path {width: 300px; height: 300px;padding: 20px;border-radius: 50%;background: #fb3; } 復制代碼總結 總結正文
轉載于:https://juejin.im/post/5cca9f2fe51d453b0d1c2487
總結
以上是生活随笔為你收集整理的《CSS揭秘》读书笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机无法删除tf卡的内容,SD卡不能删
- 下一篇: 前端学习(3231):React中的受控