整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          細聊JavaScript設計原則和常用設計模式

          者:吃葡萄不吐番茄皮

          轉發鏈接:https://segmentfault.com/a/1190000019663847

          擊右上方,關注開源中國OSC頭條號,獲取最新技術資訊

          參與翻譯 (5人) : Tocy, 楓子飄漂, ZICK_ZEON, liyue李月, 邊城

          對于許多 Web 開發人員來說,精通 CSS 意味著您可以使用一個可視化的模型,并在代碼中完美地復制它。你不用表格,而且你為自己使用盡可能少的圖片而自豪。如果你真的很優秀,你可以使用最新最好的技術,比如 media queries, transitions 和 transforms。雖然所有這些對于優秀的 CSS 開發人員來說都是正確的,但是 CSS 有一個完全獨立的方面,在評估一個人的技能時很少被提及。有趣的是,我們通常不會對其他語言進行這種忽略。Rails 開發人員之所以被認為是優秀的,并不是因為他的代碼是按照規范工作。當然,它必須按照規格工作;它的優點基于其他方面:代碼是否可讀?更改或擴展是否容易?它是否與應用程序的其他部分分離?它能擴展嗎?

          在評估代碼庫的其他部分時,這些問題是很自然的,CSS 也不應該有任何不同。今天的 Web 應用程序比以往任何時候都要大,一個考慮不周的 CSS 架構可能會削弱開發。現在是時候像評估應用程序的其他部分一樣評估 CSS 了。它不可能是事后的想法,也不可能僅僅被認為是“設計師”的問題。

          好的 CSS 架構的目標

          在 CSS 社區中,普遍共識是很難獲得最佳實踐。從 Hacker News 的評論和開發者對 CSS Lint 發布的反應來看,很明顯,許多人甚至在 CSS 作者應該和不應該做的基本事情上存在分歧。

          因此,與其為我自己的一套最佳實踐提出論據,我認為我們應該從定義我們的目標開始。如果我們能就目標達成一致,希望我們能開始發現糟糕的 CSS,不是因為它打破了我們對好的東西的固有觀念,而是因為它實際上阻礙了開發過程。

          我認為好的 CSS 架構的目標應該與所有好的軟件開發的目標沒有太大的區別。我希望我的 CSS 是可預測的、可重用的、可維護的和可擴展的。

          可被預測

          可預測的CSS意思是您的規則能按照您預想的方式運行。當您添加或更新一個規則時,它不應該影響您的站點中您不想影響的部分。在很少改變的小站點上,這并不重要,但在有數十或數百個頁面的大站點上,可預測的CSS是必須的。

          可復用

          CSS規則應該足夠抽象和可被解耦的,您不必對已經解決的模式和問題進行重新編碼,可以依靠現有的部分快速構建新的組件。

          可維護

          當您的站點需要添加、更新或重新安排新的組件和特性時,這樣做不需要重構現有的CSS。向頁面中添加某組件甲不應該破壞某組件乙。

          可擴展

          隨著站點的規模和復雜性的增長,通常需要更多的開發人員來維護。可擴展的CSS意味著它可以由一個人或一個大型工程團隊輕松管理。這也意味著您的站點的CSS架構不需要大量的學習曲線就可以輕松學習掌握。不能因為您是目前唯一維護CSS的開發人員,就不考慮以后的變化。

          常見的糟糕實踐

          在我們尋找如何實現好的CSS體系結構目標的方法之前,我認為看看妨礙我們實現目標的常見實踐是有幫助的。只有通過了解那些不斷重復的錯誤,我們才能開始接受另一種路徑。

          下面的示例都是我實際編寫的代碼的概括總結,雖然在技術上是有效的,但它們的結果都導致了災難和頭痛。盡管我的本意是好的,而且希望每次的開發會有所不同,但這些模式持續讓我陷入困境。

          根據組件的父類修改組件

          幾乎在 Web 上的每個站點中都有一個特定的視覺元素,它與每個事件看起來完全相同,只有一個例外。當遇到這種一次性的情況時,幾乎每一個新的 CSS 開發人員(甚至是經驗豐富的開發人員)都以同樣的方式處理它。您要為這個特定的事件找出某個唯一的父元素(或者創建一個),然后編寫一個新規則來處理它。

          .widget {
           background: yellow;
           border: 1px solid black;
           color: black;
           width: 50%;
          }
          #sidebar .widget {
           width: 200px;
          }
          body.homepage .widget {
           background: white;
          }
          

          初看起來這似乎是相當簡單的代碼,但是讓我們基于上面建立的目標來檢查它。

          首先,examle 中的小部件是不可預測的。一個開發過這些小部件的開發人員會希望它看起來是某種樣子的,但是當她在側邊欄或主頁上使用它時,它看起來就不一樣了,盡管標記完全一樣。

          這也不是可重復使用或可擴展的。當它在主頁上的樣子被要求在其他頁面上時,會發生什么呢?必須添加新的規則。

          最后,它不容易維護,因為如果要重新設計小部件,它必須在 CSS 中的幾個位置進行更新,并且與上面的示例不同,提交這種特定反模式的規則很少會出現在相鄰的位置。

          想像一下這個代碼是其它語言來完成的。你會先定義一個類,然后在另一部分代碼中深入到了該類的定義,根據特殊的用例對它進行修改。這直接違反了軟件開發的開放/封裝原則:

          軟件實體(類、模塊、函數等)應該為擴展開放,對修改封閉。

          本文稍后會介紹如何在不依賴父選擇器的情況下修改組件。

          過于復雜的選擇器

          偶爾會有一篇文章出現在互聯網上,展示 CSS 選擇器的強大功能,并宣稱無需使用任何類或 id 就可以對整個網站進行樣式設計。

          雖然在技術上是正確的,但是我使用 CSS 開發得越多,就越遠離復雜的選擇器。選擇器越復雜,它與 HTML 的耦合就越緊密。依賴 HTML 標記和組合符可以保持 HTML 的干凈,但它會讓 CSS 代碼變得很混亂和“骯臟”。

          #main-nav ul li ul li div { }
          #content article h1:first-child { }
          #sidebar > div > h3 + p { }
          

          以上所有的例子都符合邏輯。第一個可能是用樣式實現下拉菜單,第二個說文章的主標題應該看起來不同于所有 h1 元素,最后一個例子可能是在側邊欄的第一段增加一些額外的間距。

          如果這個 HTML 永遠不會改變,就可以對它的優點進行討論,但是假設這個 HTML 永遠不會改變的可能性有多大?過于復雜的選擇器可能會令人印象深刻,它們可以消除 HTML 中的所有表象的掛鉤,但它們很少幫助我們實現好的 CSS 架構的目標。

          上面的這些示例根本不能重用。由于選擇器指向標記中的一個非常特殊的位置,那么另一個具有不同 HTML 結構的組件如何重用這些樣式呢?以第一個選擇器(下拉列表)為例,如果在另一個頁面上需要一個類似的下拉列表,而它不在 #main-navelement 中呢?你必須重新打造整個樣式。

          如果 HTML 需要更改,這些選擇器也非常不可預測。假設一個開發者想將第三個示例中的 div 更改為 HTML5 section 標記,那么整個規則就會被破壞。

          最后,由于這些選擇器只在 HTML 保持不變的情況下才能工作,因此從定義上來說,它們是不可維護的或不可擴展的。

          在大型應用程序中,您必須做出權衡和妥協。以保持 HTML“干凈”的名義 —— 復雜選擇器的脆弱性幾乎不值得付出代價。

          過于通用的類名

          創建可利用的設計組件時,把子組件放在父組件名稱限定內(本來就是)是很常見的。例如:

          <div class="widget">
           <h3 class="title">...</h3>
           <div class="contents">
           Lorem ipsum dolor sit amet, consectetur adipiscing elit.
           In condimentum justo et est dapibus sit amet euismod ligula ornare.
           Vivamus elementum accumsan dignissim.
           <button class="action">Click Me!</button>
           </div>
          </div>
          .widget {}
          .widget .title {}
          .widget .contents {}
          .widget .action {}
          

          其想法是可以安全設置.title、.contents和 .action 這些子元素類的樣式而不用擔心這些樣式會不小心應用到其它使用相同類名的元素上。這個想法沒有錯,但它不能防止那些具有相同名稱的類定義影響到這個組件中的元素。

          在一個大型項目中,很有可能會有一個像 .title 這樣的類名用在其它上下文,甚至就在當前上下文中。如果確實有,組件的標題樣式看起來就可能和預期的不一樣。

          過于通用的類名會導致難以控制的 CSS。

          讓一個規則做太多事

          可能你需要在你的網站上把一個虛擬組件放在距某個部分左上角 20 像素的地方:

          .widget {
           position: absolute;
           top: 20px;
           left: 20px;
           background-color: red;
           font-size: 1.5em;
           text-transform: uppercase;
          }
          

          接下來你需要在不同的位置使用同樣的組件。上面的 CSS 起不到多大作用,因為它不能用在不同的環境中。

          問題在于你讓這個選擇器干了太多事情。你在這條規則里定義了視覺效果,又定義了布局和定位。視覺效果是可復用的,但布局和定位不能。既然他們被放在一起使用,那么整個規則都被破壞了。

          雖然這一開始這看起來似乎無害,但它往往導致從不太精通CSS的開發人員那里復制和粘貼代碼。如果一個新的團隊成員希望某些東西看起來像一個特定的組件,比如說.infobox,他們可能會從嘗試該類作為開始。但是,如果這不起作用,因為它是以不被期望的方式定位新的 infobox,那么他們可能會做什么? 根據我的經驗,大多數新開發人員不會將規則分解為可重用的部分。相反,他們只需將此特定實例所需的代碼行復制并粘貼到新的選擇器中,從而產生不必要的重復代碼。

          原因

          所有上述不良實踐都有一個相似之處,它們給CSS帶來了太多的樣式化的負擔。

          這貌似是很奇怪的說法。畢竟,這是一個樣式表; 它不應該承擔大部分(如果不是全部的話)樣式化負擔嗎? 這不是我們想要的嗎?

          這個問題的簡單答案是“是的”,但像往常一樣,事情并不總是那么簡單。將內容與表示層分離是一件好事,但僅僅因為你的CSS與HTML分開并不意味著你的內容與你的表示層是獨立的。換句話說,如果你的CSS需要詳細了解HTML結構才能工作,那么從HTML中刪除所有表示層代碼并不能實現此目標。

          此外,HTML不僅僅是內容;它也包含結構。通常,該結構是由容器元素組成,這些元素除了允許CSS隔離特定組內元素之外沒有其他用途。即使沒有表示類,這仍然清楚地混入到HTML中。但它是否必須將表示層與內容混合在一起呢?

          我相信,鑒于HTML和CSS的目前狀態,將HTML和CSS作為表示層協同工作是必要且通常情況下的明智之舉。內容層仍然可以通過模板和部分抽象出來。

          解決方案

          如果你的HTML和CSS將協同工作以構成Web應用程序的表示層,那么他們需要以提升優良CSS體系結構的所有原則的方式來完成。

          我發現最佳方法是在CSS中包含盡可能少的HTML結構。CSS應該定義一組可視元素的外觀(為了最大限度地減少與HTML的耦合),以及這些元素應該被看做是已定義的,無論它們出現在HTML中的哪個位置。如果某個組件在不同的場景中需要看起來不同,那么它應該被稱為不同的東西,并且HTML的責任就是調用它。

          例如,CSS可以通過.button類定義一個按鈕組件。如果HTML希望特定元素看起來像一個按鈕,它應該使用該類。如果有一種情況是讓按鈕看起來不同(可能更大和全幅),那么CSS需要使用新類來定義其外觀,并且HTML可以包含使用新外觀的新類。

          CSS 定義組件的外觀,HTML 將這些外觀分配給頁面上的元素。CSS 對 HTML 結構的了解越少越好。

          在 HTML 中聲明您想要的內容的一個巨大好處是,它允許其他開發人員查看標記,并確切地知道元素應該是什么樣子。意圖很明顯。如果不這樣做,就不可能判斷一個元素的外觀是故意的還是偶然的,這會導致團隊產生混亂。

          在標記中放置大量類的一個常見問題是需要付出額外的努力。單個 CSS 規則可以針對 1000 個特定組件的實例。僅僅在標記中顯式地聲明類一千次,真的值得嗎?

          盡管這種擔憂顯然是有道理的,但它可能具有誤導性。這意味著,要么在 CSS 中使用父選擇器,要么手工編寫 HTML 類 1000 次,但顯然還有其他選擇。Rails 或其他框架中的視圖級別抽象可以在很大程度上保持 HTML 中顯式聲明的可視化外觀,而無需反復編寫相同的類。

          最佳實踐

          在一遍又一遍地犯了上述錯誤,并在之后的路上自食其果之后,我想出了以下幾點建議。雖然并不全面,但我的經驗表明,堅持這些原則將有助于你更好地實現良好 CSS 架構的目標。

          刻意為之

          確保選擇器不樣式化不需要的元素的最佳方法是不給他們機會。像 #main-nav ul li ul li div 這樣的選擇器很容易在你的標記發生變化時最終應用于不需要的元素。另一方面,像 .subnav 這樣的樣式絕對不會意外地應用于不需要的元素。將類直接應用于要設置樣式的元素是保持 CSS 可預測性的最佳方法。

          /* Grenade */
          #main-nav ul li ul { }
          /* Sniper Rifle */
          .subnav { }
          

          想想一下上面兩個例子,第一個像手榴彈,第二個像狙擊步槍。手榴彈今天可能工作得很好,但你永遠不知道何時一個無辜的平民可能在爆炸范圍內移動。

          隔離你的擔憂

          我已經提到過,組織良好的組件層可以幫助降低 CSS 中 HTML 結構的耦合。除此之外,你的 CSS 組件本身應該是模塊化的。組件應該知道如何自己完成樣式化并做好這項作業,但它們不應該對它們的布局或定位負責,也不應該對它們與周圍元素的間隔方式做出太多假設。

          通常,組件應定義它們的外觀,而不是它們的布局或位置。在與位置、寬度、高度和邊距相同的規則中若看到背景、顏色和字體等屬性時要額外小心。

          布局和位置應由單獨的布局類或單獨的容器元素處理。(謹記,為了有效地將內容與表示層分開,通常必須將內容與其容器隔離。)

          給你的類添加命名空間

          我們已經研究了為什么父選擇器在封裝和預防樣式交叉影響不是100%有效。一種更好的方法是將命名空間應用于類本身。如果元素是可視組件的成員之一,則其每個子元素類都應使用以組件的基類名命名的命名空間。

          /* High risk of style cross-contamination */
          .widget { }
          .widget .title { }
          /* Low risk of style cross-contamination */
          .widget { }
          .widget-title { }
          

          命名空間使你的組件保持獨立和模塊化。它最大限度地降低了現有類沖突的可能性,并降低了樣式子元素所需的特異性。

          使用修飾類擴展組件

          當某個現有組件在某個上下文中需要略有不同時,請創建一個修飾符類來擴展它。

          /* Bad */
          .widget { }
          #sidebar .widget { }
          /* Good */
          .widget { }
          .widget-sidebar { }
          

          我們已經看到了基于其父元素之一修改組件的缺點,但重申一下:修飾符類可以在任何地方使用。基于位置的覆蓋只能在特定位置使用。修飾符類也可以根據需要重復使用多次。最后,修飾符類在HTML中非常明確地表達了開發者的意圖。另一方面,基于位置的類對于僅查看HTML的開發者來說是完全不可見的,這大大增加了被忽略的可能性。

          將你的CSS組織到一個邏輯結構體中

          Jonathan Snook在他的著作SMACSS中,主張將CSS規則分為四個不同的類別:基礎、布局、模塊以及狀態。基礎類別由重置規則和元素的默認值組成。布局類別主要用于定位站點范圍的元素以及網格系統等通用布局助手。模塊類別是可重用的可視元素,而狀態類別指的是可以通過JavaScript切換打開或關閉的樣式。

          在SMACSS系統中,模塊(相當于我稱之為組件的部分)構成了絕大多數CSS規則,因此我經常發現有必要將它們進一步分解為抽象模板。

          組件是獨立的可視元素。另一方面,模板是構建塊。模板不能獨立存在,很少描述其外觀和感覺。相反,它們是單一的、可重復的模式,可組合在一起形成一個組件。

          為了提供具體示例,組件可能是模式對話框。模式對話框可能在頭中具有網站的簽名背景漸變,它周圍可能有陰影效果,右上角可能有一個關閉按鈕,它可能是固定位置并垂直和水平居中的。這四種模式中的每一種都可以在整個站點上反復使用,因此你不希望每次都重新編碼這些模式。因此,它們都是模板,它們一起構成模態組件。

          我通常不在HTML中使用模板類,除非我有充分的理由。相反,我使用預處理器在組件定義中包含模板樣式。我將在后面內容中更詳細地討論這個和我如此做的合理之處。

          僅在樣式化時使用類

          任何從事大型項目的人都遇到過一個HTML元素,其中一個類的用途是完全未知的。你想刪除它,但你會猶豫不決,因為它可能有一些你不知道的用途。隨著時間的推移,這種事情一次次發生,你的HTML會被沒有用處的類填滿,因為團隊成員害怕刪除它們。

          問題是在前端Web開發中,類通常被賦予太多的責任。它們設置HTML元素的樣式,它們充當JavaScript鉤子,它們被添加到HTML中以進行特征檢測,它們被用于自動化測試等。

          這是個問題。當應用程序中的太多部分使用此類時,從HTML中刪除它們會變得非常可怕。

          但是,根據既定慣例,此問題是可以完全避免的。當你在HTML中看到一個類時,你應該能夠立即知道它的用途。我的建議是給所有非樣式類添加前綴。我在JavaScript中使用.js-,同時使用.supports-用于Modernizr類。所有沒有前綴的類僅用于樣式。

          這使得查找未使用的類并將其從HTML中刪除就像搜索樣式表目錄一樣簡單。你甚至可以通過使用document.styleSheets對象中的類交叉引用在HTML中使用JavaScript自動化此過程。不在document.styleSheets中的類可以安全刪除了。

          一般而言,與將內容與展示層分開的最佳做法類似,將展示層與功能分開也是很重要的。使用樣式化的類作為JavaScript鉤子深深地將CSS和JavaScript耦合在一起,這樣就可以在不破壞功能的情況下更新或更改某些元素的外觀。

          使用邏輯結構命名你的類

          現在大多數人用連字符作為單詞分隔符編寫CSS。但單獨的連字符通常不足以區分不同類型的類。

          Nicolas Gallagher最近寫了關于他解決這個問題的方案,我也采用了這個方案(略有改動)并取得了巨大的成功。為了舉例說明命名慣例的需要,請考慮以下內容:

          /* A component */
          .button-group { }
          /* A component modifier (modifying .button) */
          .button-primary { }
          /* A component sub-object (lives within .button) */
          .button-icon { }
          /* Is this a component class or a layout class? */
          .header { }
          

          通過查看上述類,無法確定它們適用于何種類型的規則。這不僅會增加開發過程中的困惑,而且還會使自動化測試CSS和HTML變得更加困難。結構化命名慣例允許你在看到類名時準確地知道它與其他類的關系以及它應該在HTML中出現的位置 - 使命名更容易,并且可以在之前沒有的地方進行測試。

          /* Templates Rules (using Sass placeholders) */
          %template-name
          %template-name--modifier-name
          %template-name__sub-object
          %template-name__sub-object--modifier-name
          /* Component Rules */
          .component-name
          .component-name--modifier-name
          .component-name__sub-object
          .component-name__sub-object--modifier-name
          /* Layout Rules */
          .l-layout-method
          .grid
          /* State Rules */
          .is-state-type
          /* Non-styled JavaScript Hooks */
          .js-action-name
          

          重新編寫下第一個示例:

          /* A component */
          .button-group { }
          /* A component modifier (modifying .button) */
          .button--primary { }
          /* A component sub-object (lives within .button) */
          .button__icon { }
          /* A layout class */
          .l-header { 
          

          工具

          維護高效且組織良好的CSS架構可能非常困難,尤其是在大型團隊中。這里和那里的一些不好的規則可能會導致無法控制的混亂局面。一旦你的應用程序的CSS進入了種族和!important主之爭,除了從頭再來之外,它幾乎不可能在其他情況下恢復。關鍵是從一開始就避免這些問題。

          幸運的是,有一些工具可以更輕松地控制你網站的CSS架構。

          預處理器

          現在,如果不提及預處理器,探討CSS工具是不可能的,所以本文不會例外。但在我贊揚它們的用處之前,我應該提供一些警示。

          預處理器可以幫助你更快地編寫CSS,而不是更好地。最終它變成了普通的CSS,并且相同的規則同樣適用。如果預處理器允許你更快地編寫CSS,那么它還可以讓你更快地編寫糟糕的CSS,因此在考慮預處理器將解決你的問題之前理解好的CSS架構是非常重要的。

          許多預處理器的所謂“特性”實際上在 CSS 架構上是非常糟糕。以下是一些我不惜一切代價避免的“功能”(雖然常規的想法適用于所有預處理器語言,但這些指南特別適用于 Sass )。

          • 永遠不要僅為了代碼組織而嵌套規則。只有在輸出的 CSS 是你想要的時候才嵌套。
          • 如果你沒有在傳遞參數,切勿使用 mixin 。沒有參數的 Mixin 用作可擴展的模板更合適。
          • 切勿在非單個類的選擇器上使用 @extend 。從設計的角度來看它沒有意義,并且它使編譯的 CSS 膨脹了。
          • 永遠不要在組件修飾符規則中的 UI 組件上使用 @extend ,因為你將丟失了繼承鏈(稍微多了一點)

          預處理器的最佳部分是 @extend 以及%placeholder 等函數。兩者都允許你輕松管理 CSS 抽象,而不會在你的 CSS 中添加代碼膨脹,或者在 HTML 中的增加大量可能難以管理的基類。

          @extend 應謹慎使用,因為有時你需要 HTML 中的這些類。例如,當你第一次學習 @extend 時,你可能很想將它與所有修飾符類一起使用,如下所示:

          .button {
           /* button styles */
          }
          /* Bad */
          .button--primary {
           @extend .button;
           /* modification styles */
          }
          

          這樣做的問題是你丟失了 HTML 中的繼承鏈。現在用 JavaScript 選擇所有按鈕實例變得非常困難。

          作為一般規則,我從不擴展 UI 組件或任何稍后我可能想獲取其類型的東西。這是模板的用武之地,以及輔助區分模板和組件的另一種方法。模板是你在應用程序邏輯中無需定位的東西,因此可以使用預處理器進行安全地擴展。

          以下是使用上述所引用的模態示例的可能的代碼結構:

          .modal {
           @extend %dialog;
           @extend %drop-shadow;
           @extend %statically-centered;
           /* other modal styles */
          }
          .modal__close {
           @extend %dialog__close;
           /* other close button styles */
          }
          .modal__header {
           @extend %background-gradient;
           /* other modal header styles */
          }
          

          CSS Lint

          Nicole Sullivan 和 Nicholas Zakas 創建了 CSS Lint 作為代碼質量工具,以幫助開發人員檢測 CSS 中的不良實踐。他們的網站對此工具描述如下:

          CSS Lint 指出了你 CSS 代碼中的問題。它執行基本的語法檢查,并將一組規則應用于代碼以查找存在問題的模式或低效率跡象的代碼。[規則]都是可插拔的,因此你可以輕松編寫你特有的或跳過那些你不想要的規則。

          雖然常規的規則集可能不太適用于大多數項目,但 CSS Lint 的最佳功能是能夠根據你的需求進行自定義。這意味著你可以從默認列表中選擇所需的規則,也可以編寫自己的規則。

          為確保大型團隊能至少有一個代碼一致性和遵從開發慣例的基線,CSS Lint這樣的工具是必不可少的,就像我之前示意過的,開發慣例存在的一個重要原因是它能使像CSS Lint這樣的工具很容易地識別任何破壞它們的東西。

          基于我上面提到的開發慣例,編寫規則來檢測特定的違反慣例的模式變得非常容易。以下是我的一些建議:

          • 不要在選擇器中使用id。
          • 不要在任何多部分規則中使用非語義類型選擇器(例如DIV、SPAN)。
          • 不要在選擇器中使用超過2個組合符。
          • 不要允許任何以“js-”開頭的類名。
          • 頻繁使用布局和定位非“l-”前綴規則要被警示。
          • 如果一個類本身定義后被重新定義為其他類的子類要被警示。

          這些顯然只是建議罷了,它們旨在讓您考慮如何在項目中執行您想要的標準。

          HTML檢查器

          我早些時候建議過可以很容易地搜索HTML類和所有鏈接樣式表,并指出如果HTML中使用但沒有在任何樣式表中定義的類時要提出警示 。為使這個過程更容易,我目前正在開發一個名叫HTML檢查器的工具。

          HTML檢查器遍歷您的HTML(非常像CSS Lint)并允許您編寫自己的規則,當某些規則被破壞時時就拋出錯誤和警告。我目前使用以下規則:

          • 如果同一ID在頁面上使用多次提出警示。
          • 不要使用任何樣式表中沒有提到的類或傳遞白名單(如“js-”前綴類)。
          • 修改類不應該在沒有基類的情況下使用。
          • 當沒有父類包含基類時,不應該使用子對象類。
          • 在HTML中如果沒有附加類就不應該使用普通的舊DIV或SPAN元素

          總結

          CSS不僅僅是視覺設計。不要僅僅因為你在編寫的是CSS,就扔掉編程最佳實踐。軟件開發中用到的這些OOP、DRY、開閉原則和分離關注點等概念也仍然適用于CSS。

          作CSS開發工作時,你得守住判斷你工作是否有價值的底線,這就是不管你如何編寫代碼,你都要確保你依據你的工作方法,將來很長一段時間內這個方法會使你的開發更容易,使你的代碼更好維護。

          關于作者

          Philip Walton是AppFolio的前端工程師。想了解更多這些想法,你可以閱讀他的博客或在Twitter上關注他:http://philipwalton.com @philwalton

          開源社區OSC「好文翻譯」欄目,旨在每天為用戶推薦并翻譯優質的外網文章。再也不用怕因為英語不過關,被擋在許多技術文章的門外。關注開源社區OSC,每日獲取翻譯好文推薦,點擊“了解更多”,閱讀原文章。

          ↓↓↓

          、通過搜索引擎,檢索“快遞公司排名”“快遞公司排名”“電商物流品牌”“物流評價指數”等等相關關鍵詞,查閱對電商物流企業常用的評價角度,比如:服務能力、服務口碑、發展績效、品牌指數、消費評價、安全性、滿意度、投訴率、快遞速度等等。

          2、分別以對“電商物流”“快遞物流”等相關關鍵詞,檢索以上角度的網絡評價報告。如:

          中國物流與采購聯合會:http://www.chinawuliu.com.cn/lhhzq/202005/11/502855.shtml

          買購網:https://www.maigoo.com/maigoo/939kuaidi_index.html

          深圳之窗:https://chat.shenchuang.com/xwrd/20200623/1547576.shtml

          排行榜:https://www.phb123.com/hangye/wuliu/8326.html

          中華人民共和國國家郵政局:http://www.spb.gov.cn/xw/dtxx_15079/201904/t20190424_1819245.html

          中國情報網:https://top.askci.com/news/20190701/1011551149047.shtml

          中國報告大廳:http://www.chinabgao.com/enterprise/708.html

          3、將對應的數據形成表格,如:

          表6.4 快遞服務評價表

          快遞企業

          服務能力

          服務口碑

          發展績效

          品牌指數

          消費評價

          安全性

          滿意度

          投訴率

          快遞速度

          綜合評價

          EMS

          88.2

          83.29

          55.61

          9.7

          8.26

          5顆星

          76+

          15.98

          第四名

          順豐

          86.26

          89.94

          65.81

          10

          7

          5顆星

          80+

          11.45

          第一名

          申通

          67.37

          81.43

          56.9

          9

          7.41

          4顆星

          76+

          6

          第四名

          中通

          67.14

          82.27

          45.77

          9.6

          7.32

          4顆星

          76+

          3.9

          第三名

          德邦

          74.82

          85.65

          68.99

          8.3

          5.45


          74+

          31.71


          資料來源

          中國物流與采購聯合會

          中國物流與采購聯合會

          中國物流與采購聯合會

          買購網

          深圳之窗

          排行榜

          中華人民共和國國家郵政局

          中國情報網

          中國報告大廳


          根據對應數據,形成對快遞物流的服務綜合評價,評價等級分為:優良中差等級別。


          上一篇:HTML 布局
          下一篇:關于html元素的css-定位
          主站蜘蛛池模板: 97精品国产一区二区三区| 亚洲一区免费视频| 一区二区亚洲精品精华液| 乱码人妻一区二区三区| 亚洲乱码一区av春药高潮| 国产精品乱码一区二区三区| 亚洲一区精品视频在线| 国产一区二区三区内射高清| 久久精品一区二区三区不卡| 午夜精品一区二区三区在线视| 久久一区二区三区免费播放| 国产成人无码精品一区不卡 | 一区二区三区视频免费观看| 精品三级AV无码一区| 久久青草精品一区二区三区| 一区二区三区福利视频| 亚洲AV无码一区二区三区电影| 国产福利精品一区二区| 国模少妇一区二区三区| 国产日韩AV免费无码一区二区| 中文字幕一区二区三区在线不卡| 国精产品一区一区三区有限在线| 亚洲av无码一区二区三区网站| 寂寞一区在线观看| 一区二区三区在线|欧| 免费视频一区二区| 日韩亚洲AV无码一区二区不卡| 亚洲不卡av不卡一区二区| 麻豆高清免费国产一区| 亚洲国产AV无码一区二区三区| 无码人妻久久一区二区三区免费| 亚洲一区二区电影| 日本免费一区二区三区最新| 一区二区三区精品视频| 国产一区二区三区乱码| 波多野结衣一区二区三区高清在线| 一区二区在线视频免费观看| 成人区精品一区二区不卡亚洲| 国产一区二区三区樱花动漫| 久久影院亚洲一区| 日本一区二区三区在线看|