skip to content
鰭狀漏斗

手機不能開 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 就好:

vite.config.js
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
let tailwindcssPlugin = tailwindcss();
tailwindcssPlugin[1] = { ...tailwindcssPlugin[2], apply: "serve" };
export default defineConfig({
plugins: [tailwindcssPlugin]
});

參考資料