<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • [ISUX譯]我為css變量狂

          2016-12-23    資深UI設(shè)計者

          如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

          幾個星期前,CSS Variables ——CSS 變量草案發(fā)布在了W3C官方 ,更準(zhǔn)確的應(yīng)該叫CSS 自定義屬性,目前在Chrome Canary 版里面已經(jīng)支持,開啟該功能見附[1]

          當(dāng)Chrome瀏覽器工程師Addy Osmani第一時間把這消息發(fā)布在twitter后,遭到了數(shù)萬人的否定敵視懷疑。于我而言,更多的感到是一個驚喜,因為這個功能實在讓人太興奮了。

          快速的掃了一遍之后,發(fā)現(xiàn)99%人抱怨的無外乎這兩點:

          • 語法太丑和不夠簡潔
          • Sass 、Less早就有這些玩意了,不太care

          雖然我承認(rèn)我也對這語法很反感,更重要的是理解語法不只是反復(fù)無常的在選擇。CSS工作組討論很久語法的長度,他們提取了一些點,考慮到CSS的語法兼容不會與未來增加的其他語言沖突。

          CSS 預(yù)處理器是一個非常出色的工具,但是它們的變量是靜態(tài)的,有語法作用域。Native CSS 變量,從另一面來看,它們是一個完全不同類型的變量:因為它們是動態(tài)的,他們的作用域是DOM,事實上,這也是困惑該不該稱他們?yōu)樽兞浚鼈儗嶋H上是CSS 屬性,這也給了他們一個機會,來解決這個功能完全不同的問題。

          在這篇文章中,我將討論一些CSS 自定義屬性這個功能,而且不用CSS 預(yù)處理器來做。當(dāng)然我還演示一些新的設(shè)計模式,自定義功能的啟用。文章最后討論一下,我認(rèn)為在未來最有可能的是預(yù)處理變量和自定義變量一起使用,兩個東西取長補短,珠聯(lián)璧合。

          注意:這篇文章不是介紹CSS 自定義屬性,如果你還從來沒聽說過他們,不熟悉他們是如何工作的,可以看看這里

          預(yù)處理器變量的限制

          在繼續(xù)寫之前,我想強調(diào)的是,我真的很喜歡CSS 預(yù)處理器,我的所有項目都在使用它。預(yù)處理器做了一件非常了不起的事情,即時你知道他最終出來的就是原始的CSS,任然可以感受這個神器的時代。

          任何工具,都有他的局限性,有一個炫酷的外觀會讓人驚喜而忽略了其中的限制,特別是新用戶。

          Preprocessor variables aren’t live

          也許受預(yù)處理限制,在媒體查詢中,最常見的新手也無力吐槽定義變量或使用@extend

          1. $gutter: 1em;
          2. @media (min-width: 30em) {
          3. $gutter: 2em;
          4. }
          5. .Container {
          6. padding: $gutter;
          7. }

          如果你編譯上面的代碼,你得到是:

          1. .Container {
          2. padding: 1em;
          3. }

          如你所見,媒體查詢被廢棄,變量賦值被忽略。

          從理論上講,雖然sass 負(fù)責(zé)申明條件變量,但這樣做也是一個挑戰(zhàn),枚舉所有Permutations—exponentially 會增加CSS的最終大小。

          預(yù)處理器變量不能級聯(lián)(層疊)

          每當(dāng)你使用變量,作用域的范圍不可避免,這個變量應(yīng)該全局嗎?應(yīng)該是file/module?還是塊作用域?

          CSS 最終是為HTML的樣式,事實證明還有另外一種有用的方法是變量的范圍:DOM 元素,但是preprocessors不能運行在瀏覽器且從未看見標(biāo)記

          參考一個網(wǎng)站,試圖給<html> 的元素添加一個 class user-setting-large-text 他們更傾向于更大的文本大小 。
          一旦這個class設(shè)置,更大$font-size變量賦值就會運用:

          1. $font-size: 1em;
          2.  
          3. .user-setting-large-text {
          4. $font-size: 1.5em;
          5. }
          6.  
          7. body {
          8. font-size: $font-size;
          9. }

          但是,就像上面媒體查詢例子,Sass 直接忽略變量賦值, 意味著這種事是不可能的。他輸出的:

          1. body {
          2. font-size: 1em;
          3. }

          預(yù)處理器變量不繼承

          雖然繼承是級聯(lián)的一部分,但是我還是要提一下,因為很多次我想使用這個功能都未能用成。

          有一種情況,你有Dom元素在顏色風(fēng)格基礎(chǔ)上有什么的變化時候,你可以用在他們的父元素上。

          1. .alert { background-color: lightyellow; }
          2. .alert.info { background-color: lightblue; }
          3. .alert.error { background-color: orangered; }
          4.  
          5. .alert button {
          6. border-color: darken(background-color, 25%);
          7. }

          上面的Sass代碼是無效的,但你應(yīng)該能理解這代碼試圖要完成什么。

          它最后試圖使用sass的darken函數(shù)用在background-color屬性,但button元素繼承它的父class元素.alert。如果class info或者error已經(jīng)添加到alert(或者通過JavaScript設(shè)置背景顏色或用戶樣式),按鈕元素希望能夠得到這兩個顏色。

          現(xiàn)在這個雖然不會在sass 運行,因為預(yù)處理器不知道DOM結(jié)構(gòu),但還是希望搞清楚這類型的東西可能有哪些用處。

          說一個特定的用例:這也是在繼承DOM屬性的可訪問性運行color 函數(shù)的原因。舉個栗子,為了確保文本總是可讀,且充分與背景顏色形成鮮明對比。通過自定義屬性和新的CSS Color函數(shù),這將很快成為可能!

          預(yù)處理器變量不能相互協(xié)作

          這是一個明顯呈下降趨勢的預(yù)處理器,如果你用PostCSS 建立一個網(wǎng)站,你想使用第三方組件,不好意思,你只有通過Sass的themeable

          與第三方分享預(yù)處理器變量在不同的工具集成或第三方托管的CND樣式與都非常困難(至少不容易)

          本地CSS自定義屬性將與任何CSS預(yù)處理或者原CSS正好相反。

          自定義屬性有何不同

          你可能已經(jīng)猜到了,我上面列出的適用于CSS 自定義屬性沒有任何限制,但也許更重要的不是說他們不適用,而是為什么他們不用。

          CSS自定義屬性就像常規(guī)的CSS屬性一樣,他們的操作方式完全相同

          像普通的CSS屬性,自定義屬性是動態(tài)的,他們可以在運行時修改,也可以在媒體查詢時通過更改DOM添加一個新類,同時也可以指派內(nèi)聯(lián)元素和一個常規(guī)CSS里申明選擇器。還可以通過正常的cascade規(guī)則或者使用JavaScript覆蓋。最主要的是,他們的可以繼承的,所以當(dāng)他們應(yīng)用到DOM元素的時候,他們的子元素也會繼承屬性。

          為了更簡潔,預(yù)處理器變量是語法作用域和編譯后靜態(tài)。自定義屬性作用域是DOM,他們都很靈活。

          實際案例

          如果你仍然不確定自定義屬性可以做到這一點,而預(yù)處理器不行,我這里給一些例子。

          不論真假,有大量非常好的例子我都很想展示,但為了不讓這篇文章太丑,我選了兩個。

          我選擇這些例子不僅僅因為它們的理論,它們也是我們過去實際面臨的挑戰(zhàn),我依然記得試圖用預(yù)處理器,但這是不可能的。現(xiàn)在好了,直接自定義屬性走起。

          媒體查詢的響應(yīng)式特性

          很多網(wǎng)站在項目布局使用“gap”和“gutter” 定義默認(rèn)間距和填充頁面各個部分,很多時候,你想要這個“gutter”的值根據(jù)瀏覽器窗口的大小而不同。在大屏幕上你想要每一項之間有足夠的空間,但小屏幕又負(fù)擔(dān)不起那么大的空間,所以“gutter”的值要較小。

          正如我上面提到的,在媒體查詢里面Sass 不能正常運行,所以你必須每個單獨處理。

          下面的例子定義了變量$gutterSm, $gutterMd$gutterLg,然后給每個變量申明一個單獨的規(guī)則:

          1. /* Declares three gutter values, one for each breakpoint */
          2.  
          3. $gutterSm: 1em;
          4. $gutterMd: 2em;
          5. $gutterLg: 3em;
          6.  
          7. /* Base styles for small screens, using $gutterSm. */
          8.  
          9. .Container {
          10. margin: 0 auto;
          11. max-width: 60em;
          12. padding: $gutterSm;
          13. }
          14. .Grid {
          15. display: flex;
          16. margin: -$gutterSm 0 0 -$gutterSm;
          17. }
          18. .Grid-cell {
          19. flex: 1;
          20. padding: $gutterSm 0 0 $gutterSm;
          21. }
          22.  
          23. /* Override styles for medium screens, using $gutterMd. */
          24.  
          25. @media (min-width: 30em) {
          26. .Container {
          27. padding: $gutterMd;
          28. }
          29. .Grid {
          30. margin: -$gutterMd 0 0 -$gutterMd;
          31. }
          32. .Grid-cell {
          33. padding: $gutterMd 0 0 $gutterMd;
          34. }
          35. }
          36.  
          37. /* Override styles for large screens, using $gutterLg. */
          38.  
          39. @media (min-width: 48em) {
          40. .Container {
          41. padding: $gutterLg;
          42. }
          43. .Grid {
          44. margin: -$gutterLg 0 0 -$gutterLg;
          45. }
          46. .Grid-cell {
          47. padding: $gutterLg 0 0 $gutterLg;
          48. }
          49. }

          使用自定義屬性來完成相同的東西,你只需要定義樣式即可。你可以使用一個 gutter 屬性,然后隨著媒體查詢的變化,更新gutter 的值,它就會做出相應(yīng)的變化。

          1. :root { --gutter: 1.5em; }
          2.  
          3. @media (min-width: 30em) {
          4. :root { --gutter: 2em; }
          5. }
          6. @media (min-width: 48em) {
          7. :root { --gutter: 3em; }
          8. }
          9.  
          10. /*
          11. * Styles only need to be defined once because
          12. * the custom property values automatically update.
          13. */
          14.  
          15. .Container {
          16. margin: 0 auto;
          17. max-width: 60em;
          18. padding: var(--gutter);
          19. }
          20. .Grid {
          21. --gutterNegative: calc(-1 * var(--gutter));
          22. display: flex;
          23. margin-left: var(--gutterNegative);
          24. margin-top: var(--gutterNegative);
          25. }
          26. .Grid-cell {
          27. flex: 1;
          28. margin-left: var(--gutter);
          29. margin-top: var(--gutter);
          30. }

          雖然有額外增加的自定義屬性語法,但是相比冗長的代碼完成同樣的事明顯好很多。這里只考慮了三個變量,如果變量越多,這將節(jié)省更多的代碼。

          下面的演示使用的是上面的代碼自動構(gòu)建的一個基本的網(wǎng)站布局,gutter的值跟隨窗口的變化而變化,瀏覽器的支持自定義屬性的話,效果屌屌的!
          custom-properties-responsive-1400w
          View the demo on CodePen: editor view / full page

          語境樣式

          語境樣式(樣式元素根據(jù)它出現(xiàn)在Dom)在CSS里是一個有爭議的話題。 一方面,它是最受人尊敬的CSS開發(fā)者警告,另一方面,大多數(shù)人每天都還要用它。

          Harry Roberts最近寫了這篇文章以及他對此的看法:

          If you need to change the cosmetics of a UI component based on where it is placed, your design system is failing…Things should be designed to be ignorant; things should be designed so that we always just have “this component” and not “this component when inside…

          當(dāng)我站在Harry這一邊,我認(rèn)為大多數(shù)人走捷徑這種情況可能表面一個更大的問題:CSS 表現(xiàn)能力是有限的,大部分人不滿意當(dāng)前的“最佳實踐”。

          下面例子顯示了大部分人在CSS使用語境樣式方法,使用子代選擇器

          1. /* Regular button styles. */
          2. .Button { }
          3. /* Button styles that are different when inside the header. */
          4. .Header .Button { }

          這種方法有很多問題(在我的文章有解釋),這種模式一個代碼味道,它違反了 open/closed 軟件開發(fā)原則;修改了一個封閉組件的實現(xiàn)細節(jié)

          軟件體 (類, 模塊, 函數(shù)等) 擴展開放, 對修改關(guān)閉。

          自定義屬性的改變范圍式定義組件是一個有趣的方式,用自定義屬性,我們可以在第一次就寫一個實際上是開放擴展的組件,這里有一個例子:

          1. .Button {
          2. background: var(--Button-backgroundColor, #eee);
          3. border: 1px solid var(--Button-borderColor, #333);
          4. color: var(--Button-color, #333);
          5. /* ... */
          6. }
          7.  
          8. .Header {
          9. --Button-backgroundColor: purple;
          10. --Button-borderColor: transparent;
          11. --Button-color: white;
          12. }

          這和子選擇器之間的區(qū)別很微妙而且很重要。

          當(dāng)使用子選擇器我們宣傳在頁眉按鈕會這樣,這樣不同的按鈕如何定義自己,這樣的聲明是獨裁(借Harry’s 的詞),很難撤銷例外的情況,頁眉的一個按鈕不需要這樣的方式。

          另外,自定義屬性,按鈕組件仍是沒有語境且不能完全與header 組件解耦,
          按鈕組件簡單的說申明:無論它們現(xiàn)狀如何,我要自己的風(fēng)格基于這些自定義屬性;
          header 組件:我要設(shè)置這些屬性值,由我的子代來確定和如何使用它們。

          主要的區(qū)別是,該擴展由按鈕組件選擇,并輕易消除例外情況。

          下面的演示說明了語境樣式的鏈接和按鈕在網(wǎng)站的標(biāo)題及內(nèi)容區(qū)
          custom-properties-contextual-styling-1400w
          在CodePen查看demo:editor view / full page

          創(chuàng)建例外

          如果像.promo的組件加到header,然后buttons又加到.promo 里面,使其看起來像一個正常按鈕,而不是標(biāo)題按鈕。

          如果你用子代選擇器,那你將要給header buttons寫一大串樣式,而且還不能影響promo buttons,混亂,容易出錯,而且容易失控的數(shù)量會增加:

          1. /* Regular button styles. */
          2. .Button { }
          3.  
          4. /* Button styles that are different when inside the header. */
          5. .Header .Button { }
          6.  
          7. /* Undo button styles in the header that are also in promo. */
          8. .Header .Promo .Button { }

          使用自定義屬性,你可以簡單的更新任何你想要的新按鈕屬性,或重置他們回默認(rèn)樣式,無視這些例外,改變的方式總是相同的。

          1. .Promo {
          2. --Button-backgroundColor: initial;
          3. --Button-borderColor: initial;
          4. --Button-color: initial;
          5. }

          跟React學(xué)

          當(dāng)我第一次探索自定義屬性語境樣式的時候,我很懷疑自己。像前面說的,我傾向于喜歡組件自己定義自己的變化,而不是任何屬性都繼承自父元素。

          但是有一件事,動搖了我在CSS自定義屬性的觀點,那就是React的props

          React的props依然是動態(tài)的,DOM-scoped variables,他們繼承,允許組件上下文關(guān)聯(lián),在React,父組件將數(shù)據(jù)傳遞給子組件,然后子組件定義props,他們愿意接受和使用它們。這種建筑模型通常被稱為one-way data flow。

          盡管自定義組件是全新的未測試的領(lǐng)域,我認(rèn)為React model 給了成功的信心,一個復(fù)雜的系統(tǒng)可以建立在屬性繼承——此外,DOM-scoped variables 是一個非常有用的設(shè)計模式。

          最大限度的減少副作用

          CSS 自定義屬性繼承默認(rèn),在某些情況下,這導(dǎo)致組件的樣式可能沒有達到他們的預(yù)期。

          在文章上一節(jié)中,我提到可以重置單個屬性,這可以防止未知值被應(yīng)用到元素的子元素:

          1. .MyComponent {
          2. --propertyName: initial;
          3. }

          盡管這不是規(guī)范的一部分,——正在討論屬性附[2],這個可以用來重置所有自定義屬性,如果你想白名單幾個屬性,你可以將他們單獨繼承,其他的正常即可:

          1. .MyComponent {
          2. /* Resets all custom properties. */
          3. --: initial;
          4.  
          5. /* Whitelists these individual custom properties */
          6. --someProperty: inherit;
          7. --someOtherProperty: inherit;
          8. }

          管理全局names

          如果你一直關(guān)注自定義屬性,那你可能已經(jīng)注意到本身帶有components-specific前綴的組件,如--Button-backgroundColor.

          與CSS 大多數(shù)名字一樣,自定義屬性是全局,很是有可能將正在使用命名與其他開發(fā)團隊的名稱產(chǎn)生沖突。

          有一個簡單的方法可以避免這個問題,就是堅持命名約定,我現(xiàn)在團隊就是這么做的。

          對于更復(fù)雜的項目,你可以考慮像CSS模塊 localifies所有全局名稱,而且他們最近也表示有興趣支持自定義屬性。

          結(jié)束語

          如果你在閱讀這篇文章之前,不熟悉CSS 自定義屬性,我希望你能給他一個機會。如果你還在懷疑他的必要性,希望我能改變你的想法。

          我敢肯定,自定義屬性能給CSS帶來一系列的強大的功能和面貌,它還有更多的優(yōu)勢等待我們?nèi)グl(fā)現(xiàn)。

          自定義屬性preprocessor 變量是無可替代的。盡管如此,preprocessor variables 仍然是許多情況下的不二選擇。正因如此,我堅信未來很多網(wǎng)站都會結(jié)合使用二者。
          自定義屬性為動態(tài)主題和預(yù)處理器變量靜態(tài)模板。

          我不認(rèn)為這是二選一的情況,讓他們相互競爭,就像對手一樣傷害每一個人。

          特別感謝 Addy Osmani 和 Matt Gaunt 審查文章 ,Shane Stephens并及時修復(fù)了一些bug才能使demo正常運行,再次感謝。

          腳注:
          1.你可以啟用chrome 的”Experimental Web Platform Features”功能,方法是:地址輸入 about:flags然后搜索“Experimental Web Platform Features”,然后點擊“開啟”按鈕
          2.使用——屬性(如定制相關(guān)樣式元素)是Atkins 在github comment提到的,此外,給www-style 發(fā)送建議郵件,也會很快得到處理的。

          本文原文地址:http://philipwalton.com/articles/why-im-excited-about-native-css-variables/


          藍藍設(shè)計m.sdgs6788.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)

          日歷

          鏈接

          個人資料

          藍藍設(shè)計的小編 http://m.sdgs6788.com

          存檔

          久久久久亚洲AV无码去区首| 久久久噜噜噜久久中文字幕色伊伊 | 人妻无码αv中文字幕久久| 久久综合久久美利坚合众国| 久久久久久精品免费免费自慰| 无码人妻精品一区二区三区久久 | 四虎国产精品免费久久5151| 亚洲午夜精品久久久久久人妖| 国内精品久久久久久麻豆| 亚洲国产综合久久天堂| 亚洲中文字幕无码久久综合网| 久久国产乱子伦精品免费强| 久久精品成人欧美大片| 国产aⅴ激情无码久久| 久久综合丝袜日本网| 一本一道久久a久久精品综合| 国产∨亚洲V天堂无码久久久| 久久影视综合亚洲| 久久亚洲私人国产精品| 欧美午夜A∨大片久久| 国产情侣久久久久aⅴ免费| 久久精品国产精品亚洲艾草网美妙| 亚洲色欲久久久综合网| 久久综合一区二区无码| 国产精品久久久久9999高清| 2021国产精品久久精品| 亚洲综合精品香蕉久久网97| 中文国产成人精品久久不卡| 久久精品?ⅴ无码中文字幕| 久久精品无码午夜福利理论片| 久久人妻少妇嫩草AV无码蜜桃| 国内精品久久久久| 亚洲精品乱码久久久久久按摩 | 国产毛片久久久久久国产毛片| 久久亚洲精品成人无码网站| 国产精品美女久久久久av爽 | 亚洲综合久久夜AV | 99久久国产主播综合精品| www性久久久com| 麻豆亚洲AV永久无码精品久久| 久久国产精品无|