国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【譯】CSS繼承、層疊和全局作用域

WilsonLiu95 / 951人閱讀

摘要:相反的,提供了全局作用域和局部作用域。組成界面的分子的樣式可以通過元素選擇器定位。元素選擇器的優先級很低,因此他們不會覆蓋任何基于類選擇器的樣式。使用元素選擇器有以下優點避免了的冗長沒有冗余的類。

最近學習到CSS的繼承屬性,正好看到這篇文章,便將它翻譯出來。作者的思想,在平時的項目中或多或少都有用過,但是從來沒有仔細去思考如何利用這些特性讓代碼更加優雅。

我熱愛模塊化設計。長期以來,我將網站分為組件,而不是頁面,并動態地將這些組件合并成界面,這樣可以提高彈性、效率與可維護性。

但是我不想讓我設計的東西像是互相無關的事情,我是制作一個頁面,而不是超現實主義蒙太奇。

幸運的是,有一門叫做CSS的技術,就是專門解決上述問題的。CSS可以通過賦予HTML組件樣式以最小的成本確保設計的一致性。這多虧了CSS的兩個主要的特征:

繼承inheritance

層疊the cascade(CSS中的C)

盡管這些特征可以保證網頁文檔的樣式代碼高效、DRY,并且這也成為了CSS存在的理由,但是它們明顯不受歡迎。封裝的一些CSS模塊,比如BEM、Atomic CSS,都是在盡他們最大的努力回避或者抑制這些特征,這讓開發者能夠更多地控制這些CSS,但這僅僅只是一項頻繁的專項干預機制。

我準備帶著一顆對模塊化界面設計尊重的心來重新審視繼承、層疊和作用域,目的在于向讀者展示如何平衡這些特征來使我們的CSS代碼變得更加的簡潔和靈活,并且界面也更加易于擴展。

Inheritance And font-family

盡管很多人提議為什么CSS不只提供一個全局作用域,但是如果有,很多東西就會變得重復。相反的,CSS提供了全局作用域和局部作用域。就像在JavaScript里,局部作用域可以訪問父級和全局作用域,CSS里的局部作用域幫助了繼承。

比方說,如果在根元素(全局)html中聲明了font-family,那就能確保這一規則會被應用于該文檔中所有的祖先元素中(在下一節中將會討論一些例外)。

就像在JavaScript里面,如果我聲明一個變量為局域作用域,那它在全局或者說任意祖先作用域中都是無效的,但它能夠對其子域起作用(比如上面代碼中的p元素)。在下一個例子中,line-height為1.5并不能對html元素生效,然而在p元素里的a元素繼承了p的line-heigh值。

繼承的最棒之處是你只需要非常少的代碼就能建立一致的可視化設計基礎,這些樣式甚至會影響到你還沒有寫出來的HTML。這些是不會過時的代碼。

替代方法

當然,有很多的方法可以定義普通的樣式。比如,我可以創建一個類.sans-serif

將它應用于任何我認為會用上這個樣式的元素中:

這樣我可以準確地選擇哪些元素需要這個樣式,而哪些元素不需要。

任何可以控制的機會都是誘人的,但是也存在很明顯的問題。在這種情況下,我們不僅僅需要手動給需要的元素添加類名(這意味著必須一開始就知道這些類名),而且意味著我們已經放棄了支持動態內容的可能性:WYSIWYG編輯器和Markdown解析器都不能給默認的p元素提供sans-serif類。

除了class="sans-serif"需要同時在樣式表和HTML里面添加代碼外,它和style="font-family: sans-serif"的區別并不大。如果使用繼承的話,那我們可以寫更少的代碼甚至不寫其他代碼。相比于給每一個字體樣式寫類名,我們只需要在html元素里聲明任何我們想要的樣式:

The inherit Keyword

有些屬性的默認值不是inherit,有些元素也沒有inherit一些屬性。在一些情況下,我們可以利用[property name]: inherit來決定繼承性。

比如,input和textarea元素不會繼承字體的任何屬性。為了保證所有的元素能夠從全局作用域中繼承這些屬性,我們可以用全局選擇器和關鍵字inherit。這樣,就能最大程度地利用繼承。

注意,我沒有設置font-size的值。我不想讓font-size具有直接的繼承性,這樣它可能會覆蓋一些元素的默認user-agent樣式,比如說頭部元素、small元素等。如此一來,我可以節約一行代碼,并且讓user-agent決定這些樣式。

另外一個屬性我不想用繼承的是font-style:我不想重新定義em的斜體,這會浪費工作時間,并且導致更多的代碼量。

現在,如我所想實現了所有可以繼承或者是強制繼承的字體樣式?,F在只花了兩個區塊就能聲明一致性和作用域。從現在起,開發者在構造組件時,甚至不用再考慮font-family、line-height或者是color,除非碰到一些特例,這時就需要用到層疊。

Exceptions-Based Styling

我可以利用繼承實現主要的標題擁有相同的font-family、color和line-height的目的。但是我想讓font-size的值不一樣時,可能什么都不需要設置,因為user-agent已經為h1元素提高了更大號的font-size(它是我們設置的基礎字體的125%倍)。

但是如果我想調整元素的font-size呢?這時候就可以利用全局作用域的優勢,在局部作用域里只對我需要調整的元素進行調整。

如果默認封裝了CSS元素的樣式,那這種情況就不可能實現:給h1添加所有的字體樣式。相反地,我可以將我的樣式分成獨立的類,用空格分離添加到每一個h1中。

無論采用哪種方法,都會增加工作量,并且只能產生一個具有固定樣式的h1。如果利用層疊,就可以用我想用的方式去定義最多的元素的樣式,其實h1就僅僅是一個特例。層疊就像一個過濾器,意味著只有在添加新的樣式時舊的樣式才會被覆蓋。

Element Styles

我們已經有了一個好的開始,但是真正要掌握層疊,我們需要盡可能多地定義公共元素的樣式。為什么呢?因為我們混合的模塊是由獨立的HTML元素組成的,而屏幕閱讀器友好的界面應該充分利用語義化的結構進行標記。

組成界面的“分子”的"atoms"樣式(atomic design terminology)可以通過元素選擇器定位。元素選擇器的優先級很低,因此他們不會覆蓋任何基于類選擇器的樣式。

我們需要做的第一件事是定義所有我們需要用到的元素的樣式。

如果想較簡潔地實現統一性的界面,接下來的步驟很重要:每一次需要創建一個新的組件時,如果引入了新的元素,那么利用元素選擇器定義這些新元素樣式?,F在還不需要使用限制性、高優先級的選擇器,也不需要添加類名來定義樣式,就使用語義化元素其本身。

舉個例子,如果我還沒有定義button的樣式(正如前面的例子),而我新的組件中包含了一個button元素,這時我就需要為整個界面的button元素定義樣式。

現在,如果你需要寫一個新的組件但是擁有相同的button,就少了一件需要擔心的事情了。你不需在不同的命名空間重寫相同的CSS,也不需要記住或者編寫類名。CSS設計的目的就是為了讓事情變得更簡單和高效。

使用元素選擇器有以下優點:

避免了HTML的冗長(沒有冗余的類)。

避免了樣式表的冗長(不同的組件可以共用樣式,不需要對每個組件進行重寫)。

最終的界面擁有語義化的HTML結構。

利用類來提供唯一的樣式經常被定義為“關注點分離”,這是對W3C中關注點分離原則的誤解,它的目標是利用HTML和CSS樣式來描述整個結構。類是專門為了指定樣式而制定的,并且出現在結構中,因此無論他們出現在哪里,在技術上都是在打破分離。你不得不通過改變自然結構來獲取樣式。

如果不依賴表面的結構標記(類、內聯樣式),你的CSS就會兼容通用結構,并且符合語法規范。這使得擴展內容與功能變得不再重要,并且不需要把它變成一個樣式任務。它也使得你的CSS能夠被擁有傳統語義化結構的不同的工程重復利用(CSS的‘方法論’可能要另當別論)。

特殊案例

在有人提出我思考得太簡單前,我意識到界面上不是所有的按鈕都在做相同的事情,我也意識到功能不同的按鈕可能看起來樣式也會不一樣。

這并不代表我需要定義類、繼承或者是層疊。讓一個界面的按鈕看起來完全不一樣會混淆你的用戶。為了保證可訪問性和一致性,很多的按鈕只需要在外表的標簽上進行區分。

記住,樣式不是視覺上進行區分的唯一方法。內容也可以提供視覺區分,而且這種方法會更加直觀,你可以從文字上直接明白他們的區別。

必須或者適當地多帶帶使用樣式對內容進行區分的場景可能比你想象的還要少。通常,差異化的樣式只是補充條件,比如一個紅色的背景或者帶圖標的文本標簽。文本標簽的存在對那些使用語音激活的軟件有特殊作用:說“紅色按鈕”或者“button with cross icon”不可能讓軟件識別。

我將在“Utility Classes”一節中,介紹如何給看起來相似的元素添加細節。

Attributes

語義化的HTML不僅僅指結構,標簽特征能定義類型、樣式屬性和狀態。這些對可訪問性都非常重要,因此需要寫在HTML中需要的地方。正因為他們出現在HTML中,他們為制作樣式鉤子提供了額外的機會。

比如,input元素擁有type屬性,你應該利用它的優點,另外比如說aria-invalid是用來描述狀態的。

有幾點需要注意:

由于使用了inherit關鍵字,color、font-family、line-height繼承了html的值,因此不需要設置。如果想改變整個應用范圍內的font-family,只需要在html塊中進行一次聲明。

邊框顏色與color相關聯,因此它也繼承了全局域的顏色,我需要設置的只有邊框的寬度和風格。

屬性選擇器[aria-invalid]是無限制的。這意味著它可以被更好地應用(可以同時應用在input和textarea選擇器上),且低優先級。簡單的屬性選擇器和類選擇器有相同的優先級。無限制的使用它們意味著任意寫在更深層疊處的類可以覆蓋它們。

BEM方法可以利用修飾類來解決這個方法,比如input-invalid。但考慮到無效狀態只能應用在可通信時,因此input-invalid一定是多余的。換句話說,aria-invalid屬性必須出現,那類的作用是什么呢?

只寫HTML

在層疊多,大量的元素和屬性選擇器絕對是我的最愛:新組件的構造就變成了,了解HTML結構比了解公司或者組織的命名規范重要得多。分配到這個項目中的開發者將會從已經存在的繼承樣式中獲益,這減少了對參考文檔的需求或者寫新的CSS的必要性。Tim Baxter在Meaningful CSS: Style It Like You Mean It中提到了案例。

Layout

到目前為止,我們都沒有寫額外的特定組件的CSS,這不代表我們沒有給它們任何樣式。所有的組件都是由HTML元素的,更復雜的組件都是依靠這些元素的排列順序進行組合的。

這就引出了布局的概念。

我們主要需要處理流式布局——連續的塊級元素的間距。你可能注意到至今我仍沒有為元素設置任何的margin。那是因為margin不應該考慮為元素的屬性,而應該是元素上下文的屬性。也就是說,只有元素相遇時他們才起作用。

幸運的是,相鄰選擇符可以準確地描述這種關系。除了少數例外,利用層疊可以對所有出現在子級中的塊級元素設置統一的默認值。

極低優先級lobotomized owl選擇器確保了所有的元素(除了常見的例外)的間距為一行。這意味著在所有案例中默認存在白色的間距,所有開發流式布局的開發者都有一個合理的起點。

在多數情況下,margins只關心它本身。但由于優先級較低,也很容易在需要的地方覆蓋它的一行間距。比如,為了表示標簽和它們相關元素的關聯性,我可能需要縮小它們之間的距離。在下面的例子中,標簽和它們后面的所有元素(input、textarea、select等等)之間的間隔將會縮小。

使用層疊意味著只需要在需要的地方寫特定的樣式,其他的符合一個合理的基準。

需要注意的是,因為margins只出現在元素之間,它們不會和其容器的padding重疊。

不管你是否引入了容器元素,都會產生相同的邊距。這意味著,你可以像下面這樣實現相同的布局——這些margins在divs之間出現比在標簽之間出現要好。

利用像atomic CSS的方法實現相同的結果,可以手動組合具體的margin-related類,包括通過* + *隱式處理控制first-child的特例。

請牢記如果一個元素使用atomic CSS,那只會覆蓋它的上邊距。你需要為color、background-color,或者說其他的主要屬性多帶帶添加特定的類,因為atomic CSS不會利用繼承或者元素選擇器。

Atomic CSS讓開發者能夠完全控制樣式,而不需要內聯樣式(內聯樣式不像類一樣可以重復利用)。為多帶帶的屬性提供類名可以在樣式表中減少聲明的復制。

然而,它必須直接在結構中添加標記來實現。這就要求開發者學習它冗長的API,并且增加很多額外的HTML代碼。

相反,如果對任意HTML元素和它們的空間關系設置樣式,那CSS方法就會變得過時。相比于包含一個疊加樣式的HTML系統,使用一致性設計系統進行維護將擁有很大的優勢。

無論如何,下面是我們的CSS架構和流式布局解決方案需具備的特點:

全局(html)樣式和強制繼承;

流式布局和一些例外(lobotomized owl選擇器);

元素和屬性樣式。

我們還沒有寫具體的組件和CSS類,但是我們已經完成很絕大多數的樣式——前提是假設我們能夠合理地寫出可復用的類。

Utility Classes

類有一個全局作用域:不管它們應用在HTML的哪個位置,它們都會受到相關的CSS的影響。這很多情況下會被看成缺點,因為兩個分開工作的開發者可能會寫出相同名稱的類,從而影響到對方的工作。

最近構思的CSS modules通過編程產生唯一的類名綁定到他們本地或者組件內,以彌補上述不足。

忽略生成代碼的丑陋膚淺,你可能很容易看到獨立編寫的組件直接的差別:唯一的標識用來定義相似的東西的樣式。這樣導致界面要么不一致,要么在更大的努力和更多的冗余下變得一致。

把公共元素視為獨一無二的是毫無道理的。你應該定義某種類型的元素的樣式,而不是具體的元素實例。牢記“類”意味著“可能包含更多內容的某一類型的事物”。換句話說,所有的類應該是實用工具類:可在全局重復使用。

當然,在這個例子中,類名.button是多余的:因為我們可是使用button元素選擇器。但如果是一個特殊類型的button呢?例如,我們可能寫一個類名.danger表示這類buttons可以進行代表危險性的操作,比如刪除數據:

因為類選擇器比元素選擇器的優先級高,和屬性選擇器擁有一樣的優先級,任何寫在類選擇器里的規則都會覆蓋元素選擇器和屬性選擇器的。所有上面的危險button將會以白色文本紅色背景的樣式出現,但是其他的屬性——比如padding、聚焦時的outline和margin都會保持不變。

如果數個開發者長時間在相同的代碼上進行開發,偶爾會發生命名沖突。但是這里有很多方法去避免,比如,哦,我不知道,首先要做的事是對你將要采用的命名進行搜索看是否存在。你永遠不知道,有人可能已經解決了你要解決的問題。

局部作用域

對于utility classes,我最喜歡的事是將它們設置在容器上,然后利用鉤子去影響里面的子元素的布局。比如,我可以快速對任何元素編碼出一個等間隔、響應式、居中的布局:

這樣,我可以讓列表、按鈕、按鈕和鏈接的組合居中。這多虧了使用> *,它表示.centered里面任何的直接子元素都適用這些樣式,在這個范圍內繼承全局和父級元素的樣式。

我已經調整了元素的margins,這樣這些元素就可以自由地換行,而不會破壞* + *選擇器里設置的垂直布局。這樣,通過設置任意元素的局部作用域,就可以采用了少量的代碼就提供了一個通用的、響應式的布局解決方案。

我的小型flexbox-based grid system(壓縮后93B)基本上就只是一個utility class。它高度可復用,并且因為利用了flex-basis,不需要斷點進行干預。我只用了flexbox布局的方法。

使用BEM,可以在每個網格上設置一個顯式的“元素”類:

但這不是必須的。只需要一個標識去實例化局部作用域。相比于我的版本,這些主題不會受到外部影響的保護,也不應該受> *影響。唯一的不同是充斥著大量的標記。

現在,我們已經開始合并類,但是如預期一樣只合并通用的樣式。我們仍舊沒有多帶帶為復雜組件定義樣式。相反,我們以可復用的方式解決系統層面的問題。當然,你需要在注釋中說明如何使用這些類。

這些Utility classes同時利用了CSS的全局作用域、局部作用域、繼承和層疊的優勢。這些類可以被應用在各個地方,它們實例化局部作用域以影響子元素,繼承了父級元素或者全局作用域的樣式,同時不需要過度使用元素選擇器或者類選擇器。

現在我們的層疊是這樣的:

全局(html)樣式和強制繼承;

流式布局和一些例外(lobotomized owl選擇器);

元素和屬性的樣式;

通用utility classes。

當然,可能會有不需要寫上面案例中那樣的utility classes的情況。但重點是,如果需要對一個組件使用,那解決方案應該針對所有的組件,應該站在系統的角度思考問題。

具體的組件樣式

我們已經定義了組件的樣式,組合組件的方式,所以很容易忽略這一部分的內容。但是值得一提的是,任何沒有從其他組件中創建出來的組件(包括單個的HTML元素)都是有必要存在的。它們是使用ID選擇符的組件,并且可能產生系統風險。

事實上,一個好的經驗是只通過ID來標識復雜的組件(“molecules,” “organisms”),并且不要在CSS中使用這些ID。比如,你可以在你的登錄表單組件中標識#login,不需要在CSS中有元素、屬性或者流式布局樣式的地方使用#login,即使你可能發現你構造了一個或兩個通用的utility classes可以用到其他的組件上。

如果你使用了#login,那這只能影響到特定的組件。這提醒了你已經偏離了開發一個設計系統,而朝著大量冗長代碼的工作前進。

Conclusion

當我告訴大家我不采用BEM這樣的方法或者CSS modules這樣的工具,許多人會認為我是這樣寫CSS的:

然而并不是的。這里已經闡述了一個明確的過度規范,我們需要小心去避免。就像BEM(OOCSS, SMACSS, atomic CSS等)并不是避免復雜、難以控制的CSS的唯一方法。

為了解決優先級問題,很多的方法都是引入了類選擇器。這樣帶來的麻煩是導致一串冗余的類:讓結構變得更加臃腫的奇異的代碼——不會注意到文檔——會使進入到這個系統工程中的新的開發者感到困惑。

通過大量地使用類,你可以讓你的樣式文件最大化地和HTML系統分離。這不適合“關注點分離”,會導致冗長或者更糟的代碼,導致不可訪問性:它可能在不影響可訪問性狀態的情況下影響視覺樣式:

除了大量的編寫和使用類之外,我看到了下面這些方法:

利用繼承建立一致性的前置條件;

用最多的元素和屬性選擇器來支持透明的、標準的基礎組件;

利用簡單的流式布局系統;

結合一些通用的utility classes來解決被多元素影響的布局問題。

所有這些方法對于創造可設計系統,能夠更加容易地寫出新的界面組件,而讓成熟的項目可以更少地依賴新的CSS代碼。這并不是得益于嚴格的命名和封裝,反而是因為缺少它們。

即使你不是很習慣我這里推薦的這些方法,我也希望這篇文章至少能夠幫助你重新思考什么是組件。它們不是你隔離創造出來的。有時候,在標準的HTML元素下,它們也不是你創造的東西。通過組件組合越多的組件,你的界面就能夠以更少的CSS來實現高可訪問性,并擁有一致的視覺效果。

CSS沒有任何錯。事實上,它明顯地讓你以更少的代碼做更多是事情。我們只是沒有充分利用它的優點。

作者:Heydon Pickering

原文鏈接:https://www.smashingmagazine....

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/112268.html

相關文章

  • []聊一聊CSS方法論

    摘要:這個方法論在內容和容器之間有著明顯的區分。這是通過把命名為表示其角色的類名。通過使用這種扁平的命名方式避免了多后代的選擇器。 原文鏈接:A Look at Some CSS methodologies CSS在大型,復雜,快速迭代的系統中難以管理的程度是出了名的。 其中一個原因是CSS缺少內置的作用域管理機制。在CSS中,所有的一切都是全局的,這意味著任何你所做的改變都有可能層疊或者改...

    CoffeX 評論0 收藏0
  • []聊一聊CSS方法論

    摘要:這個方法論在內容和容器之間有著明顯的區分。這是通過把命名為表示其角色的類名。通過使用這種扁平的命名方式避免了多后代的選擇器。 原文鏈接:A Look at Some CSS methodologies CSS在大型,復雜,快速迭代的系統中難以管理的程度是出了名的。 其中一個原因是CSS缺少內置的作用域管理機制。在CSS中,所有的一切都是全局的,這意味著任何你所做的改變都有可能層疊或者改...

    cfanr 評論0 收藏0
  • CSS module 入門

    摘要:示例庫通過記錄來查看定制類名默認的哈希算法是,從前面我們可以發現被編譯成了這樣的字符串。與上面不加等價顯式的局部作用域語法通過示例庫的記錄來查看下的樣式復用對于樣式復用,提供了組合的方式來處理。 showImg(https://segmentfault.com/img/bV9WfX?w=800&h=274);前端發展越來越快,這應該是每個前端開發者的切身感受,但是CSS 是前端領域中進...

    warnerwu 評論0 收藏0
  • 簡單易懂的CSS Modules

    摘要:結果是選手獲勝,名為的元素,最終的值為。而合理的命名約定,的確是組織代碼的有效策略。它們會再由轉換為適當的組合。雖然本文為了嚴謹,結果寫了相當長的篇幅,但希望你讀過之后,還能覺得是簡單易懂的。 不要誤會,CSS Modules可不是在說css模塊化這個好像在某些地方見過的詞,它其實是特指一種近期才出現的技術手段。 什么技術手段呢?請待后文說明。 層疊樣式表 我們知道,css的全名叫做層...

    chunquedong 評論0 收藏0
  • 前端面試經典題目匯總(持續更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實例中找到,若整個原型鏈未找到則返回如何實現繼承構造繼承原型繼承實例繼承拷貝繼承原型機制或和方法去實現較簡單,建議使用構造函數與原型混合方式。 HTML相關問題 1.XHTML和HTML有什么區別 HTML是一種基本的WEB網頁設計語言,XHTML是一個基于XML的標記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    BigNerdCoding 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<