整合營銷服務商

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

          免費咨詢熱線:

          你不可不知的HTML優化技巧,還不抓緊時間收藏

          何提升Web頁面的性能,很多開發人員從多個方面來下手如JavaScript、圖像優化、服務器配置,文件壓縮或是調整CSS。

          很顯然HTML 已經達到了一個瓶頸,盡管它是開發Web 界面必備的核心語言。HTML頁面的負載也是越來越重。大多數頁面平均需要40K的空間,像一些大型網站會包含數以千計的HTML 元素,頁面Size會更大。

          如何有效的降低HTML 代碼的復雜度和頁面元素的數量,本文主要解決了這個問題,從多個方面介紹了如何編寫簡練,清晰的HTML 代碼,能夠使得頁面加載更為迅速,且能在多種設備中運行良好。

          在設計和開發過程中需要遵循以下原則:

          • 結構分離:使用HTML 增加結構,而不是樣式內容;
          • 保持整潔:為工作流添加代碼驗證工具;使用工具或樣式向導維護代碼結構和格式
          • 學習新語言:獲取元素結構和語義標記。
          • 確保可訪問: 使用ARIA 屬性和Fallback 屬性等
          • 測試: 使網站在多種設備中能夠良好運行,可使用emulators和性能工具。

          HTML,CSS 和JavaScript三者的關系

          HTML 是用于調整頁面結構和內容的標記語言。HTML 不能用于修飾樣式內容,也不能在頭標簽中輸入文本內容,使代碼變得冗長和復雜,相反使用CSS 來修飾布局元素和外觀比較合適。HTML元素默認的外觀是由瀏覽器默認的樣式表定義的,如在Chrome中h1標簽元素會渲染成32px的Times 粗體。

          三條通用設計規則:

          1. 使用HTML 來構造頁面結構,CSS修飾頁面呈現,JavaScript實現頁面功能。CSS ZenGarden 很好地展示了行為分離。
          2. 如果能用CSS或JavaScript實現就少用HTML代碼。
          3. 將CSS和JavaScript文件與HTML 分開存放。這可有助于緩存和調試。

          文檔結構方面也可以做優化,如下:

          • 使用HTML5 文檔類型,以下是空文件:
          <!DOCTYPE html>
          <html>
          <head>
           <title>Recipes: pesto</title>
          </head>
          <body>
           <h1>Pesto</h1>
           <p>Pesto is good!</p>
          </body>
          </html>
          
          • 在文檔起始位置引用CSS文件,如下:
          <head>
           <title>My pesto recipe</title>
           <link rel="stylesheet" href="/css/global.css">
           <link rel="stylesheet" href="css/local.css">
          </head>
          

          使用這兩種方法,瀏覽器會在解析HTML代碼之前將CSS信息準備好。因此有助于提升頁面加載性能。

          在頁面底部body結束標簽之前輸入JavaScript代碼,這樣有助于提升頁面加載的速度,因為瀏覽器在解析JavaScript代碼之前將頁面加載完成,使用JavaScript會對頁面元素產生積極的影響。

          <body>
           ...
           <script src="/js/global.js">
           <script src="js/local.js">
          </body>
          

          使用Defer和async屬性,腳本元素具有async 屬性無法保證會按順序執行。

          可在JavaScript代碼中添加Handlers。千萬別加到HTML內聯代碼中,比如下面的代碼則容易導致錯誤且不易于維護:

          index.html:

          <head>
           ...
           <script src="js/local.js">
          </head>
          <body onload="init()">
           ...
           <button onclick="handleFoo()">Foo</button>
           ...
          </body>
          

          下面的寫法比較好:

          index.html:

          <head>
           ...
          </head>
          <body>
           ...
           <button id="foo">Foo</button>
           ...
           <script src="js/local.js">
          </body>
          

          js/local.js:

          init();
          var fooButton =
           document.querySelector('#foo');
          fooButton.onclick = handleFoo();
          

          驗證

          優化網頁的一種方法就是瀏覽器可處理非法的HTML 代碼。合法的HTML代碼很容易調試,且占內存少,耗費資源少,易于解析和渲染運行起來更快。非法的HTML代碼讓實現響應式設計變得異常艱難。

          當使用模板時,合法的HTML代碼顯得異常重要,經常會發生模板單獨運行良好,當與其他模塊集成時就報各種各樣的錯誤,因此一定要保證HTML代碼的質量,可采取以下措施:

          • 在工作流中添加驗證功能:使用驗證插件如HTMLHint或SublineLinter幫助你檢測代碼錯誤。
          • 使用HTML5文檔類型
          • 確保HTML的層次結構易于維護,要避免元素嵌套處于左開狀態。
          • 保證添加各元素的結束標簽。
          • 刪除不必要的代碼 ;沒有必要為自關閉的元素添加結束標簽;Boolean 屬性不需要賦值,如果存在則為True;

          代碼格式

          格式一致性使得HTML代碼易于閱讀,理解,優化,調試。

          語義標記

          語義指意義相關的事物,HTML 可從頁面內容中看出語義:元素和屬性的命名一定程度上表達了內容的角色和功能。HTML5 引入了新的語義元素,如<header>,<footer>及<nav>。

          選擇合適的元素來編寫代碼可保證代碼的易讀性:

          • 使用<h1>(<h2>,<h3>…)表示標題,<ul>或<ol>實現列表
          • 注意使用<article> 標簽之前應添加<h1>標簽;
          • 選擇合適的HTML5語義元素如<header>,<footer>,<nav>,<aside>;
          • 使用<p>描述Body 文本,HTML5 語義元素可以形成內容,反之不成立。
          • 使用<em>和<strong>標簽替代<i>和<b>標簽。
          • 使用<label>元素,輸入類型,占位符及其他屬性來強制驗證。
          • 將文本和元素混合,并作為另一元素的子元素,會導致布局錯誤,

          例如:

          <div>Name: <input type="text" id="name"></div>
          

          換種寫法會更好:

           1: <div>
           2: <label for="name">Name:</label><input type="text" id="name">
           3: </div>
          

          布局

          要提高HTML代碼的性能,要遵循HTML 代碼以實現功能和為目標,而不是樣式。

          • 使用<p>元素修飾文本,而不是布局;默認<p>是自動提供邊緣,而且其他樣式也是瀏覽器默認提供的。
          • 避免使用<br>分行,可以使用block元素或CSS顯示屬性來代替。
          • 避免使用<hr>來添加水平線,可使用CSS的border-bottom 來代替。
          • 不到關鍵時刻不要使用div標簽。
          • 盡量少用Tables來布局。
          • 可以多使用Flex Box
          • 使用CSS 來調整邊距等。

          CSS

          雖然本文講解的是如何優化HTML,下面介紹了一些使用css的基本技能:

          • 避免內聯css
          • 最多使用ID類 一次
          • 當涉及多個元素時,可使用Class來實現。

          以上就是本文介紹的優化HTML代碼的技巧,一個高質量高性能的網站,往往取決于對細節的處理,因此我們在日常開發中,能夠考慮到用戶體驗,后期維護等方面,則會產生更高效的開發。

          者:HXGNMSL來源:CSDN原文:https://blog.csdn.net/HXGNMSL/article/details/89076476

          Javascript的歷史來源

          94年網景公司 研發出世界上第一款瀏覽器。

          95年 sun公司 java語言誕生

          網景公司和sun合作。

          Javascript ===> javascript

          JavaScript和ECMAScript的關系

          簡單來說ECMAScript不是一門語言,而是一個標準。符合這個標準的比較常見的有:JavaScript、Action Script(Flash中用的語言)

          JavaScript的基本結構:

          JavaScript的語法:

          JavaScript的基礎語法

          變量的聲明及使用

          數據類型

          運算符

          邏輯控制語句

          注釋

          語法規則

          變量的聲明語法:

          var變量名;

          例如:

          Var num;

          然后進行賦值:num = 10;也可以聲明時直接賦值:

          Var num =10;

          在JavaScript中,提供了常用的基本數據類型:

          undefined 未定義;

          null 空;

          string 字符串類型;

          boolean 布爾類型;

          number 數值類型;

          運算符:

          算數運算符:+、-、*、/、%、++、–;

          比較運算符:>、<、> =、< =、==、!=;

          邏輯運算符:&&、||、!;

          賦值運算符:=;

          邏輯控制語句:

          JavaScript的邏輯控制語句也分為兩類:條件結構和循環機構。

          條件結構

          條件機構分為if結構和switch結構:

          If…else

          Switch

          循環結構

          JavaScript的循環結構的執行順序與Java類似,主要包括以下幾種結構:

          for循環

          while循環

          do…while循環

          for…inx循環

          示例:

          for(var i=0;i<10;i++){

          Document.write(“*”);

          }

          輸出結果:**********

          循環中斷:

          用于循環中斷的語句有以下兩種:

          break.

          continue.

          與Java用法一樣,break是跳出循環,continue是跳入下一次循環。

          函數

          函數有兩種:一種是系統函數,一種是自定義函數

          常用的系統函數包括:

          parseInt():轉換為整數。

          parseFloat():轉換為浮點型。

          isNaN():判斷非數字。

          Eval():計算表達式值。

          自定義函數:

          自定義函數的語法

          function 函數名(參數1,參數2,…){

          …//語句

          Return 返回值;//可選

          }

          函數的調用:

          函數的調用方式有以下兩種

          事件名=函數名(傳遞的實參值),例如:

          “函數名()”

          直接使用函數名(傳遞的實參值),例如:

          var recult = add(2,3);

          匿名函數

          匿名函數的語法

          var sumFun=function(num1,num2){

          return(nun1,num2);

          } ;

          在語法中:

          var sunFun=function(num1,num2)表示聲明一個變量等于某個函數體。

          {…};是把整個函數體放在變量的后面,并把末尾添加一個分號。

          匿名函數的調用:

          由于匿名函數定義的整個語句,可以像賦值一樣賦給一個變量進行保存,所以可以使用如下方式調用語法中的匿名函數:

          var sum=sumFun(2,3)

          BOM概述

          使用BOM可以移動窗口,改變狀態欄中的文本,執行其他與頁面內容不直接相關的動作。它包含的對象主要有以下幾種;

          Window對象

          Window對象是指整個窗口對象,可以通過操作Window對象的屬性和方法控制窗口,例如,打開或關閉一個窗口。

          History對象

          瀏覽器訪問過的歷史頁面對應History對象,通過History對象的屬性和方法實現瀏覽器的前進或后退的功能。

          Location對象

          瀏覽器的地址欄對應Location對象,通過Location對象的屬性和方法控制頁面跳轉。

          Document對象

          瀏覽器內的網頁內容對應Document對象,通過Document對象的屬性和方法,控制頁面元素。

          Window常用的屬性有:

          history:有關客戶訪問過的URL的信息。

          location:有關當前URL的信息。

          Screen: 有關客戶端的屏幕和顯示性能的信息。

          Window對象常用的方法:

          prompt():顯示可提示用戶輸入的對話框。

          alert():顯示帶有一段消息和一個人“確認”按鈕的警告框。

          confirm():顯示帶有一段消息以及“確認”按鈕“取消”按鈕的對話框。

          close():關閉瀏覽器窗口。

          open():打開一個新的瀏覽器窗口,加載給定URL所指定的文檔。

          setTimeout():用于在指定(以毫秒計)后調用函數或計算表達式。

          setTneerval():按照指定的周期 (以毫秒計)數來調用函數或計算表達式。

          Window對象常用窗口特征屬性

          height、width:窗口文檔顯示區的高度、寬度,以像素計。

          left、top:窗口的x坐標y坐標,以像素計。

          toolbar:yes|no|1|0:是否顯示瀏覽器的工具欄,默認是yes。

          scrollbars =yes|no|1|0:是否顯示滾動條,默認是yes。

          locationyes|no|1|0:是否顯示地址欄,默認是yes。

          status|no|1|0:是否添加地址欄,默認是yes。

          menubar|no|1|0:是否顯示菜單欄,默認是yes。

          resizable|no|1|0:窗口是否可調節尺寸,默認是yes。

          Window對象的常用事件:

          onload:一個頁面或一副圖像完成加載。

          onmouseover:鼠標指針移到某元素之上。

          onclick:單擊某個對象。

          onkeydown:某個鍵盤按鍵被按下。

          onchange:域的內容被改變。

          History對象的方法:

          back():加載History對象列表中的上一個URL。

          forward():加載History對象列表中的下一個URL。

          go():加載History對象列表中的某個具體URL。

          Location對象的屬性:

          host:設置或返回主機名和當前URL的端口號。

          hostname:設置或返回當前URL的主機名。

          href:設置或返回完整的URL。

          Location對象的方法:

          reload():重新加載當前文檔。

          replace():用新的文檔替換當前文檔。

          Document對象常用的屬性:

          referrer:返回載入當前文檔的URL。

          URL:返回當前文檔的URL。

          Document對象的常用方法:

          getElementById():返回對擁有指定id的第一個對象的引用。

          getElementsByName():返回帶有指定名稱的對象的集合。

          getElementsByTagName():返回帶有指定標簽名的對象的集合。

          write():向文檔寫文本、HTML表達式代碼。

          內置對象

          系統的內置對象有Date對象、Array對象、String對象和Math對象等。

          Date:用于操作日期和時間。

          Array:用于在單獨的變量名中儲存一系列的值。

          String:用于支持對字符串的處理。

          Math:用于執行數學任務,包含了若干數字常量和函數。

          Date對象:

          1:創建日期對象

          Date對象包含日期和時間兩個信息,創建日期對象的基本語法有兩種:

          創建日期的基本語法1: var 日期實例化=new Date(參數);

          創建日期的基本語法2: var 日期實例化=new Date();

          Date對象的常用方法:

          getDate():從Date對象返回一個月中的某一天,其值介于1到31之間。

          getDay():從Date對象返回星期中的某一天,其值介于0到6之間。

          getHours():返回Date對象的小時,其值介于0到23之間。

          getMinutes():返回Date對象的分鐘,其值介于0到59之間。

          getSeconds():返回Date對象的秒數,其值介于0到59之間。

          getMonth():返回Date對象的月份,其值介于0到11之間。

          getFullYear():返回Date對象的年份,其值為4位數。

          getTime():返回自某一時刻(2010年1月1日)以來的毫秒數。

          DOM概述

          什么是DOM

          DOM是文檔對象的縮寫,和語言無關。它提供了訪問、動態修改結構文檔的接口,W3C制定了DOM規范,主流瀏覽器都支持。

          使用Core DOM操作節點

          訪問節點:

          使用getElement系列方法訪問指定節點。

          getElementById():返回對擁有指定id的第一個對象的引用。

          getElementsByName():返回帶有指定名稱的對象的集合。

          getElementsByTagName():返回帶有指定標簽名的對象的集合。

          使用層次關系訪問節點。

          parenNode:返回節點的父節點。

          firstChild:返回節點的首個節點。文本和屬性節點沒有父節點,會返回一個空數組,對于元素節點,若是沒有子節點會返回null。

          lastChild:返回節點的最后一個子節點,返回值同firstChild。

          操作節點屬性值

          CoreDOM的標準方法包括以下兩種:

          getAttribute(“屬性名”):獲取屬性值。

          getAttribute(“屬性名”,“屬性值”):設置屬性值

          創建和增加節點:

          創建節點

          createElement(tagName):按照給定的標簽名稱創建一個新的元素節點

          appendChild(nodeName):向以存在節點列表的末尾添加新的節點。

          inserBefore(newNode,oldNode):向指定的節點之前插入一個新的子節點。

          cloneNode(deep):復制某個指定的節點。

          刪除和替換節點

          removeChild(node):刪除指定的節點。

          replaceChild(newNode,oldNode):用其他的節點替換指定的節點。

          Table對象的屬性和方法

          屬性:

          rows[]:返回包含表格中所有行的一個數組。

          rows[]用于返回表格中所有行的一個數組。

          方法:

          inserRow():在表格中插入一個新行。

          deleteRow():從表格中刪除一行。

          數組

          數組是具有相同數據類型的一個或多個值得集合

          創建數組的語法:

          var 數組名稱=new Array(size);

          數組的賦值的兩種方式:

          先聲明在賦值

          var province = new Array(4);

          province[0]=“河北省”;

          province[1]=“河南省”;

          索引也可以使用標識(字符串),例如:

          var province=new Array(4);

          province[‘河北省’]=“河北省”;

          province[‘河南省’]=“河南省”;

          聲明時同時初始化

          var province=new Array(“河北省”,“河南省”,“湖北省”,“廣東省”);

          Array對象的常用屬性和方法:

          屬性:

          length:設置或返回數組中元素的數目。

          方法:

          join():把數組的所有元素放入一個字符串,通過一個分隔符進行分割。

          sort():對數組的元素進行排序。

          家好,我是皮湯。最近業務調整,組內開啟了前端工程化方面的基建,我主要負責 CSS 技術選型這一塊,針對目前業界主流的幾套方案進行了比較完善的調研與比較,分享給大家。

          目前整個 CSS 工具鏈、工程化領域的主要方案如下:

          而我們技術選型的標準如下:

          - 開發速度快

          - 開發體驗友好

          - 調試體驗友好

          - 可維護性友好

          - 擴展性友好

          - 可協作性友好

          - 體積小

          - 有最佳實踐指導

          目前主要需要對比的三套方案:

          - Less/Sass + PostCSS 的純 CSS c側方案

          - styled-components / emotion 的純 CSS-in-JS 側方案

          - TailwindCSS 的以寫輔助類為主的 HTML 側方案

          ## 純 CSS 側方案

          ### 介紹與優點

          > 維護狀態:一般

          > Star 數:16.7K

          > 支持框架:無框架限制

          > 項目地址:https://github.com/less/less.js

          Less/Sass + PostCSS 這種方案在目前主流的組件庫和企業級項目中使用很廣,如 ant-design 等

          它們的主要作用如下:

          - 為 CSS 添加了類似 JS 的特性,你也可以使用變量、mixin,寫判斷等

          - 引入了模塊化的概念,可以在一個 less 文件中導入另外一個 less 文件進行使用

          - 兼容標準,可以快速使用 CSS 新特性,兼容瀏覽器 CSS 差異等

          這類工具能夠與主流的工程化工具一起使用,如 Webpack,提供對應的 loader 如 sass-loader,然后就可以在 React/Vue 項目中建 `.scss` 文件,寫 sass 語法,并導入到 React 組件中生效。

          比如我寫一個組件在響應式各個斷點下的展示情況的 sass 代碼:

          ```

          .component {

          width: 300px;

          @media (min-width: 768px) {

          width: 600px;

          @media (min-resolution: 192dpi) {

          background-image: url(/img/retina2x.png);

          }

          }

          @media (min-width: 1280px) {

          width: 800px;

          }

          }

          ```

          或導入一些用于標準化瀏覽器差異的代碼:

          ```

          @import "normalize.css";

          // component 相關的其他代碼

          ```

          ### 不足

          這類方案的一個主要問題就是,只是對 CSS 本身進行了增強,但是在幫助開發者如何寫更好的 CSS、更高效、可維護的 CSS 方面并沒有提供任何建議。

          - 你依然需要自己定義 CSS 類、id,并且思考如何去用這些類、id 進行組合去描述 HTML 的樣式

          - 你依然可能會寫很多冗余的 Less/Sass 代碼,然后造成項目的負擔,在可維護性方面也有巨大問題

          ### 優化

          - 可以引入 CSS 設計規范:BEM 規范,來輔助用戶在整個網頁的 HTML 骨架以及對應的類上進行設計

          - 可以引入 CSS Modules,將 CSS 文件進行 “作用域” 限制,確保在之后維護時,修改一個內容不會引起全局中其他樣式的效果

          #### BEM 規范

          B (Block)、E(Element)、M(Modifier),具體就是通過塊、元素、行為來定義所有的可視化功能。

          拿設計一個 Button 為例:

          ```

          /* Block */

          .btn {}

          /* 依賴于 Block 的 Element */

          .btn__price {}

          /* 修改 Block 風格的 Modifier */

          .btn--orange {}

          .btn--big {}

          ```

          遵循上述規范的一個真實的 Button:

          ```

          <a class="btn btn--big btn--orange" href="#">

          <span class="btn__price"></span>

          <span class="btn__text">BIG BUTTON</span>

          </a>

          ```

          可以獲得如下的效果:

          #### CSS Modules

          CSS Modules 主要為 CSS 添加局部作用域和模塊依賴,使得 CSS 也能具有組件化。

          一個例子如下:

          ```

          import React from 'react';

          import style from './App.css';

          export default () => {

          return (

          <h1 className={style.title}>

          Hello World

          </h1>

          );

          };

          ```

          ```

          .title {

          composes: className;

          color: red;

          }

          ```

          上述經過編譯會變成如下 hash 字符串:

          ```

          <h1 class="_3zyde4l1yATCOkgn-DBWEL">

          Hello World

          </h1>

          ```

          ```

          ._3zyde4l1yATCOkgn-DBWEL {

          color: red;

          }

          ```

          CSS Modules 可以與普通 CSS、Less、Sass 等結合使用。

          ## 純 JS 側方案

          ### 介紹與優點

          > 維護狀態:一般

          > Star 數:35.2K

          > 支持框架:React ,通過社區支持 Vue 等框架

          > 項目地址:https://github.com/styled-components/styled-components

          使用 JS 的模板字符串函數,在 JS 里面寫 CSS 代碼,這帶來了兩個認知的改變:

          - 不是在根據 HTML,然后去寫 CSS,而是站在組件設計的角度,為組件寫 CSS,然后應用組件的組合思想搭建大應用

          - 自動提供類似 CSS Modules 的體驗,不用擔心樣式的全局污染問題

          同時帶來了很多 JS 側才有的各種功能特性,可以讓開發者用開發 JS 的方式開發 CSS,如編輯器自動補全、Lint、編譯壓縮等。

          比如我寫一個按鈕:

          ```

          const Button = styled.button`

          /* Adapt the colors based on primary prop */

          background: ${props => props.primary ? "palevioletred" : "white"};

          color: ${props => props.primary ? "white" : "palevioletred"};

          font-size: 1em;

          margin: 1em;

          padding: 0.25em 1em;

          border: 2px solid palevioletred;

          border-radius: 3px;

          `;

          render(

          <div>

          <Button>Normal</Button>

          <Button primary>Primary</Button>

          </div>

          );

          ```

          可以獲得如下效果:

          還可以擴展樣式:

          ```

          // The Button from the last section without the interpolations

          const Button = styled.button`

          color: palevioletred;

          font-size: 1em;

          margin: 1em;

          padding: 0.25em 1em;

          border: 2px solid palevioletred;

          border-radius: 3px;

          `;

          // A new component based on Button, but with some override styles

          const TomatoButton = styled(Button)`

          color: tomato;

          border-color: tomato;

          `;

          render(

          <div>

          <Button>Normal Button</Button>

          <TomatoButton>Tomato Button</TomatoButton>

          </div>

          );

          ```

          可以獲得如下效果:

          ### 不足

          雖然這類方案提供了在 JS 中寫 CSS,充分利用 JS 的插值、組合等特性,然后應用 React 組件等組合思想,將組件與 CSS 進行細粒度綁定,讓 CSS 跟隨著組件一同進行組件化開發,同時提供和組件類似的模塊化特性,相比 Less/Sass 這一套,可以復用 JS 社區的最佳實踐等。

          但是它仍然有一些不足:

          - 仍然是是對 CSS 增強,提供非常大的靈活性,開發者仍然需要考慮如何去組織自己的 CSS

          - 沒有給出一套 “有觀點” 的最佳實踐做法

          - 在上層也缺乏基于 styled-components 進行復用的物料庫可進行參考設計和使用,導致在初始化使用時開發速度較低

          - 在 JS 中寫 CSS,勢必帶來一些本屬于 JS 的限制,如 TS 下,需要對 Styled 的組件進行類型注釋

          - 官方維護的內容只兼容 React 框架,Vue 和其他框架都由社區提供支持

          整體來說不太符合團隊協作使用,需要人為總結最佳實踐和規范等。

          ### 優化

          - 尋求一套寫 CSS 的最佳實踐和團隊協作規范

          - 能夠擁有大量的物料庫或輔助類等,提高開發效率,快速完成應用開發

          ## 偏向 HTML 側方案

          ### 介紹與優點

          > 維護狀態:積極

          > Star 數:48.9K

          > 支持框架:React、Vue、Svelte 等主流框架

          > 項目地址:https://github.com/tailwindlabs/tailwindcss

          典型的是 TailwindCSS,一個輔助類優先的 CSS 框架,提供如 `flex` 、`pt-4` 、`text-center` 、`rotate-90` 這樣實用的類名,然后基于這些底層的輔助類向上組合構建任何網站,而且只需要專注于為 HTML 設置類名即可。

          一個比較形象的例子可以參考如下代碼:

          ```

          <button class="btn btn--secondary">Decline</button>

          <button class="btn btn--primary">Accept</button>

          ```

          上述代碼應用 BEM 風格的類名設計,然后設計兩個按鈕,而這兩個類名類似主流組件庫里面的 Button 的不同狀態的設計,而這兩個類又是由更加基礎的 TailwindCSS 輔助類組成:

          ```

          .btn {

          @apply text-base font-medium rounded-lg p-3;

          }

          .btn--primary {

          @apply bg-rose-500 text-white;

          }

          .btn--secondary {

          @apply bg-gray-100 text-black;

          }

          ```

          上面的輔助類包含以下幾類:

          - 設置文本相關: `text-base` 、`font-medium` 、`text-white` 、`text-black`

          - 設置背景相關的:`bg-rose-500` 、`bg-gray-100`

          - 設置間距相關的:`p-3`

          - 設置邊角相關的:`rounded-lg`

          通過 Tailwind 提供的 `@apply` 方法來對這些輔助類進行組合構建更上層的樣式類。

          上述的最終效果展示如下:

          可以看到 TailwindCSS 將我們開發網站的過程抽象成為使用 Figma 等設計軟件設計界面的過程,同時提供了一套用于設計的規范,相當于內置最佳實踐,如顏色、陰影、字體相關的內容,一個很形象的圖片可以說明這一點:

          TailwindCSS 為我們規劃了一個元素可以設置的屬性,并且為每個屬性給定了一組可以設置的值,這些屬性+屬性值組合成一個有機的設計系統,非常便于團隊協作與共識,讓我們開發網站就像做設計一樣簡單、快速,但是整體風格又能保持一致。

          TailwindCSS 同時也能與主流組件庫如 React、Vue、Svelte 結合,融入基于組件的 CSS 設計思想,但又只需要修改 HTML 上的類名,如我們設計一個食譜組件:

          ```

          // Recipes.js

          import Nav from './Nav.js'

          import NavItem from './NavItem.js'

          import List from './List.js'

          import ListItem from './ListItem.js'

          export default function Recipes({ recipes }) {

          return (

          <div className="divide-y divide-gray-100">

          <Nav>

          <NavItem href="/featured" isActive>Featured</NavItem>

          <NavItem href="/popular">Popular</NavItem>

          <NavItem href="/recent">Recent</NavItem>

          </Nav>

          <List>

          {recipes.map((recipe) => (

          <ListItem key={recipe.id} recipe={recipe} />

          ))}

          </List>

          </div>

          )

          }

          // Nav.js

          export default function Nav({ children }) {

          return (

          <nav className="p-4">

          <ul className="flex space-x-2">

          {children}

          </ul>

          </nav>

          )

          }

          // NavItem.js

          export default function NavItem({ href, isActive, children }) {

          return (

          <li>

          <a

          href={href}

          className={`block px-4 py-2 rounded-md ${isActive ? 'bg-amber-100 text-amber-700' : ''}`}

          >

          {children}

          </a>

          </li>

          )

          }

          // List.js

          export default function List({ children }) {

          return (

          <ul className="divide-y divide-gray-100">

          {children}

          </ul>

          )

          }

          //ListItem.js

          export default function ListItem({ recipe }) {

          return (

          <article className="p-4 flex space-x-4">

          <img src={recipe.image} alt="" className="flex-none w-18 h-18 rounded-lg object-cover bg-gray-100" width="144" height="144" />

          <div className="min-w-0 relative flex-auto sm:pr-20 lg:pr-0 xl:pr-20">

          <h2 className="text-lg font-semibold text-black mb-0.5">

          {recipe.title}

          </h2>

          <dl className="flex flex-wrap text-sm font-medium whitespace-pre">

          <div>

          <dt className="sr-only">Time</dt>

          <dd>

          <abbr title={`${recipe.time} minutes`}>{recipe.time}m</abbr>

          </dd>

          </div>

          <div>

          <dt className="sr-only">Difficulty</dt>

          <dd> · {recipe.difficulty}</dd>

          </div>

          <div>

          <dt className="sr-only">Servings</dt>

          <dd> · {recipe.servings} servings</dd>

          </div>

          <div className="flex-none w-full mt-0.5 font-normal">

          <dt className="inline">By</dt>{' '}

          <dd className="inline text-black">{recipe.author}</dd>

          </div>

          <div class="absolute top-0 right-0 rounded-full bg-amber-50 text-amber-900 px-2 py-0.5 hidden sm:flex lg:hidden xl:flex items-center space-x-1">

          <dt className="text-amber-500">

          <span className="sr-only">Rating</span>

          <svg width="16" height="20" fill="currentColor">

          <path d="M7.05 3.691c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.372 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.539 1.118l-2.8-2.034a1 1 0 00-1.176 0l-2.8 2.034c-.783.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.363-1.118L.98 9.483c-.784-.57-.381-1.81.587-1.81H5.03a1 1 0 00.95-.69L7.05 3.69z" />

          </svg>

          </dt>

          <dd>{recipe.rating}</dd>

          </div>

          </dl>

          </div>

          </article>

          )

          }

          ```

          上述食譜的效果如下:

          可以看到我們無需寫一行 CSS,而是在 HTML 里面應用各種輔助類,結合 React 的組件化設計,既可以輕松完成一個非常現代化且好看的食譜組件。

          除了上面的特性,TailwindCSS 在響應式、新特性支持、Dark Mode、自定義配置、自定義新的輔助類、IDE 方面也提供非常優秀的支持,除此之外還有基于 TailwindCSS 構建的物料庫 Tailwind UI ,提供各種各樣成熟、好看、可用于生產的物料庫:

          ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1cb983da6f71470b91ac764d14907998~tplv-k3u1fbpfcp-zoom-1.image)

          因為需要自定的 CSS 不多,而需要自定義的 CSS 可以定義為可復用的輔助類,所以在可維護性方面也是極好的。

          ### 不足

          - 因為要引入一個額外的運行時,TailwindCSS 輔助類到 CSS 的編譯過程,而隨著組件越來越多,需要編譯的工作量也會變大,所以速度會有影響

          - 過于底層,相當于給了用于設計的最基礎的指標,但是如果我們想要快速設計網站,那么可能還需要一致的、更加上層的組件庫

          - 相當于引入了一套框架,具有一定的學習成本和使用成本

          ### 優化

          - Tailwind 2.0 支持 [JIT](https://blog.tailwindcss.com/tailwindcss-2-1 "JIT"),可以大大提升編譯速度,可以考慮引入

          - 基于 TailwindCSS,設計一套符合自身風格的上層組件庫、物料庫,便于更加快速開發

          - 提前探索、學習和總結一套教程與開發最佳實踐

          - 探索 styled-components 等結合 TailwindCSS 的開發方式

          ## 參考鏈接

          - [CSS 工程化發展歷程](https://bytedance.feishu.cn/docs/doccnTRF0OZtJMgKuo3y0hIDMbc# "CSS 工程化發展歷程")


          / 感謝支持/

          以上便是本次分享的全部內容,希望對你有所幫助^_^

          喜歡的話別忘了 分享、點贊、收藏 三連哦~

          歡迎關注公眾號 程序員巴士,來自字節、蝦皮、招銀的三端兄弟,分享編程經驗、技術干貨與職業規劃,助你少走彎路進大廠。


          主站蜘蛛池模板: 国模精品一区二区三区| 国产一区二区三区视频在线观看| 在线欧美精品一区二区三区 | 国产高清在线精品一区小说| 亚洲一区在线免费观看| 中文字幕VA一区二区三区| 亚洲AV无码一区二区三区电影| 无码囯产精品一区二区免费 | 色婷婷香蕉在线一区二区| 激情内射日本一区二区三区| 国产精品香蕉一区二区三区| 国产熟女一区二区三区四区五区| 国产一区二区三区高清在线观看| 亚洲国产综合精品中文第一区| 免费无码一区二区三区蜜桃| 男插女高潮一区二区| 国产成人精品一区二区三区无码| 麻豆高清免费国产一区| 亚洲国产综合无码一区| 久久精品国产一区二区三区不卡| 韩国精品福利一区二区三区| 亚洲熟妇无码一区二区三区| 少妇精品无码一区二区三区| 一区二区三区国产| 亚洲线精品一区二区三区影音先锋 | 中文字幕AV一区二区三区人妻少妇| 免费av一区二区三区| 中文字幕在线无码一区| 日韩精品无码视频一区二区蜜桃| 一区二区三区在线|日本| 国产在线精品一区二区| 春暖花开亚洲性无区一区二区 | 精品亚洲A∨无码一区二区三区| 亚洲韩国精品无码一区二区三区| 国产成人无码一区二区在线播放| 国产亚洲一区二区精品| 亚欧在线精品免费观看一区| 亚洲欧洲专线一区| 日韩有码一区二区| 久草新视频一区二区三区| 亚洲国产视频一区|