--- title: 渲染順序 | Tailwind CSS tags: tailwind --- 渲染順序 == 如果你 tailwind 已經寫一段時間了,相信你有時候也會想把因為 tailwind 語法而變的很長的 class 變短吧,那這時候就要用到的是 tailwind 裡的 **`` `@apply` ``** 指令。 ### 整理前 ```htmlembedded= <button class="rounded-xl bg-gray-400 p-3 text-white"> 立即前往 </button> ``` ### 整理後 ```htmlembedded= // html <button class="myBtn"> 立即前往 </button> ``` ```css= // css .myBtn { @apply rounded-xl bg-gray-400 p-3 text-white; } ``` </br> :::warning :warning: **注意** 如果是透過 CDN 方式使用 tailwind 的人,下面的內容你可能看不懂,也用不到。但如果有朝一日你會完整安裝 tailwind 的功能,那建議你還是可以稍微看一下。 ::: </br> 設計的墊腳石 -- 而整理起來的好處,不但是class內變的簡短,連帶的也可以達到==程式碼的複用==。比如說我頁面上的所有按鈕都要套用現在設計出來的 `` `myBtn` `` 這個樣式,我就可以這樣做: ```htmlembedded= <button class="myBtn"> 取消 </button> <button class="myBtn"> 立即前往 </button> ``` 那我是不是也可以基於已有的 `` `myBtn` `` 樣式,再加上新的 tailwind 語句,就可以讓兩個按鈕同樣版型設計,但顏色不同? 絕對是可以的! ```htmlembedded= <button class="myBtn"> 取消 </button> <button class="myBtn bg-green-500"> 立即前往 </button> ``` 滿心歡喜的覺得設計的很棒,但執行之後卻發現,==顏色沒有蓋掉==,還是原本的顏色... 是不是突然覺得很失望? 想說 tailwind 這麼好用的東西居然敗在這裡了嗎!? 那接下來正是要看看本篇的重點囉:==Tailwind 的渲染順序==。 </br> 渲染順序 -- 廢話不多說,直接上表: <table> <tr> <th colspan="8" style="text-align:center"> 低 ←← 優先度 →→ 高 </th> </tr> <tr> <th colspan="2" style="text-align:center"> 寫在 Tailwind Import 前 </th> <th colspan="6" style="text-align:center"> 寫在 Tailwind Import 後 </th> </tr> <tr> <td>原生CSS</td> <td>tailwind</br>@apply</td> <td>Components</td> <td>class</td> <td>Utilities</td> <td>原生CSS</td> <td>inline style</td> <td>!important</td> </tr> <tr> <td><code>內部順序:</code></br>css檔內順序</td> <td><code>內部順序:</code></br>css檔內順序</td> <td><code>內部順序:</code></br>Components</br>區內順序</td> <td><code>內部順序:</code></br>只會渲染class內第一個碰到的,後面同樣式的直接無效</td> <td><code>內部順序:</code></br>Utilities</br>區內順序</td> <td><code>內部順序:</code></br>css檔內順序</td> <td><code>內部順序:</code></br>行內順序</td> <td><code>內部順序:</code></br>行內順序</td> </tr> </table> </br> 如果不看表的話,純 tailwind 渲染順序大約順序是這樣。 :::info **`Tailwind Import 前` → `Components` → `class` → `Utilities`** ::: 我們可以很清楚的看到,這渲染順序就是官方所一直強調的 ==Utilities First==,那如果加入原生 CSS 的話,完整的順序應該是這樣: :::info **`原生CSS(Import前)` → `Tailwind Import 前` → `Components` → `class` → `Utilities`</br> → `原生CSS(Import後)` → `inline style` → `!important`** ::: </br> 這邊稍微來對表中的一些內容解釋一下好了。 </br> ### Import前的原生CSS 內部順序的 `CSS檔順序` 是指依照==CSS檔內出現的順序==,而非使用順序。 ```css= .a { background-color: white; } .b { background-color: black; } @tailwind base; @tailwind components; @tailwind utilities; ``` 這個情況下,==b 的優先度比 a 高==,如果同時使用 a、b,==b 的樣式會無條件把 a 蓋掉==。 </br> ### Import前的@apply 內部順序的 `CSS檔順序` 是指依照==CSS檔內出現的順序==,而非使用順序。 ```css= .a { @apply bg-white; } .b { @apply bg-black; } @tailwind base; @tailwind components; @tailwind utilities; ``` 這個情況下,==b 的優先度比 a 高==,如果同時使用 a、b,==**b** 的樣式會無條件把 **a** 蓋掉==。 </br> ### Components 內部順序的 `Components區內順序` 是指依照==CSS檔中 Components 區內出現的順序==,而非使用順序。 ```css= @tailwind base; @tailwind components; @tailwind utilities; @layer components { .a { @apply bg-white; } .b { @apply bg-black; } } ``` 這個情況下,==b 的優先度比 a 高==,如果同時使用 a、b,==**b** 的樣式會無條件把 **a** 蓋掉==。 </br> ### class 內部順序的 `只會渲染class內第一個碰到的,後面同樣式的直接無效 ` 是指==class 名稱中同樣用途的樣式,只會渲染第一個==,而非使用順序。這個可能比較難懂,直接看舉例: ```htmlembedded== <button class="bg-green-500 bg-blue-500 text-white"> 立即前往 </button> ``` 這個情況下,==只會渲染 **bg-green-500** 和 **text-white**==,和 `bg-green-500` 相同用途的 **`bg-blue-500`** 並 **==不會被渲染==**。 (同樣用途的樣式,只會渲染第一個) </br> ### Utilities 內部順序的 `Utilities區內順序` 是指依照==CSS檔中 Utilities 區內出現的順序==,而非使用順序。 ```css= @tailwind base; @tailwind components; @tailwind utilities; @layer utilities { .a { @apply bg-white; } .b { @apply bg-black; } } ``` 這個情況下,==b 的優先度比 a 高==,如果同時使用 a、b,==**b** 的樣式會無條件把 **a** 蓋掉==。 </br> ### Import後的原生CSS 內部順序的 `CSS檔順序` 是指依照==CSS檔內出現的順序==,而非使用順序。 ```css= @tailwind base; @tailwind components; @tailwind utilities; .a { background-color: white; } .b { background-color: black; } ``` 這個情況下,==b 的優先度比 a 高==,如果同時使用 a、b,==b 的樣式會無條件把 a 蓋掉==。 </br> ### Inline Style 內部順序的 `行內順序` 是指依照==style語句行內最後出現的順序==。 ```htmlembedded== <button class="bg-green-500" style="color:red; color:blue;"> 立即前往 </button> ``` 這個情況下,==color:blue 的優先度比 color:red 高==,如果同時使用 `color:red`、`color:blue`,==**color:blue** 的樣式會無條件把 **color:red** 蓋掉==。 </br> ### !important 內部順序的 `行內順序` 是指依照==style語句行內 **!important** 最後出現的順序==。 ```htmlembedded== <button class="bg-green-500" style="color:red !important; color:blue; color:yellow !important;"> 立即前往 </button> ``` 這個情況下,==優先度是 **color:yellow !important** > **color:red !important** > **color:blue**==,如果同時使用 `color:red !important`、`color:blue` 和 `color:yellow !important`,==**color:yellow !important** 的樣式會無條件把 **color:red !important** 和 **color:blue** 蓋掉==。 </br> 同場加映:Tailwind 的 !important -- 既然提到 `!important`,常見的寫法就是加在 css 檔或是加在 inline style ~~,尤其時你在用 Bootstrap 的時候~~ 。但其實 Tailwind 裡面也可以加上 `!important`,只是我==沒有很建議==,不過你如果要加,這邊要稍微注意一下: **![](https://huibizhang.com/Contributions/TailwindCSS/images/good.svg =30x30) 加在 css 檔內的 @apply 指令後面是有效的** ```css= .btn { @apply bg-green-500 !important; } ``` **![](https://huibizhang.com/Contributions/TailwindCSS/images/bad.svg =30x30) 想要像其他 tailwind 語法一樣加在 class 名稱中是無效的** ```htmlembedded= <button class="btn bg-green-500 !important"> 立即前往 </button> ``` </br> 測試結果 -- [這邊][渲染測試]有完整的==渲染順序==測試結果,有興趣的人可以去看一下。 </br> -- > [name=搋兔 Tryto] 如果有寫錯的部分,麻煩各位幫我標起來然後留言,我再修正~ 謝謝 ###### tags: `tailwind` <!-- === 連結 ============== --> [渲染測試]: https://play.tailwindcss.com/spQBiJ74KJ <!-- === CSS設定 ============== --> <style> a { color:#0072E3; text-decoration: none; transition:color 0.75s; } a:hover { color:#84C1FF; text-decoration: none; transition:color 0.75s; } .markdown-body mark { border-radius: 5px; color:#c7254e; background-color:#f9f2f4; } </style> <!-- === CSS:程式碼深色主題 ============== --> <style> .markdown-body pre { background-color: rgb(31, 41, 55); border: 1px solid #555 !important; color: #CCCCCC; border-radius:12px; } .markdown-body pre .hljs-tag { color: #BAE5FD; } .markdown-body pre .hljs-keyword { color: #20D3EE; } .markdown-body pre .hljs-string { color:#BEF263; } .markdown-body pre .hljs-comment { color:#9CA3B0; } .markdown-body pre .hljs-attr { color:#20D3EE; } .markdown-body pre .hljs-name { color:#E87BF9; } .markdown-body pre .hljs-built_in { color:#F76E79; } </style>