還有幾天就到國(guó)慶中秋了,快要放假了,先祝大家節(jié)日快樂!之前寫過js的寫作建議和技巧,那么今天就來(lái)聊聊css吧!說到css,每一個(gè)網(wǎng)頁(yè)都離不開css,但是對(duì)于css,很多開發(fā)者的想法就是,css只要能用來(lái)布局,把效果圖排出來(lái)就可以了,其它的細(xì)節(jié)或者優(yōu)化,不需要怎么考慮。但是我覺得css可不只是把頁(yè)面的布局完成就是完事的,還需要考慮很多細(xì)節(jié)有優(yōu)化,更不會(huì)像大家想得那么簡(jiǎn)單,在學(xué)習(xí)當(dāng)中,如果發(fā)現(xiàn)什么技巧或者優(yōu)化的點(diǎn),我也會(huì)學(xué)以致用!那么今天,就分享下我總結(jié)的css寫作建議和性能優(yōu)化的一些問題!希望能幫讓大家對(duì)神奇的css有一個(gè)新認(rèn)識(shí),當(dāng)然,如果大家覺得還有什么其它的建議。歡迎指點(diǎn)!
首選,關(guān)于css渲染的規(guī)則,大家可能都知道,是從右到左的渲染!如下栗子
.nav h3 a{font-size: 14px;}
渲染過程大概是:首先找到所有的a
,沿著a
的父元素查找h3
,然后再沿著h3
,查找.nav
。中途找到了符合匹配規(guī)則的節(jié)點(diǎn)就加入結(jié)果集。如果找到根元素html
都沒有匹配,則不再遍歷這條路徑,從下一個(gè)a
開始重復(fù)這個(gè)查找匹配(只要頁(yè)面上有多個(gè)最右節(jié)點(diǎn)為a
)。
參考:CSS選擇器從右向左的匹配規(guī)則
一般情況下,元素的嵌套層級(jí)不能超過3級(jí),過度的嵌套會(huì)導(dǎo)致代碼變得臃腫,沉余,復(fù)雜。導(dǎo)致css文件體積變大,造成性能浪費(fèi),影響渲染的速度!而且過于依賴HTML文檔結(jié)構(gòu)。這樣的css樣式,維護(hù)起來(lái),極度麻煩,如果以后要修改樣式,可能要使用!important
覆蓋。
這個(gè)我目前保持中立意見,因?yàn)榭粗W(wǎng)上的文章,有些人支持使用樣式重置,有些人不支持使用,誰(shuí)也說服不了誰(shuí)。我自己的情況,我有使用樣式重置,但是是比較簡(jiǎn)單的一個(gè)總結(jié),代碼如下!
body,dl,dd,h1,h2,h3,h4,h5,h6,p,form,ol,ul { margin: 0; padding: 0; } h1, h2, h3, h4, h5, h6 { font-weight: normal; } ol, ul { list-style: none; } h1{ font-size: 24px; } h2{ font-size: 20px; } h3{ font-size: 18px; } h4 { font-size: 16px; } h5{ font-size: 14px; } h6{ font-size: 12px; }
首先,css樣式級(jí)別整理如下
!important>行內(nèi)樣式 >id樣式>class樣式>標(biāo)簽名樣式。
然后有一點(diǎn)要提一下就是,組合選擇器使用權(quán)值會(huì)疊加的。比如id的權(quán)值是100,class是10,標(biāo)簽名是1(其它不清楚了)!那么p.test-class
權(quán)值就是11,p#test
就是101
比如有一個(gè)p
<p id="test" class="test-class" style="color:green;"></p>
那么樣式權(quán)值方面就是
p {color: red !improtant;} (大于下面的一切) <p id="test" class="test-class" style="color:black;"></p> (大于111) p#test.test-class (111) #id.test-class (110) p#test (101) #test (100) p.test-class (11) .test-class (10) p (1) * (小于1)
不解釋,看圖
上面幾個(gè)p
元素margin
和padding
都為0,但是還有邊距。這個(gè)的解決方案有兩種
1.刪除代碼之前的空行空格
帶display:inline-block
的元素之前的空行都刪除掉,如下寫法
2.父元素font-size設(shè)置為0,這個(gè)直接看圖
如果頁(yè)面有使用img標(biāo)簽,那么img很建議設(shè)置width和height。目的是為了在網(wǎng)速差或者其它原因加載不出圖片的時(shí)候,保證布局不會(huì)亂。
如下栗子,一個(gè)很普通的布局。
但是萬(wàn)一出現(xiàn)什么情況,圖片加載不出來(lái)的話,建議的處理方式是第一種,顯示一張默認(rèn)圖片,即使不顯示默認(rèn)圖片,也讓圖片有一個(gè)占位的作用,保證布局不會(huì)亂!
如果圖片加載不出,img又沒有設(shè)置width和height的話,就會(huì)像下面這樣,布局亂了!
關(guān)于設(shè)置width
和height
,我順便說幾點(diǎn)
1.PC站,建議在img標(biāo)簽的屬性設(shè)置width
和height
。這樣避免加載不出css而錯(cuò)位
2.手機(jī)站,建議用css設(shè)置img
的width
和height
,因?yàn)槭謾C(jī)站要做適配,在屬性設(shè)置width
和height
不靈活,比如使用rem布局,在屬性那里設(shè)置不了width
和height
。
3.如果圖片不固定,但是有一個(gè)max-width
和max-height
,那么建議在img的父元素設(shè)置width和height。img根據(jù)父元素的width
和height
設(shè)置max-width
和max-height
。
這里只放圖,不解釋
這個(gè)方式不推薦使用,因?yàn)檫@個(gè)寫法,.p2
的寬高必須要設(shè)置,否則就是100%;比如設(shè)置了top:0;bottom:0;
效果和設(shè)置height:100%;
是一樣的。如果想要避免,就必須要設(shè)置height
。
這里說的預(yù)加載,不是懶加載。首先根據(jù)我個(gè)人理解科普下,懶加載和預(yù)加載的區(qū)別。
懶加載:頁(yè)面加載的時(shí)候,先加載一部分內(nèi)容(一般是先加載首屏內(nèi)容),其它內(nèi)容等到需要加載的時(shí)候再進(jìn)行加載!
預(yù)加載:頁(yè)面加載的時(shí)候,先加載一部分內(nèi)容(一般是先加載首屏內(nèi)容),其它內(nèi)容等到先加載的一部分內(nèi)容(一般是首屏內(nèi)容)加載完了,再進(jìn)行加載。
兩種方式,都是為了減少用戶進(jìn)入網(wǎng)站的時(shí)候,更快的看到首屏的內(nèi)容!
下面栗子,將這#preloader
這個(gè)元素加入到到html中,就可以實(shí)現(xiàn)通過CSS的background
屬性將圖片預(yù)加載到屏幕外的背景上。只要這些圖片的路徑保持不變,當(dāng)它們?cè)趙eb頁(yè)面的其他地方被調(diào)用時(shí),瀏覽器就會(huì)在渲染過程中使用預(yù)加載(緩存)的圖片。簡(jiǎn)單、高效,不需要任何JavaScript。
#preloader { /*需要預(yù)加載的圖片*/ background: url(image1.jpg) no-repeat,url(image2.jpg) no-repeat,url(image3.jpg) no-repeat; width: 0px; height: 0px; display: inline; }
但是這樣會(huì)有一個(gè)問題,因?yàn)?code>#preloader預(yù)加載的圖片,會(huì)和頁(yè)面上的其他內(nèi)容一起加載,增加了頁(yè)面的整體加載時(shí)間。所以需要用js控制
function preloader(urlArr,obj) { var bgText=''; for(var i=0,len=urlArr.length;i<len;i++){ bgText+='url('+urlArr[i]+') no-repeat,'; } obj.style.background=bgText.substr(0,bgText.length-1); } window.onload = function() { preloader(['image1.jpg','image2.jpg','image3.jpg'],document.getElementById('preloader')); }
原理也很簡(jiǎn)單,就是先讓首屏的圖片加載完,然后再加載其它的圖片。通過給#preloader
設(shè)置背景圖片,加載所需要的圖片,然后頁(yè)面上需要加載這些圖片的時(shí)候,就直接從緩存里面拿圖片,不需要通過http請(qǐng)求獲取圖片,這樣加載就很快。
在做網(wǎng)頁(yè)的時(shí)候經(jīng)常會(huì)使用下面兩種方式重置樣式,以此來(lái)消除標(biāo)簽的默認(rèn)布局和不同瀏覽器對(duì)于同一個(gè)標(biāo)簽的渲染。
*{margin:0;padding:0;}
上面這種方式,代碼少,但是性能差,因?yàn)殇秩镜臅r(shí)候,要匹配頁(yè)面上所有的元素!很多基礎(chǔ)樣式?jīng)]有margin
和padding
的元素,比如p
,li
等。都被匹配,完全沒必要!
下面看另一種方式。
body,dl,dd,h1,h2,h3,h4,h5,h6,p,form,ol,ul{margin:0;padding:0;}
這種方式,代碼稍微多,但是性能比上面的方式好,在渲染的時(shí)候,只匹配body,dl,dd,h1,h2,h3,h4,h5,h6,p,form,ol,ul
這里面的元素,這些元素帶有margin
和padding
,需要重置!
再看例子:
.test * {color: red;}
匹配文檔中所有的元素,然后分別向上逐級(jí)匹配class為test的元素,直到文檔的根節(jié)點(diǎn)
.test a {color: red;}
匹配文檔中所有a的元素,然后分別向上逐級(jí)匹配class為test的元素,直到文檔的根節(jié)點(diǎn)
兩種方式,哪種更好不言而喻,所以在開發(fā)的時(shí)候,建議避免使用通配選擇器。
這個(gè)沒什么好解釋的,就是壓縮和合并css。
首先壓縮css,除了使用工具,比如gulp,webpack等把代碼壓縮,把空格和換行都去掉。還有一個(gè)建議就是屬性簡(jiǎn)寫。
比如
margin-top:0; margin-right:10px; margin-bottom:10px; margin-left:10px; background-image: url('test.jpg'); background-position: top center; background-repeat: no-repeat; border-width:1px; border-style:solid; border-color:#000; color:#0099FF;
可以換成下面的
margin:0 10px 10px 10px; background: url('test.jpg') no-repeat top center; border:1px solid #000; color:#09F;
至于合并的時(shí)候,我按照自己的開發(fā)習(xí)慣給幾個(gè)建議:
1.合并公用的樣式,比如項(xiàng)目的頭部,底部,側(cè)邊欄這些,一般都是公用的,這些可以寫在一個(gè)公用樣式表上,比如main.css
。
2.上面所說的main.css是每一個(gè)頁(yè)面都需要引入,而樣式重置表reset.css
也是每一個(gè)頁(yè)面都需要用到的,那么建議main.css和reset.css合并成一個(gè)文件,給頁(yè)面引入!減少請(qǐng)求!
3.每個(gè)頁(yè)面對(duì)應(yīng)的樣式為獨(dú)立的文件,比如首頁(yè)對(duì)應(yīng)的是index.css
。產(chǎn)品列表頁(yè)對(duì)應(yīng)的樣式是product-list.css
。那么index.css
就只在首頁(yè)引入,其它頁(yè)面不引入,因?yàn)橐爰儗倮速M(fèi)請(qǐng)求資源!其他頁(yè)面對(duì)應(yīng)的樣式也是這個(gè)處理方式!index.css
,product-list.css
等其它頁(yè)面的樣式就保留單獨(dú)的文件,不作合并處理!
瀏覽器在所有的 stylesheets 加載完成之后,才會(huì)開始渲染整個(gè)頁(yè)面,在此之前,瀏覽器不會(huì)渲染頁(yè)面里的任何內(nèi)容,頁(yè)面會(huì)一直呈現(xiàn)空白。這也是為什么要把 stylesheet 放在頭部的原因。如果放在 HTML 頁(yè)面底部,頁(yè)面渲染就不僅僅是在等待 stylesheet 的加載,還要等待 html 內(nèi)容加載完成,這樣一來(lái),用戶看到頁(yè)面的時(shí)間會(huì)更晚。
css樣式文件有兩種引入方式,一種是link
元素,另一種是@import
。在這里,我建議就是避免使用@import
。因?yàn)?code>@import會(huì)影響瀏覽器的并行下載,使得頁(yè)面在加載時(shí)增加額外的延遲,增添了額外的往返耗時(shí)。而且多個(gè)@import
可能會(huì)導(dǎo)致下載順序紊亂。比如一個(gè)css文件index.css
包含了以下內(nèi)容:@import url("reset.css")
。那么瀏覽器就必須先把index.css
下載、解析和執(zhí)行后,才下載、解析和執(zhí)行第二個(gè)文件reset.css。簡(jiǎn)單的解決方法是使用<link>
替代@import
。
接到效果圖,先不用著急切圖,先看下psd文件。思考下怎么排版,那些模塊可以做成公用的模塊,模塊應(yīng)該怎么命名,寫樣式等!
當(dāng)我們拿到設(shè)計(jì)師給的PSD時(shí),首先不要急于寫CSS代碼,首先對(duì)整個(gè)頁(yè)面進(jìn)行分析,先思考下面幾點(diǎn):
(1)分析頁(yè)面有哪些模塊是公用的,常見公用模塊有頭部,底部,菜單欄,懸浮按鈕等等
(2)分析模塊有什么樣式,把公用的樣式提取出來(lái),公用樣式包括公用的狀態(tài)樣式,比如按鈕,輸入框,下拉框等公用的選中狀態(tài),禁用狀態(tài)的樣式等等。
一個(gè)網(wǎng)站,肯定會(huì)有很多個(gè)小圖標(biāo),對(duì)于這些小圖標(biāo),目前的解決方案有兩個(gè),cssSprite(雪碧圖),字體圖標(biāo),把圖片轉(zhuǎn)成base64。下面對(duì)比一下這兩種方式!
cssSprite:把所有icon圖片合成一張png圖片,使用的是在,對(duì)節(jié)點(diǎn)設(shè)置寬高,加上bacgroud-position。以背景圖方式顯展示需要的icon,如果一個(gè)網(wǎng)站有20圖標(biāo),那么就要請(qǐng)求20次,使用cssSprite,只需要請(qǐng)求一次,大大的減少了http請(qǐng)求。缺點(diǎn)就是管理不靈活,如果需要新增一個(gè)圖標(biāo),都需要改合并圖片的源文件,圖標(biāo)定位也要規(guī)范,不然容易干擾圖片之間的定位!
字體圖標(biāo):簡(jiǎn)單粗暴的理解就是把所有的圖標(biāo)當(dāng)成一個(gè)字體處理!這樣不用去請(qǐng)求圖片。一般是使用class來(lái)定義圖標(biāo),要替換圖標(biāo)時(shí),只需更換樣式名,管理方便,語(yǔ)意明確,靈活放大縮小,并且不會(huì)造成失真。但是只支持單色的圖片。
base64:另一種方案就是把小的icon圖片轉(zhuǎn)成base64編碼,這樣可以不用去請(qǐng)求圖片,把base64編碼直接整合到j(luò)s或者css里面,可以防止因?yàn)橐恍┫鄬?duì)路徑,或者圖片被不小刪除了等問題導(dǎo)致圖片404錯(cuò)誤。但是找個(gè)方式會(huì)生成一大串的base64編碼。一般來(lái)說,8K以下的圖片才轉(zhuǎn)換成base64編碼。如果把一張50K的圖片轉(zhuǎn)成base64編碼,那么會(huì)生成超過65000個(gè)字符的base64編碼,字符的大小就已經(jīng)是將近70K了!建議就是:8K以下的圖片才轉(zhuǎn)換成base64編碼。
1.ID在頁(yè)面上本來(lái)就是唯一的而且人家權(quán)值那么大,前方嵌套(.content #test
)完全是浪費(fèi)性能。以及多寫一些沒有意義的代碼!這個(gè)雖然是一句話,但是還是有人犯這樣的錯(cuò)!
2.除了嵌套,在id的前面也不需要加標(biāo)簽或者其它選擇器。比如 p#test
或者.test#test
。這兩種方式完全是多余的,理由就是ID在頁(yè)面就是唯一的。前面加任何東西都是多余的!
把長(zhǎng)段相同樣式提取出來(lái)作為公用樣式使用,比如常用的清除浮動(dòng),單行超出顯示省略號(hào),多行超出省略號(hào)等等。
如下栗子
/*超出省略號(hào)*/ /*<p class='text-ellipsis'></p>*/ .text-ellipsis{ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } /*清除浮動(dòng)*/ /*<p class='clearfix'></p>*/ .clearfix:after { display: block; content: ''; clear: both; height:0; }
在我之前一篇文章(移動(dòng)web開發(fā)問題和優(yōu)化小結(jié)),也有寫過關(guān)于這個(gè)的優(yōu)化建議,之前說的兩個(gè)建議是:
1.CSS3動(dòng)畫或者過渡盡量使用transform
和opacity
來(lái)實(shí)現(xiàn)動(dòng)畫,不要使用left
和top
。
2.動(dòng)畫和過渡能用css3
解決的,就不要使用js
。如果是復(fù)雜的動(dòng)畫可以使用css3+js
(或者html5+css3+js
)配合開發(fā),效果只有想不到,沒有做不到。
下面補(bǔ)充一個(gè):動(dòng)畫不宜過多,尤其是手機(jī)網(wǎng)站,否則會(huì)出現(xiàn)性能的問題,比如cpu一下子就被占用滿了,掉幀等。而且,不建議給每一個(gè)元素都使用硬件加速。
參考鏈接:
CSS Animation性能優(yōu)化
css3動(dòng)畫性能優(yōu)化
CSS動(dòng)畫之硬件加速
Web動(dòng)畫
這個(gè)是在PC站會(huì)出現(xiàn)的問題,應(yīng)該大家都知道。下面簡(jiǎn)單說一下!
比如下面的栗子,一個(gè)網(wǎng)站,頁(yè)面內(nèi)容寬度是1200px??粗苷#瑳]什么特別
如果這個(gè)時(shí)候,把頁(yè)面窗口縮小。小于1200px,頁(yè)面出現(xiàn)滾動(dòng)條,然后把滾動(dòng)條拖到最右邊
這樣是不是就發(fā)現(xiàn),頂部的圖片和背景有一部分是斷層了!解決這個(gè)問題也很簡(jiǎn)單,就是給body
加上min-width
。值就是頁(yè)面寬度的值。body{min-width:1200px;}
重復(fù)上一步操作,無(wú)論怎么改變?yōu)g覽器窗口大小,都是正常的
之所以會(huì)出現(xiàn)這樣的問題,是因?yàn)?,比如窗口縮小到900px的時(shí)候,小于內(nèi)容寬度的1200px。就是出現(xiàn)橫向的滾動(dòng)條,但是body
的寬度是900px。這個(gè)時(shí)候,如果有元素(比如圖片的灰色區(qū)域和粉紅色的圖片)是相對(duì)body
的width
設(shè)置100%,那么實(shí)際上這些元素的寬度也就是900px。所以會(huì)出現(xiàn)斷層那些的視覺!解決方式就是給body
加上min-width
。讓body
的寬度最小不會(huì)小于內(nèi)容的寬度!
關(guān)于我對(duì)css寫作建議和性能優(yōu)化的一個(gè)總結(jié),就到這里了。css,絕對(duì)不是那種只要能用就行,或者只要能用css把布局弄好就行的一門語(yǔ)言。css給我的感覺,就是上手很簡(jiǎn)單,但是如果想用好css,還是得花時(shí)間去研究。css或者css3,能夠優(yōu)化的東西還有很多,用好css或者css3能夠少寫很多js代碼,做出來(lái)的東西也是很神奇,大家還是得繼續(xù)學(xué)習(xí)當(dāng)中的知識(shí)!
如果大家覺得我文章有哪個(gè)地方寫得不好,寫錯(cuò)了,歡迎指正。如果有什么其它的建議,歡迎指點(diǎn),讓大家互相交流,互相學(xué)習(xí),一起進(jìn)步!最后,祝大家節(jié)日快樂!
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com