每個做過網頁的人大概都經歷過 Bootstrap 時期。第一次把它引進來,按鈕突然變漂亮了、表格突然有間距了、手機上看突然不會爆版了,那種感覺像是第一次穿上合身的衣服。然後過了一陣子你會發現,所有人的網站都穿著同一件衣服。
Bootstrap 是 MIT 授權、用了十幾年的 CSS 框架,Google Fonts 提供上千種免費字型,兩者都是把一個網站快速做得像樣的捷徑。我的網站一個都沒用:沒有第三方 JavaScript、沒有 WebAssembly、沒有內嵌字型檔、沒有 CDN 引用,只有一份自己手寫的 CSS。這不是清高,也不是為了與眾不同,是幾個具體的代價算下來的結果。
內容安全政策會變寬
先講最技術的那個。嚴格的 CSP 長這樣:script-src 'self'、style-src 'self'、font-src 'self'、img-src 'self'。翻成人話就是「這個網頁只信任自己網域的東西」。每引進一個第三方來源,對應的指令就要多列一個網域;用 CDN 上的 Bootstrap,script-src 和 style-src 都要開;用 Google Fonts,style-src 和 font-src 都要開。
政策一寬,它能擋的東西就少。CSP 的價值在於它是一張白名單,白名單上的東西越少,漏網之魚就越少。自己的 CSS 放在自己的網域下,這幾行可以維持在最緊的狀態。你可以把它想成家裡的鑰匙,給越多人一把,就越難說清楚誰進來過。
授權聲明的義務
MIT、BSD、Apache-2.0 的姓名標示義務綁在「散布軟體」上。網站把第三方 JavaScript 送到訪客的瀏覽器,就是散布,理論上要隨附該程式的授權與版權聲明。這件事很多人不知道,因為大家都這樣做而且沒有人被告過,但「沒有人被告過」跟「合規」是兩件事。
如果瀏覽器端沒有任何第三方程式碼、後端套件也不交付給使用者,這個義務就不存在。少一個檔案要維護,也少一個將來被問「你有沒有附聲明」的機會。我對「將來被問」這種事有點過敏,寧可現在多做一點。
訪客的隱私
從 Google 的伺服器載入字型,訪客的 IP 就送到了 Google。你的訪客可能根本不知道自己來看一篇食譜,順便跟 Google 打了聲招呼。2022 年 1 月德國慕尼黑地方法院判過一件案子,認定動態嵌入 Google Fonts 在未經同意的情況下把 IP 傳給 Google 違反 GDPR。
要用 Google Fonts,比較穩的做法是下載字型檔放在自己的網域下自架,那又回到「內嵌字型檔的授權要登錄」這件事。系統字型堆疊 system-ui, -apple-system, "Segoe UI", sans-serif 沒有這些問題,而且載入速度是零,訪客的裝置上本來就有。它不會很有個性,但它永遠不會讓頁面在字型載入前閃一下。
範本的展示素材不在授權裡
這件事是我差點踩到的。我參考過一個免費的 HTML 範本來決定版面。範本本身可商用、可修改,很慷慨。但展示頁上的照片和插畫不在範本的授權內,它們是另外的素材,範本作者也只是拿來示範。你下載範本、留著那些圖、上線,就用了不知道誰的照片。
只借版面語言、用自己的 token 和純 CSS 重做,不複製它的 HTML、CSS、JavaScript 和圖片,就沒有任何第三方聲明的義務,頁尾也不用放範本署名。「借版面語言」的意思是:我看它把標題放哪、卡片怎麼排、留白多大,然後自己寫。像是看了一件衣服的剪裁,回家自己車一件,布料是自己的。
純 CSS 能做的比想像多
大家對純 CSS 的印象還停留在只能改顏色和字體。其實星空背景可以用十幾個 radial-gradient 的光點疊出來,行星弧和軌道環是幾個帶邊框的圓角元素,全部在 style-src 'self' 和 img-src 'self' 底下零成本、零授權義務。頁內錨點和原生的 <details> 在沒有 JavaScript 時照樣可用,鍵盤和螢幕閱讀器的行為是標準的,你不用自己重新發明「按 Enter 展開」這件事。
結構化資料用 microdata 屬性寫在標籤上,不用內嵌的 JSON-LD script,CSP 就不必為它開洞。這個做法比較囉嗦,每個屬性都要寫在對應的標籤上,但寫完之後它就在那裡,不會因為某個 script 被擋而消失。
小劇場:這樣不會很醜嗎
「不用框架、不用字型,你的網站看起來不會很陽春嗎?」
「陽春跟醜是兩件事。系統字型很陽春,但它清楚、快、每個裝置上都對。」
「可是大家都用漂亮的字型。」
「大家也都穿同一個牌子的衣服。我不是說那樣不好,我是說那樣不是唯一的選項。」
「那你花了多少時間寫那份 CSS?」
「比引進 Bootstrap 多很多。但那份 CSS 裡每一行我都知道在做什麼,Bootstrap 的幾千行我只用過其中一百行,剩下的都是我不知道的東西住在我的網站裡。」
它們仍然適合的場合
內部工具、原型、團隊裡有很多人要同時產出頁面的專案,Bootstrap 省下的時間是真的,而且很多。字型對品牌很重要的站,自架一套授權清楚的字型也值得,只是要記得登錄。
我的選擇建立在「一個人維護、內容為主、CSP 越緊越好」這三個條件上,條件不同答案就不同。如果你是五個人一起做一個要在兩週內上線的東西,請直接用 Bootstrap,不要看了這篇就覺得要自己寫 CSS 才高尚。合身的衣服有時候就是買的,沒有什麼不對。
那件衣服是哪裡來的
Bootstrap 是 2011 年 Twitter 兩位工程師 Mark Otto 和 Jacob Thornton 做的,一開始叫 Twitter Blueprint,是公司內部為了讓大家的內部工具長得一致做的。開源之後它變成 GitHub 上星星最多的專案之一,維持了很多年。它做對的事是把「一個網頁該長什麼樣」的幾百個小決定預先做好,讓不會設計的工程師也能做出不難看的東西。這個價值是真的,我不打算否認。
它的第五版在 2021 年拿掉了對 jQuery 的依賴,算是跟上了時代。但它的核心模型沒變:一大份 CSS、一份 JavaScript、一組你要照著寫的 class 名稱。你用它,就是穿上它。
Google Fonts 是 2010 年推出的,讓任何網站都能用一行 link 標籤載入好看的字型,字型檔從 Google 的伺服器來。它讓網頁字型從一件奢侈的事變成一件免費的事,這也是真的。只是免費的東西總有另一種價格。
CSP 則是 2012 年前後由 Mozilla 推動、後來變成 W3C 標準的東西。它的邏輯很簡單:網頁自己宣告「我只會從這些地方載入東西」,瀏覽器幫你擋掉其他的。它跟 Bootstrap 和 Google Fonts 沒有仇,只是它們剛好站在對立的兩邊:一邊想從很多地方載入,一邊想從很少地方載入。
常見的三個誤會
第一個誤會是「不用框架就要自己處理所有瀏覽器相容問題」。那是十年前的事。現在主流瀏覽器的 CSS 支援很一致,Grid、Flexbox、自訂屬性都能直接用,框架替你抹平的差異已經不多了。
第二個誤會是「系統字型很醜」。系統字型是各作業系統花大錢設計的,在各自的平台上是最合適的。它們不「特別」,但不特別跟醜是兩回事。
第三個誤會是「CSP 很難設」。第一版很難,因為你會發現網站上有一堆你不知道從哪來的東西。但那正是它的價值:它逼你把那些東西找出來。設好之後,每次要加新東西都會被問一次「這個從哪來」,這個問題值得被問。
一個週末可以試的小練習
打開一個你常去的網站,按 F12 開發者工具,切到網路分頁,重新整理。把請求依網域分組,數一數除了那個網站自己的網域之外,還有幾個網域在送東西給你。找找看有沒有 fonts.gstatic.com 或某個 CDN。這五分鐘會讓你對「一個網頁到底從幾個地方載入東西」有一個很具體的數字,通常比你想的多很多。
然後拿你自己的任何一個靜態頁面,在 head 裡加一個 meta 標籤,http-equiv 填 Content-Security-Policy,content 填 default-src 'self'。重新整理,打開主控台,看有多少紅字。每一條紅字都是一個從外面載入的東西。試著一個一個處理掉:把字型改成系統字型、把 CDN 上的 CSS 抓回本機、把內嵌的 script 搬到檔案裡。做到沒有紅字的時候,你的頁面就達到了這篇講的那個狀態,而你會很清楚地知道每一個決定的代價是什麼。
後記
「合身的衣服有時候就是買的」,這句話是我寫完整篇之後才加上去的,因為我怕整篇讀起來像在說自己寫 CSS 比較高尚。不是的。我只是一個人做一個內容為主的站,條件剛好讓我可以這樣選。如果哪天我要跟四個人一起在兩週內做一個東西,我會第一個說「用 Bootstrap 吧」,然後把這篇文章假裝沒寫過。原則要看場合,這也是一種原則。
留言(0)
還沒有留言。讀完有想法,歡迎留下第一則。