手機不能開 daisyUI 的 modal 的原因
/ 閱讀時間 4 分鐘
目次
最近寫程式的時候,用了 daisyUI 的 modal,在手機(iPhone 7)用開發伺服器開啟網頁的時候卻發現 modal 開不了。到底是為什麼呢?
我原本猜測是因為手機瀏覽器太舊了,不支援 daisyUI 用的 CSS 語法,不過奇怪的是 daisyUI 官網的 modal 範例卻是正常的。如果是同一套程式碼應該不會有這樣的差別?
既然唯獨只有在手機用開發伺服器開啟網頁開不了 modal,就只能用開發人員工具看看了。經過調查發現 modal 出現與否是由 visibility
控制的,平常 modal 沒開的時候是 visibility: hidden
的,開了之後 visibility
會變成 visible
。手機瀏覽器在開 modal 之後,visibility
還是 hidden
的。
查了 Can I use 跟 daisyUI 的原始碼後,發現的確是瀏覽器不支援 daisyUI 用的 CSS 語法。
下面是 modal 元件的原始碼:
.modal { /* ... */ &.modal-open, &[open], &:target { @apply pointer-events-auto visible opacity-100 starting:invisible starting:opacity-0; /* ... */ }}
這種 CSS Nesting 要在 Safari 16.5 才部分支援,在 Safari 17.2 才完全支援。我的 iPhone 7 最高版本只到 15.8,當然不會支援。
不過這樣還是無法說明為什麼手機瀏覽器可以正常開啟 daisyUI 官網範例的 modal,難道它們的 CSS 是不同的嗎?調查後發現還真的是不同的,差別在 @tailwindcss/vite
的 serve mode 跟 full build 的不同。
開發伺服器上這部分的程式碼長這樣:
.modal { /* ... */ &.modal-open, &[open], &:target { background-color: oklch(0% 0 0/ 0.4); transition: transform 0.3s ease-out, background-color 0.3s ease-out, opacity 0.1s ease-out; pointer-events: auto; visibility: visible; opacity: 100%; /* ... */ }}
建置後的程式碼長這樣:
.modal.modal-open,.modal[open],.modal:target { pointer-events: auto; visibility: visible; opacity: 1; background-color: #0006; transition: transform 0.3s ease-out, background-color 0.3s ease-out, opacity 0.1s ease-out;}
建置時做的 full build 跟開發伺服器的 serve mode 相比,有多使用 Lightning CSS 對 CSS 做最佳化,做最佳化時也會轉換成相容支援瀏覽器版本的程式碼。Tailwind CSS v4 最低支援 Safari 16.4,正好沒有支援 CSS Nesting,所以有用到 CSS Nesting 的地方被代換掉了。
所以 daisyUI 官網的範例才會可以在手機瀏覽器正常運作,而開發伺服器上的不行。
如果要讓開發伺服器也對 CSS 做最佳化,只要改一下 @tailwindcss/vite
就好:
import { defineConfig } from "vite";import tailwindcss from "@tailwindcss/vite";
let tailwindcssPlugin = tailwindcss();tailwindcssPlugin[1] = { ...tailwindcssPlugin[2], apply: "serve" };
export default defineConfig({ plugins: [tailwindcssPlugin]});