CSS十問——好奇心+刨根問底=CSSer

  最近有時間,想把醞釀的幾篇博客都寫出來,今天前端小學生帶着10個問題,跟你們分享一下學習CSS的一些體會,我以爲想學好CSS,必須保持一顆好奇心和刨根問底的勁頭,而不是複製粘貼,得過且過。本人能力有限,這篇文章從構思加完成用了四五天,若是你和我同樣是前端小白,不妨仔細斟酌體會,以期領悟到一些東西;若是你是業界大牛,也請你駐足隨意瞄上兩眼,把言辭內容不妥的地方指出來,咱們共同討論。css

時刻保持好奇心html

  第一問:當margin的值爲百分比形式時,爲何瀏覽器會根據父容器寬度得出計算值?前端

  在我以前一篇博客檢驗你的前端基礎——Sit the test中,聊到了margin值爲<percentage>時的計算方法。假若有一個父容器寬度400px,高度600px,其子元素設置margin:20% 20%後的計算值應該爲「margin:120px 80px」仍是「margin:80px 80px」呢?按照那篇博客中的理論,第二個是正確答案。可是在今天這篇文章中,我給出的答案是第一個確定錯,第二個也不必定對。一個符合W3C標準的瀏覽器會根據父容器的寬度進行計算,可是這個僅限於書寫模式爲橫向的時候。由於在橫向排版時,寬度「有跡可循」,能夠把瀏覽器寬度做爲參考,可是高度是不固定的,因此margin百分比值在計算時會參考父容器的寬度。當書寫模式改成縱向,其計算參考便會變爲父容器的高度了。戳我查看DEMO(請在webkit內核或IE下查看)。html5

/*修改書寫模式*/
.demo
{ -webkit-writing-mode: vertical-rl; /* for browsers of webkit engine */    writing-mode: tb-rl; /* for ie */ }

  第二問:margin:auto爲何只能實現水平居中,不能垂直居中?css3

  當一個常規流塊級元素的margin屬性左右值設爲關鍵字auto,且它擁有固定寬度時,它便會平分剩餘的水平空間,居中顯示。然而若是設置上下值爲auto,瀏覽器獲得的計算值爲0,並不起任何的效果。那麼問題來了,爲何垂直方向的auto不生效?程序員

  與上一問相似,這與佈局相關。網頁排版時,常規流的塊級元素水平方向老是鋪滿瀏覽器窗口,垂直方向各塊級元素按照前後順序從上往下排列,當頁面內容過多時網頁會出現縱向滾動條,所以原理上縱向是能夠無限擴展的,計算時找不到一個固定的參考值,因此縱向的auto沒法生效。web

  一樣,margin:auto會受書寫模式的影響。當書寫模式爲縱向時,margin:auto垂直方向是能夠居中的,水平方向仍然能夠居中(僅當父元素爲body時,見下方評論)。不信?請本身寫個demo試試吧。其實受到書寫模式影響的屬性除了這些外,還有margin摺疊、padding百分比值的計算等。面試

  第三問:可讓一個position:fixed的元素相對於一個容器定位而非瀏覽器視口嗎?瀏覽器

  提到position:fixed,不少人都會說這是一個定位屬性,與absolute的區別是它針對瀏覽器視口定位。個人博客導航欄就是利用「position:fixed」屬性,讓其始終保持在窗口的最上方。不過仍是不要忘記「世事無絕對」,CSS實現了一個position:fixed的元素相對於一個容器定位,請在FireFox下查看此DEMO網絡

  當一個元素應用了CSS3的transform屬性後,它的後代元素的fixed都將失效。http://www.w3.org/TR/css3-transforms/#issue-ca2c412c。所以能夠利用這個Bug模擬出一個相對於某個包含塊fixed的效果。

  關於transform更多的影響能夠在張鑫旭的博客中看到:CSS3 transform對普通元素的N多渲染影響

  第四問:能夠用CSS實現面板的隱藏和顯示嗎?

  如今要實現這樣一個功能,經過CSS切換某個面板的顯示或隱藏。當提到CSS,咱們天然而然想到了控制某個單一元素的樣式,一旦涉及到多個元素交互,咱們每每使用JavaScript操做Dom。事實上這個需求不但能夠用CSS來實現,甚至實現方式不止一種,請狂戳DEMO:三種CSS方式實現面板隱藏和顯示

  第一種利用了label和checkbox,使控制方和被控制方不須要有特定的HTML結構關係,可是須要額外的HTML標籤來支持。第二種方式利用了hover和子元素選擇器,第三種方式利用了focus和兄弟元素選擇器,後兩種都受限於特定的HTML結構。三種方法都只使用CSS實現了面板的隱藏顯示。

  第五問:能夠用CSS作出一個圖標嗎?好比一個三角形?一個小房子?

  一個標籤,放在HTML中,只能表明一種語義。然而一個標籤加CSS,則能夠創造出無限的可能。請看DEMO:CSS實現三角形,小房子圖案

  利用border互相覆蓋呈現出的斜線,能夠模擬出多種多樣的幾何狀。在CSS3中,每一個元素都有::before和::after兩個僞元素,對同一個標籤,由CSS能夠操控的單位由一個變爲三個,再加上絕對定位的輔佐,各類各樣的形狀被創造了出來。

css3-icons

  你能想象嗎?這些圖標都是用CSS畫出來的。要想了解更多的CSS3圖標,能夠訪問這個網站:http://www.uiplayground.in/css3-icons/

  第六問:我想寫針對IE6,7的hack,該怎麼寫呢?

  你可能會這麼回答:使用 「>」,「_」,「*」等各類各樣的符號來寫hack。是的,這樣作沒錯,可是須要記住每一個符號分別被哪些瀏覽器識別,而且若是寫的太亂將形成代碼 閱讀起來十分困難。學習CSS必須抱有一種質疑精神,有沒有一種hack方法能夠不寫這些亂七八糟的符號,而且代碼易維護易讀呢?咱們能夠看看好搜首頁是怎麼作的:在頁面頂端有這樣一句話:

<!DOCTYPE html> <!--[if lt IE 7 ]><html class="ie6"><![endif]--> <!--[if IE 7 ]><html class="ie7"><![endif]--> <!--[if IE 8 ]><html class="ie8"><![endif]--> <!--[if IE 9 ]><html class="ie9"><![endif]--> <!--[if (gt IE 9)|!(IE)]><!--><html class="w3c"><!--<![endif]--> <head>

  在頁面的CSS中,會看到這樣的規則:

.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 } ……

  這樣作的優勢就是克服了使用特殊符號hack的那些缺點,缺點是須要寫更多的代碼,使頁面增大。

  一個前端er對上面這些問題知道與否,並不影響他是否能夠完成一個項目,建設一個網站。可是若是沒有好奇心,不想追究內在緣由,僅抱着「我不想知道這麼多東西,反正我會用就行」這樣一種態度,那麼他充其量算是一個「程序員」,而非一位「工程師」。

就是要刨根問底!

  第七問:行內級元素能夠設置寬高嗎?

  不會爲自身內容造成新的塊,而讓內容分佈在多行中的元素叫作行內級元素。此類元素能夠與其它行內級元素在同一行中顯示而不會另起一行,例如span,strong。在面試時,當被問到行內級元素能否設置寬高時,根據咱們的經驗每每會回答不能。可是這樣每每着了面試官的道,由於有一些特殊的行內元素,好比img,input,select等等,是能夠被設置寬高的。一個內容不受CSS視覺格式化模型控制,CSS渲染模型並不考慮對此內容的渲染,且元素自己通常擁有固有尺寸(寬度,高度,寬高比)的元素,被稱之爲置換元素。好比img是一個置換元素,當不對它設置寬高時,它會按照自己的寬高進行顯示。因此這個問題的正確答案應該是置換元素能夠,非置換元素不能夠

  第八問:CSS規則根據優先級生效,低優先級的規則會被瀏覽器忽略仍是覆蓋?

  在個人以前一篇博客中,提到了瀏覽器中CSS優先級的使用規則:多個優先級的樣式都會被渲染,只不太高優先級會覆蓋住低優先級,元素呈現爲高優先級的樣式。如今請考慮這樣一個問題,在一個div應用了兩條background-image規則,照以前的理論來看,兩條規則都會渲染,那麼請問瀏覽器會請求被覆蓋規則的背景圖片嗎?

  真實狀況是瀏覽器會聰明到只請求當前應用的背景圖片。簡單理解的話,瀏覽器只會爲生效的CSS規則中的圖片資源發出http請求。若是深究的話,就必須談談瀏覽器的工做原理了。本人目前水平不夠,如下紅色字體爲我的理解,請選擇性閱讀。

  在現代瀏覽器中,一個頁面從請求到呈現,大體須要通過解析-構建DOM樹-構建呈現樹(框架樹)-佈局(重排)-繪製等幾個步驟。一個頁面的展示並非一蹴而就的,而是分步驟有條不紊的進行。衆所周知的樣式表層疊順序和特異性計算發生在構造呈現樹的過程當中,就是爲了解決規則不止一個時的問題。以上面提到的背景圖案爲例,瀏覽器計算完優先級後,只有後定義的背景圖案規則被構建到呈現樹上。接下來瀏覽器會進行重排和繪製,瀏覽器在繪製時纔會請求背景圖片規則用到的圖片文件。這就是爲何只發出一個HTTP請求的緣由。

  瞭解瀏覽器的工做原理不只能夠認清CSS解析和渲染過程,還能夠體會到重排和重繪發生的時機,這對咱們寫出高效的CSS規則和JavaScript Dom操做有着很是深入的指導意義。這個話題太大,目前個人水平也不足以涉獵到此,等學有所成後我會再發一篇文章詳細談談。這裏有一篇經典的文章,感興趣的能夠看看:瀏覽器的工做原理:新式網絡瀏覽器幕後揭祕。若是沒法訪問,查看此國內地址:w3ctech:瀏覽器的工做原理

  第九問:使用margin能夠作出圓角按鈕的原理是什麼?

  當不能使用border-radius時,如何製造一個圓角按鈕?如今有一個製造1px圓角的小技巧:button中嵌套span,設置span的margin爲:「margin:1px -1px」。戳我查看DEMO

  知道這個小tip的人不在少數,那麼是什麼原理致使這種現象呢?學習CSS就須要刨根問底,一張圖能夠把這個問題說明白。

  圖中紅色框爲span標籤,藍色框爲a標籤。當設置span的左右margin爲-1px時,其便會在左右各突出1px,形成一種1px圓角的視覺效果。一樣的道理,在實現一些古老瀏覽器下的圓角與底色漸變的按鈕時,一般也會利用到多層元素層疊製造視覺偏差的原理。

  第十問:清除浮動有N種方式,他們間有什麼共同點嗎?

  所謂清除浮動,通常是爲了解決子元素浮動致使父容器高度坍塌。目前有多種方式來解決這個問題,最多見的有after僞元素,父元素設置「overflow:hidden」等等,請看DEMO:七種清除浮動的方法

  其實按照原理,這幾種方法能夠概括爲兩種:clear:both法和構造BFC法。

方法 分類
浮動末尾添加新標籤,設置樣式爲clear:both clear:both
浮動末尾添加<br />標籤 clear:both
使用::after僞元素 clear:both
父元素設置display:table 構造BFC
父元素設置overflow:auto 構造BFC
父元素設置overflow:hidden 構造BFC
讓父元素也浮動 構造BFC

  使用「clear:both」來清除浮動天然沒必要多說,那麼什麼是構造BFC法呢?

  Block formatting contexts(BFC),塊級格式化上下文是在CSS2.1中提出的一個概念,在佈局中,BFC自成體系,對本身內部的元素負責,不會與浮動元素重疊,相鄰BFC上下margin也不會重疊。因此咱們會經過構造一個BFC來防止margin重疊,清除浮動或者實現一個雙欄佈局。

  那麼如何構造一個BFC呢?1.float設置爲非none值;2.overflow設置爲非visible;3.display設置爲table-cell,table-caption,inline-block;4.position設置爲absolute或fixed。這些方法恰好與上面提到構造BFC來清除浮動的方法相呼應。

  須要特別注意的是,在IE6,7下沒有BFC這個概念,可是有一個與BFC性質類似的概念:layout。在IE6,7中遇到的不少bug均可以經過讓元素has layout來解決,好比浮動margin雙邊距,躲貓貓,3像素間距等等。

  有些元素例如table,input自己就has layout,那麼如何讓一個普通元素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)。

  這也是爲何咱們會在IEhack中常常看到「height:1%」、「zoom:1」、「display:inline-block」、「overflow:hidden」這些字眼的主要緣由,其實就是爲了讓元素has layout嘛!

  因此在IE6-7下,清除浮動除了可使用clear:both外(::after僞元素沒法使用),另外一種方法就是讓父元素has layout。

  關於清除浮動更多的探討能夠在一絲冰涼的博客中看到:那些年咱們一塊兒清除過的浮動

總結

  學習任何一門語言,或者一個事物都不能得過且過,抱着前人播種後人收的思想。縱然站在巨人的肩膀上能夠少走不少彎路,可是我的仍然要保持好奇心和刨根問底、質疑的精神。多想一下「爲何」,少記一些「該這樣作」,這在CSS的學習中尤爲重要。

  CSS很簡單,她的出現僅僅是爲了排版。CSS很複雜,一個簡單的排版每每有N種解決方案。

  望諸君共勉。

  (完)

相關文章
相關標籤/搜索