TailwindCSS 高級使用技巧

作者:曉平

https://zhengxiaoping.xyz/css/TailwindCSS%E9%AB%98%E7%BA%A7%E6%8A%80%E5%B7%A7.html

前言

如果你剛剛熟悉 TailwindCSS,不妨先看看這篇文章:TailwindCSS 的使用,看這一篇就夠了!

以下內容,將會假設你已經使用過 TailwindCSS 一段時間了,比較熟悉其使用手感。本篇內容將會着重於講解比較不常用的功能點,如果你是深度使用者,可能需要此篇文章。

提取配置

我們想到的第一個問題就是: 複用。你總會碰到需要抽象的情況,例如需要在多個項目中共享一份配置。儘管可以通過Ctrl C, Ctrr V一分鐘搞定,這種方案速度最快,後患卻也最大(散落在各處的副本,最後都不知道該以哪個爲基準)。

幸好 TailwindCSS 爲我們提供了preset的特性,你只需要幾個簡單的步驟就可以將配置抽離出去:

1. 新建 tailwind.preset.js

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      theme: {
        extend: {
          colors: {
            primary: 'orange'
          }
        },
      },
    }

preset文件的配置方法與tailwind.config.js一樣,TailwindCSS 會根據自己的合併規則去合併presettailwind.config.js中的配置。

合併規則可參考:https://tailwindcss.com/docs/presets#merging-logic-in-depth

2. 配置 tailwind.config.js

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: [
        './src/**/*.{vue,js,ts,jsx,tsx}'
      ],
      theme: {
        extend: {},
      },
      presets: [ 
        require('./tailwind.preset.js')
      ],
    }

當然,你也可以考慮將tailwind.preset.js發佈爲一個 npm 庫:

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: [
        './src/**/*.{vue,js,ts,jsx,tsx}'
      ],
      theme: {
        extend: {},
      },
      presets: [ 
        require('tailwind-preset') // 庫名爲tailwind-preset,配置package.json中main字段爲配置文件位置作爲庫的默認導出
      ],
    }

你可能已經注意到,presets配置是一個數組,是的,TailwindCSS 允許配置多個預設,然後從上至下進行合併,如果多個 preset 存在同樣的配置,則後者會覆蓋前者。

TIP

presets 可配置多個提供了更細粒度化拆分配置的可能性,你可以將一個 Tailwind 配置,按照不同的模塊進行拆分,使用時,根據需要組合使用。

這種拆分形式相當於在配置層面進行原子化,看來 TailwindCSS 無處不散發着 原子化 的風味,Respect!

使用插件提高開發效率

CSS 的能力相比 JS 要弱得多,所以,針對 CSS 的插件其實主要是對一些常用樣式進行封裝,形成所謂 CSS 組件,比如下方的代碼:

    .button {
      display: inline-block;
      padding: 5px 12px;
      text-align: center;
      background-color: orange;
      color: #fff;
    }

上述代碼實現了一個按鈕的 CSS 組件,在 TailwindCSS 中,你可以認爲它是一個名爲button的插件。當開發人員安裝此插件,就可以通過簡單添加一個 class 的方式實現快速編碼。

以下簡單介紹兩款比較常用的官方插件的安裝及使用方法:

安裝插件

    pnpm i -D @tailwindcss/line-clamp @tailwindcss/aspect-ratio
    # yarn add -D @tailwindcss/line-clamp @tailwindcss/aspect-ratio
    # npm i -D @tailwindcss/line-clamp @tailwindcss/aspect-ratio

註冊插件

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: [
        './src/**/*.{vue,js,ts,jsx,tsx}'
      ],
      plugins: [ 
        require('@tailwindcss/line-clamp'),
        require('@tailwindcss/aspect-ratio'),
      ],
    }

line-clamp 插件使用方法

    <template>
      <div>
        <span v-for="x in 100" :key="x">我是一段文本</span>
      </div>
    </template>

我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本我是一段文本

aspect-ratio 插件使用方法

生成一個常用視頻(16:9)的比例盒子:

    <div class="w-[400px] aspect-video bg-blue-300">
      <video
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"
        class="w-full h-full"
        controls />
    </div>

又愛又恨的 Preflight 特性

preflight 是 TailwindCSS 內置的一套全局樣式,其作用類似於 normalize.css / modern-normalize (TailwindCSS 建立在 modern-normalize 之上)。

preflight 主要修改的全局樣式情況:

禁用此特性

preflight 默認是跟隨 @tailwind base 被注入到你的應用中的,如果不想使用這個特性,可以在配置中新增一行:

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      corePlugins: {
        preflight: false
      },
      // ...
    }

個人看法

我個人不喜歡使用這個特性,一般會關掉,理由有三:

  1. 一般我會在項目中引用 normalize.css 或 modern-normalize 庫,如果使用 preflight,其實有部分工作是重複的;

  2. preflight 主要是對 html 的一些原生標籤進行樣式重置,而像 h1/h2/h3/h4/h5/h6/ol/ul/p 等標籤,我喜歡使用 div 標籤代替,雖然會降低語義化,但是效率提升了;

  3. 我不喜歡 img 標籤被設置爲塊級盒子這個特性,因爲這很反直覺,給開發人員帶來了額外的學習成本。

邊框默認樣式的坑

如果你禁用了這個特性,在設置邊框時需要注意一下寫法的不同。TailwindCSS 官方推薦的邊框寫法:

    <div class="border-t border-gray-200" />

結合 preflight 的全局樣式:

    * {
      border-width: 0;
      border-style: solid;
    }

最終,合成的樣式將會是:

    div {
      border-width: 0;
      border-top-width: 1px;
      border-style: solid;
      border-color: #e5e7eb;
    }

但是,如果禁用掉 preflight,則最終合成的樣式將會是:

    div {
      border-top: 1px;
      border-color: #e5e7eb;
    }

此時,邊框將會不存在,因爲沒有設置邊框的風格。

因此,你需要爲每個設置邊框的場景都設置邊框樣式

    <div class="border-t border-solid border-gray-200" />

這種寫法的問題就更大了,除了上邊框是灰色外,其他邊也會出現邊框,因爲 html 中所有元素的默認邊框寬度爲 1px。爲了去掉其他邊的邊框,你還需要手動處理:

    <div class="border-t border-solid border-gray-200 border-l-0 border-r-0 border-b-0" />

這???也太痛苦了,所以,個人推薦手動加入一些全局樣式:

    *, *:before, *:after {
      border-width: 0;
      border-style: solid;
    }

這樣,就跟開啓了 preflight 特性的效果保持一致了。

TIP

反向操作,你可以在啓用 preflight 的前提下,將 img 等標籤設置爲行內盒子。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/mvnLzsLWhKY-YlL9hzrAlA