摘要:最近有時(shí)間,想把醞釀的幾篇博客都寫(xiě)出來(lái),今天前端小學(xué)生帶著10個(gè)問(wèn)題秦驯,跟大家分享一下學(xué)習(xí)CSS的一些體會(huì),我覺(jué)得想學(xué)好CSS挣棕,必須保持一顆好奇心和刨根問(wèn)底的勁頭译隘,而不是復(fù)制粘貼,得過(guò)且過(guò)洛心。本人能力有限固耘,這篇文章從構(gòu)思加完成用了四五天,如果你和我一樣是前端小白词身,不妨仔細(xì)斟酌體會(huì)厅目,以期領(lǐng)悟到一些東西;如果你是業(yè)界大牛,也請(qǐng)你駐足隨意瞄上兩眼损敷,把言辭內(nèi)容不妥的地方指出來(lái)户辫,我們共同討論。
最近有時(shí)間嗤锉,想把醞釀的幾篇博客都寫(xiě)出來(lái),今天前端小學(xué)生帶著10個(gè)問(wèn)題墓塌,跟大家分享一下學(xué)習(xí)CSS的一些體會(huì)瘟忱,我覺(jué)得想學(xué)好CSS,必須保持一顆好奇心和刨根問(wèn)底的勁頭苫幢,而不是復(fù)制粘貼访诱,得過(guò)且過(guò)。本人能力有限韩肝,這篇文章從構(gòu)思加完成用了四五天触菜,如果你和我一樣是前端小白,不妨仔細(xì)斟酌體會(huì)哀峻,以期領(lǐng)悟到一些東西涡相;如果你是業(yè)界大牛,也請(qǐng)你駐足隨意瞄上兩眼剩蟀,把言辭內(nèi)容不妥的地方指出來(lái)催蝗,我們共同討論。
時(shí)刻保持好奇心
第一問(wèn):當(dāng)margin的值為百分比形式時(shí)育特,為什么瀏覽器會(huì)根據(jù)父容器寬度得出計(jì)算值丙号?
在我之前一篇博客檢驗(yàn)?zāi)愕那岸嘶A(chǔ)——Sit the test中,聊到了margin值為時(shí)的計(jì)算方法缰冤。假如有一個(gè)父容器寬度400px犬缨,高度600px,其子元素設(shè)置margin:20% 20%后的計(jì)算值應(yīng)該為“margin:120px 80px”還是“margin:80px 80px”呢棉浸?按照那篇博客中的理論怀薛,第二個(gè)是正確答案。但是在今天這篇文章中涮拗,我給出的答案是第一個(gè)肯定錯(cuò)乾戏,第二個(gè)也不一定對(duì)。一個(gè)符合W3C標(biāo)準(zhǔn)的瀏覽器會(huì)根據(jù)父容器的寬度進(jìn)行計(jì)算三热,但是這個(gè)僅限于書(shū)寫(xiě)模式為橫向的時(shí)候鼓择。因?yàn)樵跈M向排版時(shí),寬度“有跡可循”就漾,可以把瀏覽器寬度作為參考呐能,但是高度是不固定的,所以margin百分比值在計(jì)算時(shí)會(huì)參考父容器的寬度。當(dāng)書(shū)寫(xiě)模式改為縱向摆出,其計(jì)算參考便會(huì)變?yōu)楦溉萜鞯母叨攘恕?/b>戳我查看DEMO(請(qǐng)?jiān)趙ebkit內(nèi)核或IE下查看)朗徊。
/*修改書(shū)寫(xiě)模式*/
.demo{-webkit-writing-mode:vertical-rl;/*for browsers of webkit engine*/writing-mode:tb-rl;/*for ie*/
}
第二問(wèn):margin:auto為什么只能實(shí)現(xiàn)水平居中,不能垂直居中偎漫?
當(dāng)一個(gè)常規(guī)流中塊級(jí)元素的margin屬性左右值設(shè)為關(guān)鍵字auto爷恳,且它擁有固定寬度時(shí),它便會(huì)平分剩余的水平空間象踊,居中顯示温亲。然而如果設(shè)置上下值為auto,瀏覽器得到的計(jì)算值為0杯矩,并不起任何的效果栈虚。那么問(wèn)題來(lái)了,為什么垂直方向的auto不生效史隆?
與上一問(wèn)類(lèi)似魂务,這與布局相關(guān)。網(wǎng)頁(yè)排版時(shí)泌射,常規(guī)流的塊級(jí)元素水平方向總是鋪滿(mǎn)瀏覽器窗口粘姜,垂直方向各塊級(jí)元素按照先后順序從上往下排列,當(dāng)頁(yè)面內(nèi)容過(guò)多時(shí)網(wǎng)頁(yè)會(huì)出現(xiàn)縱向滾動(dòng)條熔酷,因此原理上縱向是可以無(wú)限擴(kuò)展的相艇,計(jì)算時(shí)找不到一個(gè)固定的參考值,所以縱向的auto無(wú)法生效纯陨。
同樣坛芽,margin:auto會(huì)受書(shū)寫(xiě)模式的影響。當(dāng)書(shū)寫(xiě)模式為縱向時(shí)翼抠,margin:auto垂直方向是可以居中的咙轩,水平方向仍然可以居中。不信阴颖?請(qǐng)自己寫(xiě)個(gè)demo試試吧活喊。其實(shí)受到書(shū)寫(xiě)模式影響的屬性除了這些外,還有margin折疊量愧、padding百分比值的計(jì)算等钾菊。
第三問(wèn):可以讓一個(gè)position:fixed的元素相對(duì)于一個(gè)容器定位而非瀏覽器視口嗎?
提到position:fixed偎肃,很多人都會(huì)說(shuō)這是一個(gè)定位屬性煞烫,與absolute的區(qū)別是它針對(duì)瀏覽器視口定位。我的博客導(dǎo)航欄就是利用“position:fixed”屬性累颂,讓其始終保持在窗口的最上方滞详。不過(guò)還是不要忘記“世事無(wú)絕對(duì)”凛俱,CSS實(shí)現(xiàn)了一個(gè)position:fixed的元素相對(duì)于一個(gè)容器定位,請(qǐng)?jiān)贔ireFox下查看此DEMO料饥。
當(dāng)一個(gè)元素應(yīng)用了CSS3的transform屬性后蒲犬,它的后代元素的fixed都將失效。http://www.w3.org/TR/css3-transforms/#issue-ca2c412c岸啡。因此可以利用這個(gè)Bug模擬出一個(gè)相對(duì)于某個(gè)包含塊fixed的效果原叮。
關(guān)于transform更多的影響可以在張?chǎng)涡竦牟┛椭锌吹剑?a target="_blank" rel="nofollow">CSS3 transform對(duì)普通元素的N多渲染影響。
第四問(wèn):可以用CSS實(shí)現(xiàn)面板的隱藏和顯示嗎巡蘸?
現(xiàn)在要實(shí)現(xiàn)這樣一個(gè)功能篇裁,通過(guò)CSS切換某個(gè)面板的顯示或隱藏。當(dāng)提到CSS赡若,我們自然而然想到了控制某個(gè)單一元素的樣式,一旦涉及到多個(gè)元素交互团甲,我們往往使用JavaScript操作Dom逾冬。事實(shí)上這個(gè)需求不但可以用CSS來(lái)實(shí)現(xiàn),甚至實(shí)現(xiàn)方式不止一種躺苦,請(qǐng)狂戳DEMO:三種CSS方式實(shí)現(xiàn)面板隱藏和顯示身腻。
第一種利用了label和checkbox,使控制方和被控制方不需要有特定的HTML結(jié)構(gòu)關(guān)系匹厘,但是需要額外的HTML標(biāo)簽來(lái)支持嘀趟。第二種方式利用了hover和子元素選擇器,第三種方式利用了focus和兄弟元素選擇器愈诚,后兩種都受限于特定的HTML結(jié)構(gòu)她按。三種方法都只使用CSS實(shí)現(xiàn)了面板的隱藏顯示。
第五問(wèn):可以用CSS做出一個(gè)圖標(biāo)嗎炕柔?比如一個(gè)三角形酌泰?一個(gè)小房子?
一個(gè)標(biāo)簽匕累,放在HTML中陵刹,只能代表一種語(yǔ)義。然而一個(gè)標(biāo)簽加CSS欢嘿,則可以創(chuàng)造出無(wú)限的可能衰琐。請(qǐng)看DEMO:CSS實(shí)現(xiàn)三角形,小房子圖案炼蹦。
利用border互相覆蓋呈現(xiàn)出的斜線(xiàn)羡宙,可以模擬出多種多樣的幾何狀。在CSS3中掐隐,每個(gè)元素都有::before和::after兩個(gè)偽元素辛辨,對(duì)同一個(gè)標(biāo)簽,由CSS可以操控的單位由一個(gè)變?yōu)槿齻€(gè),再加上絕對(duì)定位的輔佐斗搞,各種各樣的形狀被創(chuàng)造了出來(lái)指攒。
你能想象嗎?這些圖標(biāo)都是用CSS畫(huà)出來(lái)的僻焚。要想了解更多的CSS3圖標(biāo)允悦,可以訪(fǎng)問(wèn)這個(gè)網(wǎng)站:http://www.uiplayground.in/css3-icons/
第六問(wèn):我想寫(xiě)針對(duì)IE6,7的hack虑啤,該怎么寫(xiě)呢隙弛?
你可能會(huì)這么回答:使用 “>”,“_”狞山,“*”等各種各樣的符號(hào)來(lái)寫(xiě)hack全闷。是的,這樣做沒(méi)錯(cuò)萍启,但是需要記住每個(gè)符號(hào)分別被哪些瀏覽器識(shí)別总珠,并且如果寫(xiě)的太亂將造成代碼 閱讀起來(lái)十分困難。學(xué)習(xí)CSS必須抱有一種質(zhì)疑精神勘纯,有沒(méi)有一種hack方法可以不寫(xiě)這些亂七八糟的符號(hào)局服,并且代碼易維護(hù)易讀呢?我們可以看看好搜首頁(yè)是怎么做的:在頁(yè)面頂端有這樣一句話(huà):
在頁(yè)面的CSS中驳遵,會(huì)看到這樣的規(guī)則:
.ie7 #hd_usernav:before, .ie8 #hd_usernav:before {display:none}.ie6 .skin_no #hd_nav li, .ie7 .skin_no #hd_nav li, .ie8 .skin_no #hd_nav li {border-right-color:#c5c5c5}.ie6 .skin_no #hd_nav a, .ie7 .skin_no #hd_nav a, .ie8 .skin_no #hd_nav a {color:#c5c5c5}……
這樣做的優(yōu)點(diǎn)就是克服了使用特殊符號(hào)hack的那些缺點(diǎn)淫奔,缺點(diǎn)是需要寫(xiě)更多的代碼,使頁(yè)面增大堤结。
一個(gè)前端er對(duì)上面這些問(wèn)題知道與否唆迁,并不影響他是否可以完成一個(gè)項(xiàng)目,建設(shè)一個(gè)網(wǎng)站竞穷。但是如果沒(méi)有好奇心媒惕,不想追究?jī)?nèi)在原因,僅抱著“我不想知道這么多東西来庭,反正我會(huì)用就行”這樣一種態(tài)度妒蔚,那么他充其量算是一個(gè)“程序員”,而非一位“工程師”月弛。
就是要刨根問(wèn)底肴盏!
第七問(wèn):行內(nèi)級(jí)元素可以設(shè)置寬高嗎?
不會(huì)為自身內(nèi)容形成新的塊帽衙,而讓內(nèi)容分布在多行中的元素叫做行內(nèi)級(jí)元素菜皂。此類(lèi)元素可以與其它行內(nèi)級(jí)元素在同一行中顯示而不會(huì)另起一行,例如span厉萝,strong恍飘。在面試時(shí)榨崩,當(dāng)被問(wèn)到行內(nèi)級(jí)元素可否設(shè)置寬高時(shí),根據(jù)我們的經(jīng)驗(yàn)往往會(huì)回答不能章母。但是這樣往往著了面試官的道母蛛,因?yàn)橛幸恍┨厥獾男袃?nèi)元素,比如img乳怎,input彩郊,select等等,是可以被設(shè)置寬高的蚪缀。一個(gè)內(nèi)容不受CSS視覺(jué)格式化模型控制秫逝,CSS渲染模型并不考慮對(duì)此內(nèi)容的渲染,且元素本身一般擁有固有尺寸(寬度询枚,高度违帆,寬高比)的元素,被稱(chēng)之為置換元素金蜀。比如img是一個(gè)置換元素刷后,當(dāng)不對(duì)它設(shè)置寬高時(shí),它會(huì)按照本身的寬高進(jìn)行顯示廉油。所以這個(gè)問(wèn)題的正確答案應(yīng)該是置換元素可以,非置換元素不可以苗傅。
第八問(wèn):CSS規(guī)則根據(jù)優(yōu)先級(jí)生效抒线,低優(yōu)先級(jí)的規(guī)則會(huì)被瀏覽器忽略還是覆蓋?
在我的之前一篇博客中渣慕,提到了瀏覽器中CSS優(yōu)先級(jí)的使用規(guī)則:多個(gè)優(yōu)先級(jí)的樣式都會(huì)被渲染嘶炭,只不過(guò)高優(yōu)先級(jí)會(huì)覆蓋住低優(yōu)先級(jí),元素呈現(xiàn)為高優(yōu)先級(jí)的樣式⊙疯耄現(xiàn)在請(qǐng)考慮這樣一個(gè)問(wèn)題眨猎,在一個(gè)div應(yīng)用了兩條background-image規(guī)則,照之前的理論來(lái)看强经,兩條規(guī)則都會(huì)渲染睡陪,那么請(qǐng)問(wèn)瀏覽器會(huì)請(qǐng)求被覆蓋規(guī)則的背景圖片嗎?
真實(shí)情況是瀏覽器會(huì)聰明到只請(qǐng)求當(dāng)前應(yīng)用的背景圖片匿情。簡(jiǎn)單理解的話(huà)兰迫,瀏覽器只會(huì)為生效的CSS規(guī)則中的圖片資源發(fā)出http請(qǐng)求。如果深究的話(huà)炬称,就必須談?wù)劄g覽器的工作原理了汁果。本人目前水平不夠,以下紅色字體為個(gè)人理解玲躯,請(qǐng)選擇性閱讀据德。
在現(xiàn)代瀏覽器中鳄乏,一個(gè)頁(yè)面從請(qǐng)求到呈現(xiàn),大致需要經(jīng)過(guò)解析-構(gòu)建DOM樹(shù)-構(gòu)建呈現(xiàn)樹(shù)(框架樹(shù))-布局(重排)-繪制等幾個(gè)步驟棘利。一個(gè)頁(yè)面的展現(xiàn)并不是一蹴而就的橱野,而是分步驟有條不紊的進(jìn)行。眾所周知的樣式表層疊順序和特異性計(jì)算發(fā)生在構(gòu)造呈現(xiàn)樹(shù)的過(guò)程中赡译,就是為了解決規(guī)則不止一個(gè)時(shí)的問(wèn)題仲吏。以上面提到的背景圖案為例,瀏覽器計(jì)算完優(yōu)先級(jí)后蝌焚,只有后定義的背景圖案規(guī)則被構(gòu)建到呈現(xiàn)樹(shù)上裹唆。接下來(lái)瀏覽器會(huì)進(jìn)行重排和繪制,瀏覽器在繪制時(shí)才會(huì)請(qǐng)求背景圖片規(guī)則用到的圖片文件只洒。這就是為什么只發(fā)出一個(gè)HTTP請(qǐng)求的原因许帐。
了解瀏覽器的工作原理不僅可以認(rèn)清CSS解析和渲染過(guò)程,還可以體會(huì)到重排和重繪發(fā)生的時(shí)機(jī)毕谴,這對(duì)我們寫(xiě)出高效的CSS規(guī)則和JavaScript Dom操作有著非常深刻的指導(dǎo)意義成畦。這個(gè)話(huà)題太大,目前我的水平也不足以涉獵到此涝开,等學(xué)有所成后我會(huì)再發(fā)一篇文章詳細(xì)談?wù)勓省_@里有一篇經(jīng)典的文章,感興趣的可以看看:瀏覽器的工作原理:新式網(wǎng)絡(luò)瀏覽器幕后揭秘舀武。如果無(wú)法訪(fǎng)問(wèn)拄养,查看此國(guó)內(nèi)地址:w3ctech:瀏覽器的工作原理。
第九問(wèn):使用margin可以做出圓角按鈕的原理是什么银舱?
當(dāng)不能使用border-radius時(shí)瘪匿,如何制造一個(gè)圓角按鈕?現(xiàn)在有一個(gè)制造1px圓角的小技巧:button中嵌套span寻馏,設(shè)置span的margin為:“margin:1px -1px”棋弥。戳我查看DEMO。
知道這個(gè)小tip的人不在少數(shù)诚欠,那么是什么原理導(dǎo)致這種現(xiàn)象呢顽染?學(xué)習(xí)CSS就需要刨根問(wèn)底,一張圖可以把這個(gè)問(wèn)題說(shuō)明白轰绵。
圖中紅色框?yàn)閟pan標(biāo)簽家乘,藍(lán)色框?yàn)閍標(biāo)簽。當(dāng)設(shè)置span的左右margin為-1px時(shí)藏澳,其便會(huì)在左右各突出1px仁锯,造成一種1px圓角的視覺(jué)效果。同樣的道理翔悠,在實(shí)現(xiàn)一些古老瀏覽器下的圓角與底色漸變的按鈕時(shí)业崖,通常也會(huì)利用到多層元素層疊制造視覺(jué)誤差的原理野芒。
第十問(wèn):清除浮動(dòng)有N種方式,他們間有什么共同點(diǎn)嗎双炕?
所謂清除浮動(dòng)狞悲,一般是為了解決子元素浮動(dòng)導(dǎo)致父容器高度坍塌。目前有多種方式來(lái)解決這個(gè)問(wèn)題妇斤,最常見(jiàn)的有after偽元素摇锋,父元素設(shè)置“overflow:hidden”等等,請(qǐng)看DEMO:七種清除浮動(dòng)的方法站超。
其實(shí)按照原理荸恕,這幾種方法可以歸納為兩種:clear:both法和構(gòu)造BFC法。
方法分類(lèi)
浮動(dòng)末尾添加新標(biāo)簽死相,設(shè)置樣式為clear:bothclear:both
浮動(dòng)末尾添加
標(biāo)簽clear:both
使用::after偽元素clear:both
父元素設(shè)置display:table構(gòu)造BFC
父元素設(shè)置overflow:auto構(gòu)造BFC
父元素設(shè)置overflow:hidden構(gòu)造BFC
讓父元素也浮動(dòng)構(gòu)造BFC
使用“clear:both”來(lái)清除浮動(dòng)自然不必多說(shuō)融求,那么什么是構(gòu)造BFC法呢?
Block formatting contexts(BFC)算撮,塊級(jí)格式化上下文是在CSS2.1中提出的一個(gè)概念生宛,在布局中,BFC自成體系肮柜,對(duì)自己內(nèi)部的元素負(fù)責(zé)陷舅,不會(huì)與浮動(dòng)元素重疊,相鄰BFC上下margin也不會(huì)重疊审洞。所以我們會(huì)通過(guò)構(gòu)造一個(gè)BFC來(lái)防止margin重疊莱睁,清除浮動(dòng)或者實(shí)現(xiàn)一個(gè)雙欄布局。
那么如何構(gòu)造一個(gè)BFC呢预明?1.float設(shè)置為非none值缩赛;2.overflow設(shè)置為非visible耙箍;3.display設(shè)置為table-cell撰糠,table-caption,inline-block辩昆;4.position設(shè)置為absolute或fixed阅酪。這些方法剛好與上面提到構(gòu)造BFC來(lái)清除浮動(dòng)的方法相呼應(yīng)。
需要特別注意的是汁针,在IE6术辐,7下沒(méi)有BFC這個(gè)概念,但是有一個(gè)與BFC性質(zhì)相似的概念:layout施无。在IE6辉词,7中遇到的很多bug都可以通過(guò)讓元素has layout來(lái)解決,比如浮動(dòng)margin雙邊距猾骡,躲貓貓瑞躺,3像素間距等等敷搪。
有些元素例如table,input本身就has layout幢哨,那么如何讓一個(gè)普通元素has?layout呢赡勘?包括但不限于以下幾種方法:1.position:absolute;2.float不為none捞镰;3.display:inline-block闸与;4.height:除auto外任意值;5.width:除auto外任意值岸售;6.zoom:除normal外任意值践樱;7.overflow非visible(僅限IE7)。
這也是為什么我們會(huì)在IEhack中經(jīng)潮溃看到“height:1%”映胁、“zoom:1”、“display:inline-block”甲雅、“overflow:hidden”這些字眼的主要原因解孙,其實(shí)就是為了讓元素has layout嘛!
所以在IE6-7下抛人,清除浮動(dòng)除了可以使用clear:both外(::after偽元素?zé)o法使用)弛姜,另一種方法就是讓父元素has layout。
關(guān)于清除浮動(dòng)更多的探討可以在一絲冰涼的博客中看到:那些年我們一起清除過(guò)的浮動(dòng)妖枚。
總結(jié)
學(xué)習(xí)任何一門(mén)語(yǔ)言廷臼,或者一個(gè)事物都不能得過(guò)且過(guò),抱著前人播種后人收的思想绝页≤蹋縱然站在巨人的肩膀上可以少走很多彎路,但是個(gè)人仍然要保持好奇心和刨根問(wèn)底续誉、質(zhì)疑的精神莱没。多想一下“為什么”,少記一些“該這樣做”酷鸦,這在CSS的學(xué)習(xí)中尤其重要饰躲。
CSS很簡(jiǎn)單,她的出現(xiàn)僅僅是為了排版臼隔。CSS很復(fù)雜嘹裂,一個(gè)簡(jiǎn)單的排版往往有N種解決方案。
http://www.cnblogs.com/dongtianee/p/4563084.html
本文為云棲社區(qū)原創(chuàng)內(nèi)容摔握,未經(jīng)允許不得轉(zhuǎn)載寄狼,如需轉(zhuǎn)載請(qǐng)發(fā)送郵件至yqeditor@list.alibaba-inc.com;如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容氨淌,歡迎發(fā)送郵件至:yqgroup@service.aliyun.com 進(jìn)行舉報(bào)泊愧,并提供相關(guān)證據(jù)狡逢,一經(jīng)查實(shí),本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容拼卵。