摘要:除了其本身的語法規(guī)則,我們必須自我約束,引入語義規(guī)則,不僅僅是為了提高可讀性這樣的理由,而是拉近人與機(jī)器的距離,讓我們在思維上更加和代碼契合,這樣才能寫出優(yōu)秀的程序。
前一陣子在項(xiàng)目組中講了一個關(guān)于CSS的Session,在講之前我曾收到了許多意見,大部分是希望能講講CSS實(shí)用性的技術(shù),比如盒模型,CSS3之類的。干貨人人都喜歡,因?yàn)榭吹靡娒弥脕砭陀杏茫易詈筮€是決定講一些”濕貨“。因?yàn)樵贑ode Diff的時候我發(fā)現(xiàn)了許多樣式的問題不是由于不會寫CSS導(dǎo)致的,而是由于在錯誤的地方使用了寫在錯誤地方的樣式。
其實(shí)CSS很簡單,沒有計(jì)算沒有流程,只是一直描述,無論什么復(fù)雜的效果,你只要Google一下就知道怎么寫了,甚至可以直接copy。但CSS又很復(fù)雜,一個元素的表現(xiàn)會受到它旁邊的兄弟元素,也會受到內(nèi)部的子元素影響,還會受到父元素影響,在這種多重影響下,一個元素的顯示邏輯會變得錯綜復(fù)雜。有沒有面對塌陷的塊級元素而束手無策?無論怎么改它的屬性就是得不到自己想要的,但看看似乎一模一樣的示例程序卻安然無恙,是不是恨得咬牙切齒?我想這就是本文所要解決的主要問題,讓你學(xué)會如何優(yōu)雅的寫CSS。
涇渭分明 - 明確書寫意圖和表現(xiàn)語義其實(shí)我們只要稍微接觸過CSS,一定都學(xué)過盒模型,我假設(shè)你已經(jīng)對margin、padding和border已經(jīng)很熟悉。好了,我們經(jīng)常會遇到一種情況,想讓父元素和子元素之間有一些空間,比如布局的時候,container和content之間的留白。一般來說有兩種方式,一種是給父元素加padding內(nèi)邊距,另一種是給子元素加margin外邊距。現(xiàn)在想想,你是否慎重考慮過用哪一種方式?你是否明白兩者的區(qū)別?如果你從未考慮過這些,現(xiàn)在考慮也不遲,這真的很重要,如果你真的想優(yōu)雅的運(yùn)用CSS,而不是被它耍的團(tuán)團(tuán)轉(zhuǎn),如果你真的想把CSS寫出規(guī)模,那你就要認(rèn)真的思考這里面的邏輯。
先說說父元素的container加上padding的方式,子元素的背景將不會延伸到空白區(qū)域,另一種給子元素加margin的方式則反之。但我想先拋下這個表象,看看此時加上padding的父元素的邏輯。它意味著,我創(chuàng)建了一個容器,并且該容器的內(nèi)部有一些區(qū)域是被看不見的東西填充的,無論放入什么都不應(yīng)該占據(jù)這個區(qū)域。在你的腦海中想象一個厚厚的玻璃瓶,它就好像是在說“雖然我是透明的,但是在這厚厚的玻璃之內(nèi)才是你應(yīng)該呆的地方,無論是什么只要你想放在瓶子里”。現(xiàn)在來看看子元素,是的,其背景也應(yīng)該并且確實(shí)在內(nèi)部,而不該占據(jù)那段空白的區(qū)域。如果是為子元素加上margin,這意味著我在容器中創(chuàng)建了某個東西,而這個東西有一個自己的地盤,容器內(nèi)的其他東西都不能進(jìn)入這里。
所以他們的本質(zhì)區(qū)別在于其所表達(dá)的意義,也就是語義,一個是容器上的語義,另一個是容器內(nèi)元素的語義,主語也不同,謂語意義也不同。那么這能說明什么呢,不得不提一下高級語言中的高級,這代表某個語言將機(jī)器語言封裝的更好,接口更接近自然語言,其強(qiáng)大不言而喻。其實(shí)編程語言的發(fā)展軌跡就是不斷把機(jī)器語言往自然語言翻譯,讓人們可以更容易的跟機(jī)器溝通,終極目標(biāo)自然是人工智能,和機(jī)器用自然語言自由溝通。所以雖然代碼或者說CSS的語法并沒有什么變化,但我們應(yīng)該在思維上清楚的區(qū)分代碼片段的意圖和語義來寫CSS。
語言學(xué)家喬姆斯基曾構(gòu)造過一句符合語法的話:
“Colorless green ideas sleep furiously”
意思是無色的綠色想法憤怒的睡覺。想法睡覺是違反常識的,無色的綠色是矛盾的,憤怒的睡覺是不合常理的。僅僅符合語法是不夠的,僅僅不報錯也是不夠的,尤其是CSS這種描述性的語言很少會報錯,所以我想說的是,其描述性質(zhì)讓我們有更多選擇來實(shí)現(xiàn)我們所期望的效果,但我們卻應(yīng)該慎重,要讓語義分明,而不是在有限的語法規(guī)則下任意妄為,那樣寫不出好的CSS代碼。除了其本身的語法規(guī)則,我們必須自我約束,引入語義規(guī)則,不僅僅是為了提高可讀性這樣的理由,而是拉近人與機(jī)器的距離,讓我們在思維上更加和代碼契合,這樣才能寫出優(yōu)秀的程序。
言歸正傳,究竟如何語義化CSS呢。之前有講過OOCSS,其實(shí)面向?qū)ο蟮乃枷刖褪且环N語義化,將虛擬的元素看作實(shí)際的對象,用常識來構(gòu)造代碼,就像是用戶體驗(yàn)中的用戶習(xí)慣一樣,這是一種遍及全人類的用戶習(xí)慣,讓代碼更友好,即所謂的優(yōu)雅。
比如最常見的布局,我們一般都會有header、body和footer,這樣無需任何說明和規(guī)則,誰都會理解,header在前,footer在后,中間是body。有趣的是table中的thead、tbody和tfoot,由于加載優(yōu)化,我們即使把tfoot放在tbody前面,讓其先加載,但顯示的時候tfoot仍然會在tbody下面,由此可見語義化的重要,否則你一定會以為不是W3C的人弄錯了標(biāo)準(zhǔn),就是瀏覽器廠商搞出了Bug。雖然這是HTML標(biāo)簽不是CSS,但我覺得這個例子很恰當(dāng)?shù)恼f明了一點(diǎn),顯示邏輯是獨(dú)立的,不應(yīng)該和其他邏輯混為一談,它應(yīng)該只關(guān)心如何顯示。
再比如,一個導(dǎo)航條一般分為左右兩邊,里面各有若干鏈接。你會如何命名?navbar-left和navbar-right是Bootstrap所使用的class,但當(dāng)寬度減少,Responsive響應(yīng)式的Bootstrap會讓這些鏈接都收進(jìn)下拉菜單中,左和右又從何談起呢?同樣是Bootstrap中的顏色命名就做的十分成熟,不是green、blue、red這些詞匯,而是success、primary、warning這些詞,它們的區(qū)別是表現(xiàn)化與語義化的區(qū)別,我喜歡把這個叫做顯示邏輯。也就是說在class層面我們應(yīng)該只關(guān)注元素(或者說對象)是用來做什么的(意圖)以及它應(yīng)該表示什么(語義)。這里三種顏色代表成功、重要和警告,至于我們是用綠、藍(lán)和紅來表示還是通過其他什么顏色甚至形狀,應(yīng)該在style層面寫CSS屬性表示。如此我們使用class時無需迷茫于表示成功應(yīng)該用綠色還是紅色,意圖明確無誤。回到導(dǎo)航欄的例子,我們應(yīng)該使用main和sub之類的詞語標(biāo)識導(dǎo)航欄中重要的和次要的鏈接,即使在某些實(shí)現(xiàn)下,主要和次要沒有區(qū)別也不用擔(dān)心,那是該實(shí)現(xiàn)的顯示邏輯,我們不應(yīng)該橫加干涉。
狡兔三窟 - 善用class與style多對多的復(fù)雜關(guān)系說到class和style(樣式屬性),這又是一段混亂不清的關(guān)系。其實(shí)每當(dāng)我們要實(shí)現(xiàn)一個樣式,自覺或不自覺的都會考慮,是將元素和class一一對應(yīng),然后為元素上的class寫style,還是用class和幾條style對應(yīng)之后在元素上搭配組合。前者的好處是每個class中的style不會影響其他class,但可用性十分的低,極端點(diǎn)說這已經(jīng)不算是在編程了,而是在畫頁面;后者的好處可以靈活使用不同的樣式搭配給元素使用,組合出元素需要的效果,但很難維護(hù),牽一發(fā)動全身,樣式很難測試,無法保證在你動了一條style之后,沒有影響其他的地方。甚至最要命的是大部分CSS代碼都是無意識的游走在這兩種情況之間,所以我們要做的不是選擇一種極端,而是找到一個平衡點(diǎn),并使用一些方法使得我們的CSS既能靈活復(fù)用在各種元素上,又能易于維護(hù),不致修了這破壞那的情況。
分組首先,對于一個或一套元素的樣式,我們應(yīng)該有自己的創(chuàng)建原則,而不是想到哪寫到哪。比如,我一般使用這樣的步驟來創(chuàng)建元素:
1. 結(jié)構(gòu)首先僅關(guān)注結(jié)構(gòu)布局,以站點(diǎn)整體為基準(zhǔn),將元素抽象為一個或多個結(jié)構(gòu)。
比如制作一個按鈕,你也許會發(fā)現(xiàn)它的尺寸和導(dǎo)航上的鏈接一致,而內(nèi)外邊距以及display和overflow之類的屬性又和頁面容器一樣,這時你就可以把按鈕的結(jié)構(gòu)拆成兩個結(jié)構(gòu),一個是尺寸,一個是邊界邏輯,這種情況時常發(fā)生,所以有的CSS理論認(rèn)為應(yīng)該把width和height這對尺寸屬性和padding以及margin這對邊距屬性徹底的分開也是這個道理。其實(shí)并不是說它們4個放一起就決定不行,只是一般它們都有各自復(fù)用的價值,所以常常被拆開使用,歸根揭底這是由顯示邏輯決定的。
2. 皮膚一般由于設(shè)計(jì)統(tǒng)一性,我們可以借助設(shè)計(jì)指導(dǎo),輕松的制作出標(biāo)準(zhǔn)皮膚。但要注意的是,皮膚指的不僅僅甚至不一定是顏色之類的。繼續(xù)用Bootstrap舉例,有5種基礎(chǔ)顏色,但這并不是皮膚,5種顏色的語義不同,它們只是默認(rèn)用了5種顏色,勉強(qiáng)可以看作默認(rèn)皮膚,而真正的皮膚是theme,讓按鈕變得有立體感。還有一個誤區(qū)就是認(rèn)為哪幾種屬性是皮膚,哪幾種不是。就像前面所說的,我們要在語義上進(jìn)行劃分。一個屬性在某些意圖下可能是結(jié)構(gòu),在另外的意圖中可能是皮膚。
舉個極端的例子,在一個Workshop中我用CSS和HTML制作了左邊這樣的Logo,Logo本身應(yīng)該完全算是皮膚,因?yàn)橐话銇碚f就是一張圖片,所以制作它的所有CSS屬性都應(yīng)該算作皮膚。下面的CSS代碼中,無論是定位還是文字的處理,以及尺寸等,都是為了構(gòu)造Logo,所以這些屬性都是皮膚。
css#logo i, #logo b { position: relative; } #logo i { left: -30px; transform: rotate(-30deg); font-size: 60px; letter-spacing: -11px; opacity: 0.3; } #logo b { top: -43px; left: 40px; font-size: 68px; word-break: break-all; width: 3px; line-height: 10px; text-indent: 6px; }3. 狀態(tài)
除了結(jié)構(gòu)和皮膚,其實(shí)還有一類很容易被人忽視的樣式,即使是設(shè)計(jì)人員也經(jīng)常忘了它,那就是狀態(tài)。最常見的是hover,鼠標(biāo)觸碰元素與否的狀態(tài),以及active,當(dāng)前選中的標(biāo)簽,當(dāng)前所在的分頁等等。通常人們會把它劃分到皮膚中,但你要明白我們劃分的依據(jù)是意圖,很顯然,狀態(tài)不是皮膚,僅僅是通常為表達(dá)某些狀態(tài)時會使用一些顏色,畢竟顏色是最好的表示方法。它還與各種邏輯有著千絲萬縷的聯(lián)系,經(jīng)常會使用JavaScript來加以控制,所以將狀態(tài)多帶帶分出來是極有必要的,JavaScript只需要更改一個class就可以實(shí)現(xiàn)狀態(tài)的切換,而不是在執(zhí)行的時候才想起來應(yīng)該把哪里隱藏把哪里顯示,或者是變個顏色出個動畫之類的。
使用接著,無論我們是已經(jīng)把各種寫好的CSS屬性分好了組,還是正準(zhǔn)備以這種方式開始寫CSS,我先引入一個語言學(xué)的術(shù)語 語塊(Lexical chunk),創(chuàng)造這一術(shù)語的 Michael Lewis 認(rèn)為語言并非由傳統(tǒng)語法和詞匯組成,而是由多個詞匯的預(yù)制語塊組成。我們現(xiàn)在分好的組其實(shí)就是一個個CSS的語塊,CSS本身就是這種預(yù)制功能,我們要做的就是把style語塊化,然后在HTML中寫上代表它的class名稱,當(dāng)HTML元素上的多個class組合在一起時就組成完整的語義。
比如表示步驟的元素,這是一個形狀類似標(biāo)簽,一個挨一個的排列的元素。我將它的尺寸等屬性抽出來命名為label,然后把布局的屬性組命名為float-left,如果我的設(shè)計(jì)風(fēng)格是扁平化的,我可以把相關(guān)的皮膚屬性命名為flat,你知道雖然扁平化一般用不著特別的屬性,但我也可以寫一些強(qiáng)制去掉圓角和漸變背景的屬性。作為步驟,會分為當(dāng)前的步驟,之前的步驟,以及還沒到的步驟,當(dāng)前的步驟可以命名為current,或者is—active,后面的步驟不能點(diǎn)所以可以命名為is-disable,這些都是狀態(tài)。而現(xiàn)在我們來看看當(dāng)前步驟元素是什么樣的
總結(jié)成一句話就是“The flat label which float left is active”。這就是語義化的CSS。把組織好的語塊像說話一樣作用于元素上,對元素發(fā)出指令,讓其變成想要的樣式。而且你應(yīng)該會發(fā)現(xiàn),一組該元素所獨(dú)有的屬性,或者是尺寸之類的一般是主語,布局是動賓短語,而皮膚多是一些形容詞,最后狀態(tài)可以用表語。
總之,CSS作為一個描述性的語言,有很多人覺得不能算一種語言,但我反而覺得這是一種高級語言,因?yàn)楦咏匀徽Z言。當(dāng)然其主要作用是在視覺渲染上,所以應(yīng)該是一種受限的語言,可以看作是接近自然語言的子集。所以它的性質(zhì)覺得了其重語義輕語法的特點(diǎn),寫CSS不能僅靠語法規(guī)則,一定要用上語義規(guī)則,最好是能和項(xiàng)目中所有人達(dá)成共識,CSS框架其實(shí)就是一種通用共識。
原文
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/111021.html
摘要:一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用影響的內(nèi)容。的思維導(dǎo)圖是層疊樣式表語言,是對的語言進(jìn)行樣式化。我設(shè)計(jì)的思維導(dǎo)圖如下簡介,對象,編程語言基礎(chǔ),客戶端,參考,創(chuàng)建與調(diào)試等等內(nèi)容。 一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用 影響的內(nèi)容。 HTML的思維導(dǎo)圖 HTML是一種超文本標(biāo)記語言。我認(rèn)為要學(xué)...
摘要:一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用影響的內(nèi)容。的思維導(dǎo)圖是層疊樣式表語言,是對的語言進(jìn)行樣式化。我設(shè)計(jì)的思維導(dǎo)圖如下簡介,對象,編程語言基礎(chǔ),客戶端,參考,創(chuàng)建與調(diào)試等等內(nèi)容。 一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用 影響的內(nèi)容。 HTML的思維導(dǎo)圖 HTML是一種超文本標(biāo)記語言。我認(rèn)為要學(xué)...
摘要:一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用影響的內(nèi)容。的思維導(dǎo)圖是層疊樣式表語言,是對的語言進(jìn)行樣式化。我設(shè)計(jì)的思維導(dǎo)圖如下簡介,對象,編程語言基礎(chǔ),客戶端,參考,創(chuàng)建與調(diào)試等等內(nèi)容。 一個思維導(dǎo)圖是把抽象的事物具體化,以一個東西為思想核心內(nèi)容,映射出一系列的組成及作用 影響的內(nèi)容。 HTML的思維導(dǎo)圖 HTML是一種超文本標(biāo)記語言。我認(rèn)為要學(xué)...
摘要:繼承性子標(biāo)簽會繼承父標(biāo)簽樣式優(yōu)先級行內(nèi)樣式選擇器類選擇器標(biāo)簽選擇器通配符繼承機(jī)制創(chuàng)建了的元素中,在垂直方向上的會發(fā)生重疊。 技能考察: 一、關(guān)于Html 1、html語義化標(biāo)簽的理解; 結(jié)構(gòu)化的理解; 能否寫出簡潔的html結(jié)構(gòu); SEO優(yōu)化 a、理解:根據(jù)內(nèi)容的結(jié)構(gòu)化(內(nèi)容語義化),選擇合適的標(biāo)簽(代碼語義化)便于開發(fā)者閱讀和寫出更優(yōu)雅的代碼的同時 讓瀏覽器的爬蟲和...
閱讀 2901·2021-11-23 09:51
閱讀 1547·2021-11-15 11:36
閱讀 3006·2021-10-13 09:40
閱讀 1863·2021-09-28 09:35
閱讀 13039·2021-09-22 15:00
閱讀 1367·2019-08-29 13:56
閱讀 2924·2019-08-29 13:04
閱讀 2698·2019-08-28 18:06