每次要用到圖標的時候都會到 icono 去copypaste,但每次用到的時候尺寸都各不同,老是要調整參數,巨煩。固然你能夠會想到用zoom、scale來作縮放,可是這樣的縮放會使得線寬也變粗了,不甚滿意。css
終於下定心思來改造一個可縮放的圖標庫。github先上:https://github.com/qieguo2016/iconoo,目前提供下載link標籤引入和npm+webpack的引入方式,詳見項目的readme。(喂,來個star!)。上圖:前端
關於改造,一開始的想法就是使用百分比尺寸來改造,而後立刻發現不可行了,繪製圖標最依賴的兩種手段:border、box-shadow都不能夠用百分比,因此這個想法,pass!而後很天然就想到了在單位上作文章,rem?No、No、No,一個庫依賴全局變量那簡直是個笑話。剩下的天然就是em了,在icon級設置font-size,而後icon自己以及後代都以這個font-size爲參照,Perfect!webpack
使用CSS繪製線條,用到的不外乎兩個屬性:border & box-shadow。而形狀則能夠用border-radius、transform控制,位置會用到絕對定位、transform、margin等。CSS的繪圖,作過幾個就知道大概是怎麼回事了,歸根到底,仍是幾何。git
好比最簡單的加號:github
1 .plus { 2 box-sizing : border-box; 3 display : inline-block; 4 position : relative; 5 font-size : 20px; 6 } 7 8 .plus:before, plus:after { 9 content : ''; 10 pointer-events : none; 11 position : absolute; 12 left : 50%; 13 top : 50%; 14 transform : translate(-50%, -50%); 15 box-shadow : inset 0 0 0 1em; 16 } 17 18 .plus:before { 19 width : 1em; 20 height : 2px; 21 } 22 23 .plus:after { 24 height : 1em; 25 width : 2px; 26 }
實現很是簡單,經過設置兩個僞類的寬高造成橫豎兩個小矩形,接着用陰影填充滿,這樣一個加號必需的圖形就出來了。而後就是調整位置了,將這兩個矩形居中,加號就出來了。具體是經過絕對定位+反向偏移的方式,巧妙利用了這兩個屬性百分比參照的不一樣實現居中。尺寸方面,全部尺寸除了線寬(2px)外都使用em這個相對單位,因此調整font-size的值就能夠調整圖標的大小了。若是要調整線寬,那就須要改變這個2px了,引入less、sass將線寬定義成變量就能夠很方便地改變線寬了。web
原理雖然簡單,可是不少圖標仍是至關有意思的,經過分析這些圖標也能加深對css的認識。例如:npm
這個圖形網上說的應該仍是比較多的了,第一眼看到懵逼了。。。分析一下,最外層的邊框明顯能夠用border來作,而後用個before來作圓點也很是簡單,關鍵是兩座大山要如何繪製呢?box-shadow貌似能夠作多層邊框呢,而後加個旋轉是否是就出來了呢?繪製流程以下:canvas
上CSS代碼吧:瀏覽器
1 .icon-test { 2 display: inline-block; 3 position: relative; 4 box-sizing: border-box; 5 width: 90px; 6 height: 80px; 7 border: 5px solid; 8 border-radius: 10px; 9 color: #2ba5bb; 10 overflow: hidden; 11 } 12 13 .icon-test:before,.icon-test:after { 14 content: ''; 15 pointer-events: none; 16 position: absolute; 17 } 18 19 .icon-test:before { 20 width: 10px; 21 height: 10px; 22 top: 18px; 23 right: 20px; 24 box-shadow: inset 0 0 0 1em; 25 border-radius: 50%; 26 } 27 28 .icon-test:after { 29 width: 60px; 30 height: 50px; 31 left: 0; 32 bottom: -27px; 33 box-shadow: inset 0 0 0 50px,30px -20px 0 0; 34 transform: rotate(45deg); 35 }
再來一個:sass
看起來跟上一個有點像,然而,按照上一個的繪製方式卻怎麼也畫不出來~~~仍是分解幾步來畫,邊框很容易解決,一個box-shadow就完事。這兩座大山其實形狀都同樣,都是一個三角形下接一個矩形,三角形顯然能夠用border來畫,而矩形用box-shadow就能夠了!這裏還用了透明border來作左側和下側的留白,比直接用尺寸對齊要好不少。
1 .icon-test { 2 display: inline-block; 3 position: relative; 4 box-sizing: border-box; 5 color: #2ba5bb; 6 width: 60px; 7 height: 40px; 8 border-top-width: 0; 9 border-right-width: 0; 10 border: 4px solid; 11 border-color: transparent; 12 box-shadow: -4px 5px; 13 overflow: hidden; 14 } 15 16 .icon-test:before,.icon-test:after { 17 content: ''; 18 pointer-events: none; 19 position: absolute; 20 } 21 22 .icon-test:before { 23 left: 0; 24 bottom: 8px; 25 border: 14px solid transparent; 26 border-bottom-color: currentColor; 27 box-shadow: 0 16px; 28 } 29 30 .icon-test:after { 31 left: 28px; 32 bottom: 9px; 33 border-width: 0 9px 21px; 34 border-style: solid; 35 border-color: transparent transparent currentColor; 36 box-shadow: 0 17px; 37 }
怎麼樣?以爲這些都是小玩意?好吧,都讓開,我要開始裝逼了!
蒙娜麗莎?什麼鬼?我會告訴你這也是一個單標籤純CSS畫出來的嗎?
幾千條box-shadow構成的蒙娜麗莎,看的我內分泌都失調了。。。
(author:Jay Salvat, 來源:http://codepen.io/jaysalvat/pen/HaqBf )
如此變態的繪圖,都沒有怎麼用到CSS中最強大的變形,若是加入變形,那能夠畫出來的形狀就更多了。。。更多CSS玩意兒,請到codepen上去探寶吧!
PS: 蒙娜麗莎這種圖形,能夠讀取原圖信息轉換成單位面積的box-shadow,前端用canvas就能夠作的,其實這貨的技術含量比一個圖片圖標還要少呢。話雖如此,複雜圖形使用CSS來繪製的話,性價比仍是過低,建議仍是使用圖片,這樣會更具表現力一些,操做起來也更加簡單!專業的繪圖仍是交給專業的UI去作吧!
其實,遇到的這些都不能叫作坑,是本身對CSS的理解度不夠而已。原覺得,將原來icono使用的單位換算成em就算完事了,然而,一改font-size就變形了,頓時懵逼!究其緣由,其實也很簡單,並非全部地方與font-size都是正比的,不少地方混入了線寬的影響,因此要剔除線寬的影響。
去除線寬影響的方法不外乎兩種:
1)去掉線寬,例如使用box-shadow等不影響尺寸的屬性
2)將線寬歸入計算內,好比translate反向偏移掉線寬,這樣總體縮放就不會受到線寬的影響了。
另一個比較煩的就是居中,其實居中基本上就只用到了下面兩種方式,仍是蠻簡單的。只是,這個反覆的copypaste,煩哪!
1. 絕對定位+margin:auto。
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
實現原理:利用css定位規則,設置左右、上下方向定位爲0,margin爲auto,讓css根據定位計算margin值,用hack的方式實現居中。居中塊的尺寸須要可控,由於css計算margin時也須要參考尺寸值,因爲四周爲0,因此自動計算獲得的盒子尺寸(含margin)是與父容器同樣的。不管是設置居中塊的width、height或者是max-height、max-width,都是讓尺寸不會擴大到與父級同樣。
侷限:在參考系父級(position!=static)大小比自己要小的時候,水平方向的居中就會失效。(垂直方向依然居中)
2. 絕對定位 + transform反向偏移。
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: auto;
實現原理:先絕對定位相對父級偏移50%,而後使用transform來反向偏移。因爲transform的計算基準是元素自己,因此這裏能夠用50%來作反向偏移。
侷限:這個方案須要固定居中塊的尺寸值(不能設置max-width等範圍限制),瀏覽器須要以此爲基準來計算定位!
綜合來講,方案2的居中方式明顯會比方案1要好,可是在繪製圖標的時候會用到transform來作一些偏移,爲了避免覆蓋偏移效果因此要用到方案的方式來作居中。除了這兩種居中方式,還有inline-block對齊after/before子元素的方式,還有table和flexbox的方式來實現居中,可是畫圖標自己層級有限並且也用到了before/after,因此不適用圖標繪製。
目前純CSS的圖標仍是挺多應用場景的,這種圖標的方案免去了作雪碧圖和維護雪碧圖的麻煩,並且減小了圖片資源的請求,從性能上來講會有那麼0.01s的提升吧。不用堆雪碧圖還方便調整顏色,性能還有0.01s的優化,這套CSS圖標你還不趕忙用起來?!
PS:各位看官以爲不錯的話,還請順手給個github星星哈。多攥幾顆星星,說不定就升職加薪贏取白富美了呢~~~
PPS:再附上幾個神級的CSS效果吧(by Fabrizio Bianchi 來源: http://codepen.io/fbrz/pen/iqtlk):