<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="pretty-atom-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hant">
  <title>光輝咖碼</title>
  <subtitle>光輝咖碼是一個分享網站架設、WordPress、靜態網站生成器、程式開發等技術主題的部落格。提供實用的教學文章和工具介紹，幫助讀者建立和管理自己的網站。</subtitle>
  <link href="https://kamadiam.com/feed/feed.xml" rel="self" />
  <link href="https://kamadiam.com/" />
  <updated>2026-01-10T00:00:00Z</updated>
  <id>https://kamadiam.com/</id>
  <author>
    <name>huihere</name>
  </author>
  <entry>
    <title>CSS Border-radius 指南, 不是只能畫圓角</title>
    <link href="https://kamadiam.com/border-radius-guide/" />
    <updated>2026-01-10T00:00:00Z</updated>
    <id>https://kamadiam.com/border-radius-guide/</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;border-radius 通常用來做這些事：&lt;ul&gt;&lt;li&gt;按鈕變圓一點&lt;li&gt;卡片看起來柔和一點&lt;li&gt;&lt;code&gt;border-radius: 50%&lt;/code&gt; 畫一個圓&lt;/ul&gt;&lt;p&gt;其實它還能做更多： &lt;strong&gt;border-radius 其實是一個「形狀語言」&lt;/strong&gt;&lt;p&gt;試試看下面這個實驗，你會發現很多「看起來很設計感的形狀」，其實只是 CSS。&lt;/blockquote&gt;&lt;div data-svelte-component=&quot;BorderRadius&quot; data-svelte-props=&#39;{&quot;label&quot;:&quot;四個角半徑控制&quot;}&#39;&gt;&lt;/div&gt;&lt;hr&gt;&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E7%82%BA%E4%BB%80%E9%BA%BC%E8%A6%81%E9%87%8D%E6%96%B0%E8%AA%8D%E8%AD%98-border-radius?&quot;&gt;為什麼要重新認識 border-radius？&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#border-radius-%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%AA%9E%E6%B3%95&quot;&gt;border-radius 的基本語法&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E4%B8%80%E5%80%8B%E5%80%BC&quot;&gt;一個值&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E5%85%A9%E5%80%8B%E4%B8%89%E5%80%8B%E5%9B%9B%E5%80%8B%E5%80%BC%E7%9A%84%E8%A6%8F%E5%89%87&quot;&gt;兩個、三個、四個值的規則&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E5%96%AE%E4%BD%8D%E5%BE%88%E9%87%8D%E8%A6%81:px-vs-%&quot;&gt;單位很重要：px vs %&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#px:%E5%9B%BA%E5%AE%9A%E5%B9%BE%E4%BD%95&quot;&gt;px：固定幾何&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%:%E7%9B%B8%E5%B0%8D%E6%96%BC%E3%80%8C%E7%9B%92%E5%AD%90%E5%B0%BA%E5%AF%B8%E3%80%8D&quot;&gt;%：相對於「盒子尺寸」&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#/-%E6%96%9C%E7%B7%9A%E8%AA%9E%E6%B3%95:border-radius-%E7%9A%84%E7%9C%9F%E6%AD%A3%E5%A8%81%E5%8A%9B&quot;&gt;/ 斜線語法：border-radius 的真正威力&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E5%AE%8C%E6%95%B4%E8%AA%9E%E6%B3%95&quot;&gt;完整語法&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E7%80%8F%E8%A6%BD%E5%99%A8%E5%85%B6%E5%AF%A6%E6%9C%83%E3%80%8C%E5%81%B7%E5%81%B7%E4%BF%AE%E6%AD%A3%E3%80%8D%E4%BD%A0%E7%9A%84-radius&quot;&gt;瀏覽器其實會「偷偷修正」你的 radius&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E8%A8%AD%E8%A8%88%E6%84%9F%E5%8D%81%E8%B6%B3%E7%9A%84%E5%9C%93%E8%A7%92%E6%87%89%E7%94%A8&quot;&gt;設計感十足的圓角應用&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#1.-%E8%86%A0%E5%9B%8A%E6%8C%89%E9%88%95---%E7%8F%BE%E4%BB%A3-UI-%E7%9A%84%E7%B6%93%E5%85%B8&quot;&gt;1. 膠囊按鈕 - 現代 UI 的經典&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#2.-%E4%B8%8D%E5%B0%8D%E7%A8%B1%E8%A8%AD%E8%A8%88%E5%8D%A1%E7%89%87---%E5%89%B5%E9%80%A0%E8%A6%96%E8%A6%BA%E5%B1%A4%E6%AC%A1&quot;&gt;2. 不對稱設計卡片 - 創造視覺層次&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#3.-%E6%BC%B8%E5%B1%A4%E8%83%8C%E6%99%AF-+-%E5%9C%93%E8%A7%92---%E5%89%B5%E9%80%A0%E6%B7%B1%E5%BA%A6%E6%84%9F&quot;&gt;3. 漸層背景 + 圓角 - 創造深度感&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#4.-%E5%8B%95%E7%95%AB%E9%81%8E%E6%B8%A1---%E4%BA%92%E5%8B%95%E9%AB%94%E9%A9%97&quot;&gt;4. 動畫過渡 - 互動體驗&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#5.-%E5%A4%9A%E5%B1%A4%E6%AC%A1%E5%9C%93%E8%A7%92%E8%A8%AD%E8%A8%88&quot;&gt;5. 多層次圓角設計&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E5%B0%8F%E6%8C%91%E6%88%B0&quot;&gt;小挑戰&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E9%87%8D%E9%BB%9E%E7%B8%BD%E7%B5%90&quot;&gt;重點總結&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/border-radius-guide/#%E5%BB%B6%E4%BC%B8%E5%AD%B8%E7%BF%92&quot;&gt;延伸學習&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id=&quot;為什麼要重新認識-border-radius?&quot;&gt;為什麼要重新認識 border-radius？&lt;/h2&gt;&lt;p&gt;在現代 UI 裡，圓角早就不是裝飾，而是結構的一部分：&lt;ul&gt;&lt;li&gt;&lt;strong&gt;設計系統會定義 radius token&lt;/strong&gt;（sm / md / lg），確保視覺一致性&lt;li&gt;&lt;strong&gt;元件之間的「柔軟程度」需要一致&lt;/strong&gt;，影響整體品牌感受&lt;li&gt;&lt;strong&gt;不同裝置尺寸下，圓角感覺要穩定&lt;/strong&gt;，避免在小螢幕上過於突兀&lt;/ul&gt;&lt;p&gt;border-radius 其實有很多實用功能，但可能比較少被注意到。&lt;p&gt;&lt;strong&gt;這篇文章會介紹：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;✅ 它的「計算模型」和瀏覽器行為&lt;li&gt;✅ 斜線語法，用來創造有機形狀&lt;li&gt;✅ 瀏覽器什麼時候會自動調整值，以及為什麼&lt;li&gt;✅ 如何有意識地設計形狀，而不只是「試試看哪個值好看」&lt;li&gt;✅ 常見的實戰技巧和需要注意的地方&lt;/ul&gt;&lt;h2 id=&quot;border-radius-的基本語法&quot;&gt;border-radius 的基本語法&lt;/h2&gt;&lt;h3 id=&quot;一個值&quot;&gt;一個值&lt;/h3&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 最簡單的用法：四個角使用相同的半徑值
 * 適合：統一的設計風格，快速原型開發 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 12px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:140px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);border-radius:12px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;12px&lt;/div&gt;&lt;p&gt;👉 四個角都一樣，最常用也最簡單。&lt;h3 id=&quot;兩個三個四個值的規則&quot;&gt;兩個、三個、四個值的規則&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;兩個值：&lt;/strong&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 對角線模式：第一個值給左上和右下，第二個值給右上和左下
 * 適合：創造對角線節奏，增加視覺動感 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 8px 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:140px;background:linear-gradient(135deg,#f093fb 0,#f5576c 100%);border-radius:8px 16px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;8px 16px&lt;/div&gt;&lt;p&gt;實際展開是：&lt;ul&gt;&lt;li&gt;左上 / 右下 → 8px（對角線）&lt;li&gt;右上 / 左下 → 16px（對角線）&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;三個值：&lt;/strong&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 不對稱模式：左上獨立，右上和左下相同，右下獨立
 * 適合：創造「方向感」，引導視線流向 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 8px 16px 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:140px;background:linear-gradient(135deg,#4facfe 0,#00f2fe 100%);border-radius:8px 16px 24px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;8px 16px 24px&lt;/div&gt;&lt;p&gt;實際展開是：&lt;ul&gt;&lt;li&gt;左上 → 8px（獨立值）&lt;li&gt;右上 / 左下 → 16px（共享值）&lt;li&gt;右下 → 24px（獨立值）&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;四個值：&lt;/strong&gt;&lt;p&gt;順序永遠是：&lt;strong&gt;左上 → 右上 → 右下 → 左下（順時針）&lt;/strong&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 完全控制模式：每個角都可以獨立設定
 * 適合：精細的設計調整，創造複雜的視覺節奏
 * 記憶技巧：從左上開始，順時針方向 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 8px 12px 20px 4px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:140px;background:linear-gradient(135deg,#43e97b 0,#38f9d7 100%);border-radius:8px 12px 20px 4px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;8px 12px 20px 4px&lt;/div&gt;&lt;p&gt;💡 &lt;strong&gt;小提醒&lt;/strong&gt;：如果視覺效果不如預期，可能是角順序記錯了。記住：從左上開始，順時針方向！&lt;h2 id=&quot;單位很重要:px-vs-%&quot;&gt;單位很重要：px vs %&lt;/h2&gt;&lt;h3 id=&quot;px:固定幾何&quot;&gt;px：固定幾何&lt;/h3&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 固定像素值：無論元素大小如何變化，圓角半徑都保持不變
 * 適合：按鈕、卡片等需要「一致視覺大小」的元件 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:80px;background:linear-gradient(135deg,#fa709a 0,#fee140 100%);border-radius:24px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;24px&lt;/div&gt;&lt;p&gt;&lt;strong&gt;特點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;✅ 不會隨容器比例變&lt;li&gt;✅ 適合元件設計（button / card）- 保證一致的視覺大小&lt;li&gt;✅ 在設計系統中容易維護（固定的 token 值）&lt;/ul&gt;&lt;h3 id=&quot;%:相對於「盒子尺寸」&quot;&gt;%：相對於「盒子尺寸」&lt;/h3&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 百分比值：相對於元素自己的寬度和高度計算
 * 50% 表示：水平半徑 = 寬度的 50%，垂直半徑 = 高度的 50% */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:120px;height:120px;background:linear-gradient(135deg,#a8edea 0,#fed6e3 100%);border-radius:50%;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#333;font-size:14px&quot;&gt;50%&lt;/div&gt;&lt;div style=&quot;width:160px;height:80px;background:linear-gradient(135deg,#ff9a9e 0,#fecfef 100%);border-radius:50%;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;50% (長方形)&lt;/div&gt;&lt;p&gt;&lt;strong&gt;重點不是「50% 很圓」，而是：&lt;/strong&gt;&lt;p&gt;&lt;strong&gt;百分比是根據「盒子自己的寬高」算的&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;正方形 → 圓（因為寬高相等）&lt;li&gt;長方形 → 膠囊（pill）（因為寬高不同）&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;實用技巧：&lt;/strong&gt;&lt;p&gt;📌 為什麼有些人會用 &lt;code&gt;9999px&lt;/code&gt;？&lt;p&gt;因為無論元素多大，&lt;code&gt;9999px&lt;/code&gt; 都保證會讓元素變成最大可能的圓角（通常就是圓形或膠囊形）。這是一個「懶人技巧」，但要注意：&lt;ul&gt;&lt;li&gt;✅ 優點：不需要計算，總是最大圓角&lt;li&gt;⚠️ 缺點：不夠語義化，在設計系統中不推薦&lt;/ul&gt;&lt;h2 id=&quot;/-斜線語法:border-radius-的真正威力&quot;&gt;/ 斜線語法：border-radius 的真正威力&lt;/h2&gt;&lt;p&gt;這個語法比較少被提到，但它是創造「有機形狀」的關鍵。&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 斜線語法：分開控制水平和垂直半徑
 * 格式：水平半徑 / 垂直半徑
 * 這個例子：所有角的水平半徑是 40px，垂直半徑是 20px */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px / 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:100px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);border-radius:40px/20px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px&quot;&gt;40px / 20px&lt;/div&gt;&lt;p&gt;&lt;strong&gt;代表：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;水平方向半徑：40px（X 軸）&lt;li&gt;垂直方向半徑：20px（Y 軸）&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;關鍵理解：&lt;/strong&gt; &lt;strong&gt;每個角其實是一段橢圓弧，不是圓弧。&lt;/strong&gt; 當水平和垂直半徑不同時，就會形成橢圓形的圓角，這是創造各種有機形狀的基礎。&lt;h3 id=&quot;完整語法&quot;&gt;完整語法&lt;/h3&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 完整語法：8 個值控制 4 個角的 X 和 Y 半徑
 * a b c d：四個角的 X 軸（水平）半徑
 * e f g h：四個角的 Y 軸（垂直）半徑
 * 順序：左上 → 右上 → 右下 → 左下（順時針） */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; a b c d / e f g h&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;/&lt;/code&gt; 前：X 軸半徑（水平方向）&lt;li&gt;&lt;code&gt;/&lt;/code&gt; 後：Y 軸半徑（垂直方向）&lt;li&gt;每個角都可以獨立控制，創造無限可能&lt;/ul&gt;&lt;div style=&quot;width:280px;height:200px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);border-radius:50px 80px 100px 30px/40px 60px 80px 20px;margin:40px auto;position:relative&quot;&gt;&lt;div style=&quot;position:absolute;top:-25px;left:20px;background:#ff6b6b;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;a&lt;/div&gt;&lt;div style=&quot;position:absolute;top:-25px;right:20px;background:#51cf66;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;b&lt;/div&gt;&lt;div style=&quot;position:absolute;bottom:-25px;right:20px;background:#339af0;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;c&lt;/div&gt;&lt;div style=&quot;position:absolute;bottom:-25px;left:20px;background:#ffd43b;color:#000;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;d&lt;/div&gt;&lt;div style=&quot;position:absolute;top:40px;left:-35px;background:#ff8787;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;e&lt;/div&gt;&lt;div style=&quot;position:absolute;top:40px;right:-35px;background:#69db7c;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;f&lt;/div&gt;&lt;div style=&quot;position:absolute;bottom:40px;right:-35px;background:#4dabf7;color:#fff;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;g&lt;/div&gt;&lt;div style=&quot;position:absolute;bottom:40px;left:-35px;background:#ffe066;color:#000;padding:4px 10px;border-radius:8px;font-size:var(--step-1);font-weight:700&quot;&gt;h&lt;/div&gt;&lt;div style=&quot;position:absolute;bottom:-60px;left:50%;transform:translateX(-50%);color:#666;font-size:14px;text-align:center&quot;&gt;&lt;strong&gt;X軸:&lt;/strong&gt; a b c d&lt;br&gt;&lt;strong&gt;Y軸:&lt;/strong&gt; e f g h&lt;/div&gt;&lt;/div&gt;&lt;p&gt;📌 這就是很多「有機形狀」的來源。&lt;h2 id=&quot;瀏覽器其實會「偷偷修正」你的-radius&quot;&gt;瀏覽器其實會「偷偷修正」你的 radius&lt;/h2&gt;&lt;p&gt;如果你這樣寫：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;/* 你設定了 80px，但元素寬度只有 100px */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 80px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;會發生什麼？&lt;p&gt;實際上：&lt;ul&gt;&lt;li&gt;瀏覽器會&lt;strong&gt;自動 clamp（限制）半徑值&lt;/strong&gt;&lt;li&gt;確保圓角不會超過元素尺寸的一半&lt;li&gt;在這個例子中，實際生效的是 &lt;code&gt;50px&lt;/code&gt;（高度的一半）&lt;/ul&gt;&lt;p&gt;這個行為是 CSS 規範中的&lt;strong&gt;正常機制&lt;/strong&gt;，不是 bug。&lt;p&gt;&lt;strong&gt;計算規則：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;水平半徑不能超過 &lt;code&gt;width / 2&lt;/code&gt;&lt;li&gt;垂直半徑不能超過 &lt;code&gt;height / 2&lt;/code&gt;&lt;li&gt;如果超過，瀏覽器會自動縮放兩個半徑，保持比例&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;實用技巧&lt;/strong&gt;：當你輸入很大的 radius 值時，畫面看起來「卡住不動」，是因為瀏覽器已經自動調整到最大可能值了。如果你想要「最大圓角」，直接設定一個很大的值（如 &lt;code&gt;9999px&lt;/code&gt;）即可。&lt;h2 id=&quot;設計感十足的圓角應用&quot;&gt;設計感十足的圓角應用&lt;/h2&gt;&lt;h3 id=&quot;1.-膠囊按鈕---現代-UI-的經典&quot;&gt;1. 膠囊按鈕 - 現代 UI 的經典&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;capsule-button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;立即下載&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.capsule-button&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 內距：垂直 12px，水平 24px，創造舒適的點擊區域 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 12px 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 關鍵技巧：使用固定 px 值，約為按鈕高度的一半
   * 這樣可以創造完美的膠囊形狀，不受文字長度影響
   * 如果使用 50%，在按鈕寬度變化時會變成橢圓形 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 25px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 漸層背景增加視覺吸引力 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #667eea 0%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #764ba2 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 500&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 陰影增加深度感，顏色與背景色調一致 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 4px 15px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;102&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 126&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 234&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.4&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 平滑過渡效果，讓互動更自然 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; all 0.3s ease&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pointer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.capsule-button:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 微妙的向上移動，創造「浮起」的視覺效果 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-2px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* hover 時增強陰影，強化浮起感 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 8px 25px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;102&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 126&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 234&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.6&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;margin:20px auto;text-align:center&quot;&gt;&lt;button style=&quot;padding:12px 24px;border:none;border-radius:25px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);color:#fff;font-weight:500;box-shadow:0 4px 15px rgba(102,126,234,.4);transition:all .3s ease;cursor:pointer;font-size:14px&quot; onmouseover=&#39;this.style.transform=&quot;translateY(-2px)&quot;,this.style.boxShadow=&quot;0 8px 25px rgba(102, 126, 234, 0.6)&quot;&#39; onmouseout=&#39;this.style.transform=&quot;none&quot;,this.style.boxShadow=&quot;0 4px 15px rgba(102, 126, 234, 0.4)&quot;&#39;&gt;立即下載&lt;/button&gt;&lt;/div&gt;&lt;h3 id=&quot;2.-不對稱設計卡片---創造視覺層次&quot;&gt;2. 不對稱設計卡片 - 創造視覺層次&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;asymmetric-card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card-title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;不對稱設計&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;利用不同大小的圓角創造視覺節奏，讓設計更有個性和現代感。&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.asymmetric-card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #667eea 0%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #764ba2 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 不對稱圓角模式：左上/右下大，右上/左下小
   * 順序：左上 → 右上 → 右下 → 左下（順時針）
   * 這種模式創造出「對角線節奏」，比完全對稱更有動感 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px 8px 20px 8px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 柔和的陰影，顏色與背景呼應 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 8px 32px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;102&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 126&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 234&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.card-title&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 0 12px 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 18px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 600&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.asymmetric-card p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 使用 rgba 而非 opacity，避免影響子元素 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.9&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.5&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 14px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:280px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);border-radius:20px 8px 20px 8px;padding:24px;box-shadow:0 8px 32px rgba(102,126,234,.3);margin:20px auto;color:#fff&quot;&gt;&lt;div style=&quot;margin:0 0 12px 0;color:#fff;font-size:18px;font-weight:600&quot;&gt;不對稱設計&lt;/div&gt;&lt;p style=&quot;margin:0;color:rgba(255,255,255,.9);line-height:1.5;font-size:14px&quot;&gt;利用不同大小的圓角創造視覺節奏，讓設計更有個性和現代感。&lt;/div&gt;&lt;h3 id=&quot;3.-漸層背景-+-圓角---創造深度感&quot;&gt;3. 漸層背景 + 圓角 - 創造深度感&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;gradient-depth-card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card-title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;漸層深度效果&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;結合漸層背景和微妙的邊框效果，創造出立體的視覺深度。&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.gradient-depth-card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 三色漸層：從藍紫到粉紫，創造豐富的視覺層次 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    #667eea 0%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    #764ba2 50%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    #f093fb 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 統一的圓角，讓整體更和諧 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 相對定位，讓 ::after 偽元素可以絕對定位 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 深色陰影增加立體感 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 10px 40px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;102&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 126&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 234&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.gradient-depth-card::after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* inset: 0 等同於 top: 0; right: 0; bottom: 0; left: 0;
   * 讓偽元素完全覆蓋父元素 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 重要：繼承父元素的圓角，確保邊框也跟著圓角 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* padding 創造邊框的「厚度」 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 半透明白色漸層，模擬高光效果 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;0.05&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* mask 技巧：只顯示邊框區域，隱藏中間內容
   * content-box 只顯示 padding 區域（即邊框）
   * exclude 模式讓邊框區域可見，內容區域透明 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;#fff 0 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; content-box&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;#fff 0 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;mask-composite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; exclude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.card-title&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 0 12px 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 18px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 600&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.gradient-depth-card p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.9&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.5&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 14px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:260px;background:linear-gradient(135deg,#667eea 0,#764ba2 50%,#f093fb 100%);border-radius:16px;padding:22px;margin:20px auto;position:relative;color:#fff;box-shadow:0 10px 40px rgba(102,126,234,.3);border:2px solid transparent;background-clip:padding-box&quot;&gt;&lt;div style=&quot;position:absolute;inset:0;border-radius:16px;padding:2px;background:linear-gradient(135deg,rgba(255,255,255,.2),rgba(255,255,255,.05));border-radius:inherit;pointer-events:none&quot;&gt;&lt;/div&gt;&lt;div style=&quot;position:relative;z-index:1&quot;&gt;&lt;div style=&quot;margin:0 0 12px 0;font-size:18px;font-weight:600&quot;&gt;漸層深度效果&lt;/div&gt;&lt;p style=&quot;margin:0;opacity:.9;line-height:1.5;font-size:14px&quot;&gt;結合漸層背景和微妙的邊框效果，創造出立體的視覺深度。&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;4.-動畫過渡---互動體驗&quot;&gt;4. 動畫過渡 - 互動體驗&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;interactive-morph&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hover Me&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.interactive-morph&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 120px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 120px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 對角漸層，從紅到青，視覺對比強烈 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;45deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #ff6b6b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #4ecdc4&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 初始狀態：小圓角 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 關鍵：只對 border-radius 做動畫，使用緩動函數
   * cubic-bezier(0.4, 0, 0.2, 1) 是 Material Design 的標準緩動
   * 創造出「先快後慢」的自然動畫效果 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; border-radius 0.6s &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0.4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token property&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pointer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;align-items&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bold&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 8px 32px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 107&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 107&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.interactive-morph:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* hover 時變成大圓角（接近圓形）
   * 因為元素是正方形，60px 約等於寬度的一半，形成圓形 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 60px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 同時放大，增強互動感 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;margin:20px auto;text-align:center&quot;&gt;&lt;div style=&quot;width:120px;height:120px;background:linear-gradient(45deg,#ff6b6b,#4ecdc4);border-radius:20px;transition:border-radius .6s cubic-bezier(.4,0,.2,1),transform .6s ease;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:#fff;font-weight:700;box-shadow:0 8px 32px rgba(255,107,107,.3);margin:10px&quot; onmouseover=&#39;this.style.borderRadius=&quot;60px&quot;,this.style.transform=&quot;scale(1.1)&quot;&#39; onmouseout=&#39;this.style.borderRadius=&quot;20px&quot;,this.style.transform=&quot;scale(1)&quot;&#39;&gt;Hover Me&lt;/div&gt;&lt;p style=&quot;font-size:14px;color:#666;margin-top:10px&quot;&gt;滑鼠移到上面看看動畫效果&lt;/div&gt;&lt;h3 id=&quot;5.-多層次圓角設計&quot;&gt;5. 多層次圓角設計&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;layered-design&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;accent-element&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card-title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;多層次設計&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;不同大小的圓角創造視覺層次，讓介面更有深度和趣味。&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.layered-design&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 外層：大圓角，作為容器的「框架」 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #667eea 0%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #764ba2 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* padding 創造內外層之間的「間隙」 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.inner-content&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 內層：較小的圓角，形成層次對比
   * 24px vs 16px 的差異創造視覺深度 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.95&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 陰影讓內層「浮」起來 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 8px 32px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;0.15&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 毛玻璃效果（如果瀏覽器支援） */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;backdrop-filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blur&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;10px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.accent-element&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 負值定位，讓元素「溢出」容器邊界
   * 創造出「貼紙」或「標籤」的視覺效果 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -8px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -8px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;135deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #ff6b6b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #4ecdc4&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 中等大小的圓角，與其他層次形成對比 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 12px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 強烈的陰影，讓這個元素更突出 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 6px 20px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 107&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 107&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.6&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;/* 白色邊框，與背景形成對比，增強視覺分離 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3px solid white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.card-title&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 0 12px 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #333&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 600&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.layered-design p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #666&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.5&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 14px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:300px;background:linear-gradient(135deg,#667eea 0,#764ba2 100%);border-radius:24px;padding:16px;margin:20px auto;position:relative;color:#fff&quot;&gt;&lt;div style=&quot;background:rgba(255,255,255,.95);border-radius:16px;padding:20px;box-shadow:0 8px 32px rgba(0,0,0,.15);position:relative&quot;&gt;&lt;div style=&quot;position:absolute;top:-8px;right:-8px;width:40px;height:40px;background:linear-gradient(135deg,#ff6b6b,#4ecdc4);border-radius:12px;box-shadow:0 6px 20px rgba(255,107,107,.6);border:3px solid #fff&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin:0 0 12px 0;color:#333;font-size:16px;font-weight:600&quot;&gt;多層次設計&lt;/div&gt;&lt;p style=&quot;margin:0;color:#666;line-height:1.5;font-size:14px&quot;&gt;不同大小的圓角創造視覺層次，讓介面更有深度和趣味。&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;小挑戰&quot;&gt;小挑戰&lt;/h2&gt;&lt;p&gt;試試只用 border-radius 創造這些形狀：&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;水滴形狀&lt;/strong&gt;：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 技巧解析：
 * X軸：四個角都是 50%（標準圓角）
 * Y軸：上方 60%（較圓），下方 40%（較尖）
 * 這樣創造出上圓下尖的水滴效果 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50% 50% 50% 50% / 60% 60% 40% 40%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:80px;height:140px;background:linear-gradient(135deg,#74c0fc 0,#339af0 100%);border-radius:50% 50% 50% 50%/60% 60% 40% 40%;margin:20px auto&quot;&gt;&lt;/div&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;有方向感的卡片&lt;/strong&gt;：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 對角線模式：左上/右下大圓角，右上/左下小圓角
 * 創造出「指向性」的視覺效果，適合用在需要引導視線的地方 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px 4px 16px 4px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:160px;height:90px;background:linear-gradient(135deg,#ffd43b 0,#fab005 100%);border-radius:16px 4px 16px 4px;margin:20px auto;display:flex;align-items:center;justify-content:center;color:#333;font-size:14px&quot;&gt;方向感卡片&lt;/div&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;柔軟的 blob（有機形狀）&lt;/strong&gt;：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* 進階技巧：使用百分比創造不規則的有機形狀
 * X軸：40% 60% 60% 40% - 左右不對稱
 * Y軸：60% 30% 60% 40% - 上下也不對稱
 * 這種組合創造出「柔軟、有機」的視覺感受
 * 適合用在需要「親和力」的設計中 */&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40% 60% 60% 40% / 60% 30% 60% 40%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style=&quot;width:140px;height:100px;background:linear-gradient(135deg,#d0bfff 0,#9775fa 100%);border-radius:40% 60% 60% 40%/60% 30% 60% 40%;margin:20px auto&quot;&gt;&lt;/div&gt;&lt;/ol&gt;&lt;h2 id=&quot;重點總結&quot;&gt;重點總結&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;border-radius 是一個形狀語言&lt;/strong&gt;，不只是簡單的圓角裝飾&lt;li&gt;&lt;strong&gt;斜線語法 &lt;code&gt;/&lt;/code&gt; 是核心&lt;/strong&gt;：水平和垂直半徑可以分開控制，創造橢圓和有機形狀&lt;li&gt;&lt;strong&gt;瀏覽器會自動 clamp 數值&lt;/strong&gt;：確保圓角不會超出元素範圍，這是正常機制&lt;li&gt;&lt;strong&gt;單位選擇很重要&lt;/strong&gt;：&lt;ul&gt;&lt;li&gt;&lt;code&gt;px&lt;/code&gt;：固定幾何，適合元件設計，保證一致的視覺大小&lt;li&gt;&lt;code&gt;%&lt;/code&gt;：相對尺寸，適合響應式設計，但要注意比例變化&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;好的圓角來自有意識的選擇&lt;/strong&gt;：理解計算模型、單位差異和瀏覽器行為&lt;li&gt;&lt;strong&gt;實戰技巧&lt;/strong&gt;：&lt;ul&gt;&lt;li&gt;膠囊按鈕：使用固定 px 值（約為高度一半）&lt;li&gt;最大圓角：使用 &lt;code&gt;9999px&lt;/code&gt; 或 &lt;code&gt;50%&lt;/code&gt;（取決於需求）&lt;li&gt;有機形狀：使用百分比配合斜線語法&lt;li&gt;多層次設計：外層大圓角，內層小圓角，創造深度&lt;/ul&gt;&lt;/ul&gt;&lt;h2 id=&quot;延伸學習&quot;&gt;延伸學習&lt;/h2&gt;&lt;p&gt;想要更深入？試試這些進階主題：&lt;ul&gt;&lt;li&gt;&lt;strong&gt;與 &lt;code&gt;clip-path&lt;/code&gt; 結合&lt;/strong&gt;：創造更複雜的形狀&lt;li&gt;&lt;strong&gt;動畫技巧&lt;/strong&gt;：讓形狀在 hover 時平滑變形&lt;li&gt;&lt;strong&gt;響應式圓角&lt;/strong&gt;：使用 CSS 變數和媒體查詢&lt;li&gt;&lt;strong&gt;效能考量&lt;/strong&gt;：大量圓角元素的優化技巧&lt;/ul&gt;&lt;p&gt;希望這些內容對你有幫助。🎨</content>
  </entry>
  <entry>
    <title>在 Eleventy（11ty）中優雅地使用 Svelte：一套實用的 Vite-based islands 架構</title>
    <link href="https://kamadiam.com/integrate-svelte-with-11ty/" />
    <updated>2026-01-06T00:00:00Z</updated>
    <id>https://kamadiam.com/integrate-svelte-with-11ty/</id>
    <content type="html">&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#%E7%82%BA%E4%BB%80%E9%BA%BC%E6%88%91%E6%83%B3%E5%9C%A8-11ty-%E8%A3%A1%E7%94%A8-Svelte?&quot;&gt;為什麼我想在 11ty 裡用 Svelte？&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#%E9%80%99%E7%AF%87%E6%96%87%E7%AB%A0%E6%9C%83%E4%BB%8B%E7%B4%B9%E4%BB%80%E9%BA%BC?&quot;&gt;這篇文章會介紹什麼？&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#%E6%95%B4%E5%90%88%E6%AD%A5%E9%A9%9F&quot;&gt;整合步驟&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-1:%E5%9C%A8-11ty-%E4%B8%AD%E5%95%9F%E7%94%A8-Svelte(Vite)&quot;&gt;Step 1：在 11ty 中啟用 Svelte（Vite）&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-2:%E5%BB%BA%E7%AB%8B%E4%B8%80%E5%80%8B-Svelte-shortcode(%E9%97%9C%E9%8D%B5)&quot;&gt;Step 2：建立一個 Svelte shortcode（關鍵）&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-3:%E5%9C%A8-Markdown-%E6%96%87%E7%AB%A0%E4%B8%AD%E4%BD%BF%E7%94%A8&quot;&gt;Step 3：在 Markdown 文章中使用&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-4:%E6%92%B0%E5%AF%AB%E4%B8%80%E5%80%8B-Svelte-%E5%85%83%E4%BB%B6&quot;&gt;Step 4：撰寫一個 Svelte 元件&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-5:Client-side-Svelte-Loader(%E6%A0%B8%E5%BF%83)&quot;&gt;Step 5：Client-side Svelte Loader（核心）&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#Step-6:%E6%95%B4%E5%90%88-Barba.js&quot;&gt;Step 6：整合 Barba.js&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/integrate-svelte-with-11ty/#%E7%B5%90%E8%AA%9E&quot;&gt;結語&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;執行範例&lt;/strong&gt;&lt;div data-svelte-component=&quot;Counter&quot; data-svelte-props=&#39;{&quot;count&quot;:10,&quot;label&quot;:&quot;目前點擊數&quot;}&#39;&gt;&lt;/div&gt;&lt;p&gt;這是用 svelte 寫的元件，整合在 markdown file.&lt;h2 id=&quot;為什麼我想在-11ty-裡用-Svelte?&quot;&gt;為什麼我想在 11ty 裡用 Svelte？&lt;/h2&gt;&lt;p&gt;Eleventy（11ty）是一個我非常喜歡的靜態網站產生器：&lt;ul&gt;&lt;li&gt;快&lt;li&gt;簡單&lt;li&gt;不綁框架&lt;li&gt;非常適合寫技術文章&lt;/ul&gt;&lt;p&gt;但寫久了總會遇到一個問題：&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;文章裡想放一點互動的東西&lt;/strong&gt;&lt;/blockquote&gt;&lt;p&gt;例如：&lt;ul&gt;&lt;li&gt;小型計算器&lt;li&gt;Demo widget&lt;li&gt;可重複使用的互動範例&lt;li&gt;教學用的即時操作元件&lt;/ul&gt;&lt;p&gt;這時候我並不想：&lt;ul&gt;&lt;li&gt;把整個網站搬去 SvelteKit&lt;li&gt;或為了一個元件引入一整套 SPA 架構&lt;/ul&gt;&lt;p&gt;於是我選擇了一條折衷但非常實用的路：&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;11ty 負責靜態內容&lt;br&gt;Svelte 只負責「局部互動」&lt;/strong&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;這篇文章會介紹什麼?&quot;&gt;這篇文章會介紹什麼？&lt;/h2&gt;&lt;p&gt;這篇會完整說明我目前在用的一套做法：&lt;ul&gt;&lt;li&gt;在 11ty 文章中用 &lt;strong&gt;shortcode 插入 Svelte 元件&lt;/strong&gt;&lt;li&gt;Svelte 元件集中管理、每個元件一個檔案&lt;li&gt;透過 &lt;strong&gt;Vite 自動打包整合到 11ty build&lt;/strong&gt;&lt;li&gt;支援 &lt;strong&gt;Barba.js 無刷新換頁&lt;/strong&gt;&lt;li&gt;最後會比較這套做法和 &lt;strong&gt;11ty is-land&lt;/strong&gt; 的差異&lt;/ul&gt;&lt;h2 id=&quot;整合步驟&quot;&gt;整合步驟&lt;/h2&gt;&lt;p&gt;整個流程其實很單純：&lt;ol&gt;&lt;li&gt;Markdown 文章中放一個「Svelte 插槽」&lt;li&gt;11ty build 時輸出普通 HTML&lt;li&gt;瀏覽器載入後：&lt;ul&gt;&lt;li&gt;JS 掃描插槽&lt;li&gt;找到對應的 Svelte 元件&lt;li&gt;&lt;code&gt;mount()&lt;/code&gt; 掛載上去&lt;/ul&gt;&lt;/ol&gt;&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Markdown
  ↓
HTML（含 data-svelte-component 插槽）
  ↓
Vite bundle（含 Svelte）
  ↓
Client-side mount&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;專案目錄結構: 把 Svelte 元件集中管理：&lt;pre&gt;&lt;code&gt;src/
├─ svelte/            # 專門放 Svelte 元件
│  ├─ Counter.svelte
│  └─ MyWidget.svelte
└─ assets/
   └─ js/
      ├─ site.js
      └─ svelte-loader.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;好處很明確：&lt;ul&gt;&lt;li&gt;元件與文章內容完全解耦&lt;li&gt;同一個元件可以在不同文章重複使用&lt;li&gt;不會污染 11ty 的模板系統&lt;/ul&gt;&lt;h3 id=&quot;Step-1:在-11ty-中啟用-Svelte(Vite)&quot;&gt;Step 1：在 11ty 中啟用 Svelte（Vite）&lt;/h3&gt;&lt;p&gt;我使用的是官方的 plugin：&lt;ul&gt;&lt;li&gt;@11ty/eleventy-plugin-vite&lt;li&gt;@sveltejs/vite-plugin-svelte&lt;/ul&gt;&lt;p&gt;修改 eleventy.config.js&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; EleventyVitePlugin &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@11ty/eleventy-plugin-vite&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 11ty 官方 Vite 插件&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; svelte &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@sveltejs/vite-plugin-svelte&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Svelte Vite 插件&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EleventyVitePlugin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 啟用 11ty Vite 插件&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;viteOptions&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;svelte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 讓 Vite 能編譯 .svelte 檔案&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 返回 11ty 配置物件&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這裡的重點觀念是：&lt;blockquote&gt;&lt;p&gt;11ty 不負責編譯 Svelte&lt;br&gt;Svelte 完全交給 Vite&lt;/blockquote&gt;&lt;h3 id=&quot;Step-2:建立一個-Svelte-shortcode(關鍵)&quot;&gt;Step 2：建立一個 Svelte shortcode（關鍵）&lt;/h3&gt;&lt;p&gt;這一步是整個架構的靈魂，也沒那麼誇張啦，就是使用 11ty shortcode 產生 html 放 svelte 元件位置&lt;p&gt;修改 eleventy.config.js&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addShortcode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;svelte&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 註冊 &quot;svelte&quot; shortcode&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; propsString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 將 props 物件序列化為 JSON 字串&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;amp;apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 將單引號轉義為 HTML 實體，避免 HTML 屬性解析錯誤&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; // 返回 HTML 字串，創建一個空的 div 作為 Svelte 元件掛載點
    &amp;lt;div
      data-svelte-component=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; // 指定要掛載的 Svelte 元件名稱
      data-svelte-props=&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;propsString&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&gt; // 以 JSON 格式傳遞 props 給元件
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這個 shortcode 做的事情只有一個：&lt;p&gt;在 HTML 中留下「我之後要掛哪個 Svelte 元件」的資訊&lt;h3 id=&quot;Step-3:在-Markdown-文章中使用&quot;&gt;Step 3：在 Markdown 文章中使用&lt;/h3&gt;&lt;p&gt;放在文章任何位置都行。&lt;pre class=&quot;language-nunjucks&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-nunjucks&quot;&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;svelte&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Counter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;目前點擊數&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;!&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; 使用 &lt;span class=&quot;token variable&quot;&gt;svelte&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;shortcode&lt;/span&gt; 插入 &lt;span class=&quot;token variable&quot;&gt;Counter&lt;/span&gt; 元件，並傳遞初始 &lt;span class=&quot;token variable&quot;&gt;props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此時請記住一件事：&lt;p&gt;這裡不會渲染 Svelte 只會產生 shortcode 設定的 HTML，例如：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;data-svelte-component&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Counter&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;data-svelte-props&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&#39;&lt;/span&gt;{&quot;count&quot;:10,&quot;label&quot;:&quot;目前點擊數&quot;}&lt;span class=&quot;token punctuation&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;Step-4:撰寫一個-Svelte-元件&quot;&gt;Step 4：撰寫一個 Svelte 元件&lt;/h3&gt;&lt;p&gt;ex: Counter.svelte&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; label &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Count&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;$props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 解構 props，設定預設值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;p-4 border rounded my-4&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 使用 Tailwind CSS 樣式 --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{label}: {count}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 顯示標籤和計數值 --&gt;&lt;/span&gt;

  &amp;lt;button onclick={() =&gt; count--}&gt;-1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 減少按鈕 --&gt;&lt;/span&gt;
  &amp;lt;button onclick={() =&gt; count++}&gt;+1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 增加按鈕 --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這是一個非常普通的 Svelte 元件，沒有任何 11ty 耦合。&lt;h3 id=&quot;Step-5:Client-side-Svelte-Loader(核心)&quot;&gt;Step 5：Client-side Svelte Loader（核心）&lt;/h3&gt;&lt;p&gt;基本版本（全部一起打包）&lt;p&gt;ex: svelte-loader.js&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; mount &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;svelte&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Svelte 5：掛載元件&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; modules &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;../../svelte/*.svelte&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;eager&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 小元件：直接全打包&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; components &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// { ComponentName: Component }&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; filePath &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; modules&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &quot;../../svelte/Counter.svelte&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filePath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.svelte&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &quot;Counter&quot;&lt;/span&gt;
  components&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; modules&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;filePath&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 註冊元件&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initSvelteComponents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;root &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 允許傳入 Barba container&lt;/span&gt;
  root&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[data-svelte-component]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;svelteInitialized&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 已初始化就跳過&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;svelteComponent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 元件名稱&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Component &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; components&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 取得元件&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Component&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 以前你這邊是 return（太安靜）&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[svelte] component not found: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; raw &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;svelteProps &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// props 字串（預設空物件）&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;raw&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parse props JSON&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[svelte] invalid props JSON for &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;raw&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 以前你是吞掉&lt;/span&gt;
      props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 掛載元件&lt;/span&gt;
    el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;svelteInitialized &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 標記完成&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這裡利用了 Vite 的 &lt;code&gt;import.meta.glob&lt;/code&gt;：&lt;ul&gt;&lt;li&gt;自動掃描 &lt;code&gt;src/svelte/&lt;/code&gt;&lt;li&gt;不需要手動 import 每個元件&lt;li&gt;新增元件只需要放檔案即可&lt;/ul&gt;&lt;h3 id=&quot;Step-6:整合-Barba.js&quot;&gt;Step 6：整合 Barba.js&lt;/h3&gt;&lt;p&gt;如果你使用 Barba.js 或 PJAX 類工具，這一步非常必要：&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; initSvelteComponents &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./svelte-loader.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 匯入 Svelte 元件初始化函數&lt;/span&gt;

document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 頁面首次載入時&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;initSvelteComponents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 初始化所有 Svelte 元件&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

barba&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hooks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;afterEnter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Barba.js 換頁完成後&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;initSvelteComponents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 重新初始化新頁面的 Svelte 元件&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;原因很簡單：&lt;p&gt;Barba 換頁不會重新載入 JS，但新頁面需要重新掛載 Svelte&lt;hr&gt;&lt;p&gt;那這套和 11ty is-land 有什麼不同？&lt;p&gt;簡單對照&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;項目&lt;th&gt;本文做法&lt;th&gt;11ty is-land&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;架構&lt;td&gt;CSR islands&lt;td&gt;SSR + hydration&lt;tr&gt;&lt;td&gt;初始 HTML&lt;td&gt;插槽是空的&lt;td&gt;可預渲染&lt;tr&gt;&lt;td&gt;SEO&lt;td&gt;不太好&lt;td&gt;較佳&lt;tr&gt;&lt;td&gt;載入策略&lt;td&gt;手動控制&lt;td&gt;宣告式（on:visible）&lt;tr&gt;&lt;td&gt;Barba 相容&lt;td&gt;非常好&lt;td&gt;需額外處理&lt;tr&gt;&lt;td&gt;複雜度&lt;td&gt;不好說&lt;td&gt;不好說&lt;/table&gt;&lt;p&gt;實務建議&lt;ul&gt;&lt;li&gt;部落格互動元件 → 本文這套&lt;li&gt;SEO 關鍵內容元件 → is-land&lt;li&gt;已有 Vite / Barba 架構 → 本文這套會非常順&lt;/ul&gt;&lt;p&gt;大多數使用 Svelte 的目的應該是為了互動操作，如果是為了 SEO 產生內容，那這樣用 Svelte 就不太適合了。&lt;h2 id=&quot;結語&quot;&gt;結語&lt;/h2&gt;&lt;p&gt;這套做法本質上是一種：簡單可控的 islands 架構&lt;p&gt;它不追求「什麼都幫你包好」，而是讓你清楚知道：&lt;ul&gt;&lt;li&gt;元件什麼時候被載入&lt;li&gt;JS 什麼時候被執行&lt;li&gt;換頁時發生了什麼事&lt;/ul&gt;&lt;p&gt;如果你正在用 11ty 寫技術部落格，又偶爾需要一點互動，svelte 是一個還不錯的方式。</content>
  </entry>
  <entry>
    <title>CSS Stacking Context 教學：z-index 為什麼不聽話？</title>
    <link href="https://kamadiam.com/css-stack-context/" />
    <updated>2026-01-05T00:00:00Z</updated>
    <id>https://kamadiam.com/css-stack-context/</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;你一定遇過這些情況：&lt;br&gt;&lt;code&gt;z-index: 9999&lt;/code&gt; 還是沒用、dropdown 被切掉、modal 被 header 壓住。&lt;br&gt;這篇文章會用一個「投影片世界」的比喻，就像上面這張圖，馬上就能了解問題的根源。&lt;/blockquote&gt;&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5:%E4%BB%80%E9%BA%BC%E6%98%AF-Stacking-Context(%E5%A0%86%E7%96%8A%E4%B8%8A%E4%B8%8B%E6%96%87)&quot;&gt;核心概念：什麼是 Stacking Context（堆疊上下文）&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E6%8A%95%E5%BD%B1%E7%89%87%E4%B8%96%E7%95%8C%E7%9A%84%E6%AF%94%E5%96%BB&quot;&gt;投影片世界的比喻&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#z-index-%E6%9C%83%E5%A4%B1%E6%95%88%E7%9A%84%E7%9C%9F%E6%AD%A3%E5%8E%9F%E5%9B%A0&quot;&gt;z-index 會失效的真正原因&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#z-index-%E4%B8%8D%E6%98%AF%E9%9A%A8%E4%BE%BF%E5%B0%B1%E8%83%BD%E7%94%A8&quot;&gt;z-index 不是隨便就能用&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E7%88%B6%E5%B1%A4%E4%B8%80%E6%97%A6%E5%BB%BA%E7%AB%8B%E4%B8%96%E7%95%8C,%E5%AD%90%E5%B1%A4%E5%B0%B1%E8%A2%AB%E5%B0%81%E5%8D%B0&quot;&gt;父層一旦建立世界，子層就被封印&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E5%93%AA%E4%BA%9B%E6%83%85%E6%B3%81%E6%9C%83%E5%BB%BA%E7%AB%8B%E6%96%B0%E7%9A%84-Stacking-Context&quot;&gt;哪些情況會建立新的 Stacking Context&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E5%B8%B8%E8%A6%8B%E8%A7%B8%E7%99%BC%E6%A2%9D%E4%BB%B6%E6%95%B4%E7%90%86&quot;&gt;常見觸發條件整理&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#isolation:-isolate-%E6%98%AF%E6%95%91%E5%91%BD%E7%94%A8%E7%9A%84&quot;&gt;isolation: isolate 是救命用的&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E7%82%BA%E4%BB%80%E9%BA%BC-z-index:-9999-%E9%82%84%E6%98%AF%E8%BC%B8&quot;&gt;為什麼 z-index: 9999 還是輸&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E7%B5%90%E6%A7%8B%E7%AF%84%E4%BE%8B&quot;&gt;結構範例&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E5%AF%A6%E9%9A%9B%E7%99%BC%E7%94%9F%E4%BA%86%E4%BB%80%E9%BA%BC%E4%BA%8B&quot;&gt;實際發生了什麼事&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E4%B8%89%E5%80%8B%E6%9C%80%E5%B8%B8%E8%A6%8B%E4%B9%9F%E6%9C%80%E7%97%9B%E7%9A%84%E5%AF%A6%E6%88%B0%E5%9D%91&quot;&gt;三個最常見、也最痛的實戰坑&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#overflow:-hidden-%E6%8A%8A%E6%B5%AE%E5%B1%A4%E5%88%87%E6%8E%89&quot;&gt;overflow: hidden 把浮層切掉&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#transform-%E8%AE%93%E5%B1%A4%E7%B4%9A%E7%AA%81%E7%84%B6%E4%BA%82%E6%8E%89&quot;&gt;transform 讓層級突然亂掉&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#fixed-%E4%B8%8D%E5%86%8D%E7%9B%B8%E5%B0%8D%E8%A6%96%E7%AA%97&quot;&gt;fixed 不再相對視窗&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E5%AF%A6%E7%94%A8%E7%9A%84-Debug-%E6%80%9D%E8%80%83%E6%B5%81%E7%A8%8B&quot;&gt;實用的 Debug 思考流程&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E5%B0%88%E6%A1%88%E7%AD%89%E7%B4%9A%E7%9A%84-z-index-%E7%AE%A1%E7%90%86%E6%96%B9%E5%BC%8F&quot;&gt;專案等級的 z-index 管理方式&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E6%9C%80%E7%A9%A9%E5%AE%9A%E7%9A%84-Tooltip-/-Modal-%E8%A7%A3%E6%B3%95&quot;&gt;最穩定的 Tooltip / Modal 解法&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/css-stack-context/#%E7%B8%BD%E7%B5%90&quot;&gt;總結&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id=&quot;核心概念:什麼是-Stacking-Context(堆疊上下文)&quot;&gt;核心概念：什麼是 Stacking Context（堆疊上下文）&lt;/h2&gt;&lt;p&gt;在多數人的直覺裡，&lt;code&gt;z-index&lt;/code&gt; 像是一個「數字越大就越上面」的全域排序系統。&lt;br&gt;但實際上，CSS 的層級運作方式&lt;strong&gt;完全不是這樣&lt;/strong&gt;。&lt;p&gt;比較正確的理解方式是：&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;z-index 只在同一個 stacking context 裡有意義。&lt;/strong&gt;&lt;/blockquote&gt;&lt;h3 id=&quot;投影片世界的比喻&quot;&gt;投影片世界的比喻&lt;/h3&gt;&lt;p&gt;可以把整個畫面想成很多層透明投影片疊在一起。&lt;ul&gt;&lt;li&gt;預設情況下，所有元素都在同一個「大投影片」裡&lt;li&gt;一旦某個元素建立了 stacking context&lt;br&gt;它就變成一疊「自己的小投影片」&lt;/ul&gt;&lt;p&gt;這個小投影片裡面的子元素：&lt;ul&gt;&lt;li&gt;彼此之間可以用 &lt;code&gt;z-index&lt;/code&gt; 排名&lt;li&gt;&lt;strong&gt;但永遠無法跳出這一疊，跟外面的元素比較&lt;/strong&gt;&lt;/ul&gt;&lt;p&gt;也就是說：&lt;ul&gt;&lt;li&gt;子元素的 &lt;code&gt;z-index: 9999&lt;/code&gt;&lt;li&gt;永遠贏不了父層 stacking context 在外部世界的順位&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;記住這句就好：&lt;br&gt;&lt;strong&gt;z-index 不是全域排名，而是「區域內排序」。&lt;/strong&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;z-index-會失效的真正原因&quot;&gt;z-index 會失效的真正原因&lt;/h2&gt;&lt;p&gt;在實務中，&lt;code&gt;z-index&lt;/code&gt; 不聽話通常不是因為你寫錯數字，而是因為你忽略了下面兩件事。&lt;h3 id=&quot;z-index-不是隨便就能用&quot;&gt;z-index 不是隨便就能用&lt;/h3&gt;&lt;p&gt;預設情況下，元素是 &lt;code&gt;position: static&lt;/code&gt;，而這種狀態下：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.badge&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* 不會生效 */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;原因是： static 元素根本不參與層級計算。&lt;p&gt;正確寫法至少要這樣：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.badge&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* 或 absolute / fixed / sticky */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以把它想成： 你必須先「加入層級系統」，才有資格比大小。&lt;h2 id=&quot;父層一旦建立世界,子層就被封印&quot;&gt;父層一旦建立世界，子層就被封印&lt;/h2&gt;&lt;p&gt;當父元素建立 stacking context 時，會發生一件非常關鍵的事：&lt;p&gt;子元素的 z-index，只在這個父世界裡有效。&lt;p&gt;這也是為什麼很多人會遇到：&lt;ul&gt;&lt;li&gt;子元素數字設很大&lt;li&gt;卻還是被外面的元素壓住&lt;/ul&gt;&lt;p&gt;因為瀏覽器實際比較的是：&lt;p&gt;&lt;strong&gt;父層 stacking context vs 父層 stacking context&lt;/strong&gt;&lt;p&gt;而不是你以為的子元素。&lt;h2 id=&quot;哪些情況會建立新的-Stacking-Context&quot;&gt;哪些情況會建立新的 Stacking Context&lt;/h2&gt;&lt;p&gt;你不需要記完整規格，但下面這些是實務中最常踩到的。&lt;h3 id=&quot;常見觸發條件整理&quot;&gt;常見觸發條件整理&lt;/h3&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align:left&quot;&gt;類型&lt;th style=&quot;text-align:left&quot;&gt;會建立 Stacking Context 的情況&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align:left&quot;&gt;定位&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;position: relative / absolute&lt;/code&gt; 且 &lt;code&gt;z-index&lt;/code&gt; 不是 &lt;code&gt;auto&lt;/code&gt;&lt;tr&gt;&lt;td style=&quot;text-align:left&quot;&gt;固定定位&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;position: fixed&lt;/code&gt;、&lt;code&gt;sticky&lt;/code&gt;&lt;tr&gt;&lt;td style=&quot;text-align:left&quot;&gt;視覺效果&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;opacity &amp;lt; 1&lt;/code&gt;、&lt;code&gt;filter&lt;/code&gt; 非 &lt;code&gt;none&lt;/code&gt;&lt;tr&gt;&lt;td style=&quot;text-align:left&quot;&gt;變形&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;transform&lt;/code&gt;（即使只是 &lt;code&gt;translate(0)&lt;/code&gt;）&lt;tr&gt;&lt;td style=&quot;text-align:left&quot;&gt;最安全做法&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;isolation: isolate&lt;/code&gt;&lt;/table&gt;&lt;p&gt;這裡面最容易被忽略的是 &lt;code&gt;transform&lt;/code&gt;，因為它看起來只是動畫用，但實際上會直接改變層級行為。&lt;h2 id=&quot;isolation:-isolate-是救命用的&quot;&gt;isolation: isolate 是救命用的&lt;/h2&gt;&lt;p&gt;如果你希望某個區塊：&lt;ul&gt;&lt;li&gt;內部層級自己處理&lt;li&gt;不影響外部，也不被外部影響&lt;/ul&gt;&lt;p&gt;請直接用：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;isolation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; isolate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這個屬性唯一的目的就是建立 stacking context， 不會順便影響定位、動畫或 layout，非常適合拿來當「防火牆」。&lt;h2 id=&quot;為什麼-z-index:-9999-還是輸&quot;&gt;為什麼 z-index: 9999 還是輸&lt;/h2&gt;&lt;p&gt;這是一個最典型、也最容易誤判的例子。&lt;h3 id=&quot;結構範例&quot;&gt;結構範例&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;header&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  zindex 1
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dropdown&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    zindex 9999
    我是 dropdown
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;sidebar&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  zindex 2
  我是 sidebar
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.header&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.dropdown&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 9999&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.sidebar&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;實際發生了什麼事&quot;&gt;實際發生了什麼事&lt;/h3&gt;&lt;p&gt;你以為 dropdown 會是最上面，實際上不是。&lt;p&gt;瀏覽器不是在比：&lt;ul&gt;&lt;li&gt;dropdown (9999)&lt;li&gt;sidebar (2)&lt;/ul&gt;&lt;p&gt;而是在比：&lt;ul&gt;&lt;li&gt;.header (1)&lt;li&gt;.sidebar (2)&lt;/ul&gt;&lt;p&gt;因為 .dropdown 被鎖在 .header 的世界裡。&lt;p&gt;結果就是：&lt;p&gt;整個 header（包含裡面的 dropdown） 都會被 sidebar 壓在下面&lt;p&gt;這也是為什麼調整 dropdown z-index 永遠沒用。&lt;h2 id=&quot;三個最常見也最痛的實戰坑&quot;&gt;三個最常見、也最痛的實戰坑&lt;/h2&gt;&lt;h3 id=&quot;overflow:-hidden-把浮層切掉&quot;&gt;overflow: hidden 把浮層切掉&lt;/h3&gt;&lt;p&gt;這種情況常見於 card、layout container。&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; hidden&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;即使你的 dropdown 或 tooltip z-index 再高， 只要超出這個容器，就會被裁掉。&lt;p&gt;常見解法有兩種：&lt;ul&gt;&lt;li&gt;把浮層移到不受 overflow 限制的父層&lt;li&gt;直接用 portal，掛到 body&lt;/ul&gt;&lt;p&gt;「Portal」是一種技術手法，讓浮層元素能直接渲染到 body 或其他節點，跳脫原本的 DOM 階層，常用於各種前端框架。 例如：&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://svelte.dev/playground/407576d4fa984cfb97dcdd3da98e833e?version=5.46.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Svelte 官方 Portal 範例&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/romkor/svelte-portal&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;svelte-portal&lt;/a&gt;&lt;/ul&gt;&lt;h3 id=&quot;transform-讓層級突然亂掉&quot;&gt;transform 讓層級突然亂掉&lt;/h3&gt;&lt;p&gt;很多動畫會這樣寫：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.panel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但這行其實已經：&lt;ul&gt;&lt;li&gt;建立新的 stacking context&lt;li&gt;改變 fixed / absolute 的參考行為&lt;/ul&gt;&lt;p&gt;實務建議是：&lt;ul&gt;&lt;li&gt;不要在 layout 最外層用 transform&lt;li&gt;動畫盡量包在最內層元素&lt;/ul&gt;&lt;h3 id=&quot;fixed-不再相對視窗&quot;&gt;fixed 不再相對視窗&lt;/h3&gt;&lt;p&gt;如果某個祖先元素有：&lt;ul&gt;&lt;li&gt;transform&lt;li&gt;filter&lt;li&gt;perspective&lt;/ul&gt;&lt;p&gt;那麼：&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.modal&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fixed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;會變成「相對那個祖先」，而不是瀏覽器視窗。&lt;p&gt;這也是為什麼 modal 明明是 fixed，卻會跟著捲動。&lt;h2 id=&quot;實用的-Debug-思考流程&quot;&gt;實用的 Debug 思考流程&lt;/h2&gt;&lt;p&gt;當你發現層級怪怪的，可以照這個順序檢查。&lt;ul&gt;&lt;li&gt;這個元素有沒有 position？&lt;li&gt;最近的 stacking context 是誰？&lt;li&gt;有沒有祖先用了 transform / opacity / filter？&lt;li&gt;壓住它的元素，父層是誰？&lt;/ul&gt;&lt;p&gt;在 Chrome DevTools 裡：&lt;ul&gt;&lt;li&gt;Elements 面板往上看 computed styles&lt;li&gt;Layers 面板可以直接看到層級分組&lt;/ul&gt;&lt;h2 id=&quot;專案等級的-z-index-管理方式&quot;&gt;專案等級的 z-index 管理方式&lt;/h2&gt;&lt;p&gt;如果沒有規範，最後一定會出現：&lt;p&gt;&lt;code&gt;z-index: 9999999;&lt;/code&gt;&lt;p&gt;建議一開始就定義層級語意。&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-dropdown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 300&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-overlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 900&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-modal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1000&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--z-toast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1100&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用時只用語意，不用數字。&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.modal&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fixed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--z-modal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;最穩定的-Tooltip-/-Modal-解法&quot;&gt;最穩定的 Tooltip / Modal 解法&lt;/h2&gt;&lt;p&gt;如果你真的不想再跟 stacking context 糾纏， 最穩定的方式只有一種：&lt;p&gt;把浮層直接掛在 body 底下。&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;btn&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hover&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;tip&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;tip&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Safe tooltip&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.tip&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fixed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--z-toast&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;pointer-events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; btn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;#btn&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;#tip&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

btn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mouseenter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; btn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBoundingClientRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  tip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  tip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottom &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  tip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;classList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;show&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這也是大多數 UI library 採用的做法。&lt;h2 id=&quot;總結&quot;&gt;總結&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;z-index 不是全域排序&lt;li&gt;stacking context 才是真正的邊界&lt;li&gt;父層層級決定一切&lt;li&gt;浮層想省事，直接走 portal&lt;/ul&gt;&lt;p&gt;只要你開始用「世界」來思考層級問題， z-index 就再也不會無止盡的 999999...。</content>
  </entry>
  <entry>
    <title>在 Eleventy（11ty）整合 Pagefind：回到「最簡單」的做法</title>
    <link href="https://kamadiam.com/eleventy-pagefind-simple-approach/" />
    <updated>2025-12-26T00:00:00Z</updated>
    <id>https://kamadiam.com/eleventy-pagefind-simple-approach/</id>
    <content type="html">&lt;p&gt;在把網站從 WordPress 搬到 11ty 之後，一直在研究一件事情，就是如果沒有了後端程式，也沒有資料庫，該怎麼做站內搜尋，Google Programmable Search Engine 也可以，但就走走看看有沒有別的選擇。&lt;p&gt;參考其他的 11ty 網站發現還蠻多人在用 Pagefind，而且這個工具是任何網頁架構都可以使用，不是只支持 11ty。&lt;p&gt;Pagefind 是為「靜態網站」設計的全文搜尋工具，不需要後端、不需要資料庫，搜尋全在前端完成。&lt;p&gt;而且老實說，Pagefind 本身真的不難。 難的是：一開始我完全用錯方式在理解它。&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E4%B8%80%E9%96%8B%E5%A7%8B%E7%9A%84%E8%AA%A4%E6%9C%83:%E6%8A%8A-Pagefind-%E7%95%B6%E6%88%90%E3%80%8C%E4%B8%80%E8%88%AC%E5%89%8D%E7%AB%AF%E5%A5%97%E4%BB%B6%E3%80%8D&quot;&gt;一開始的誤會：把 Pagefind 當成「一般前端套件」&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E6%8F%9B%E5%80%8B%E6%83%B3%E6%B3%95:Pagefind-%E5%8F%AA%E9%9C%80%E8%A6%81%E5%81%9A%E4%B8%80%E4%BB%B6%E4%BA%8B%E5%B0%B1%E5%A5%BD&quot;&gt;換個想法：Pagefind 只需要做一件事就好&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-1:%E7%9B%B4%E6%8E%A5-include-Pagefind-%E7%94%A2%E7%94%9F%E7%9A%84-CSS-/-JS&quot;&gt;Step 1：直接 include Pagefind 產生的 CSS / JS&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-2:%E6%94%BE%E4%B8%80%E5%80%8B%E6%90%9C%E5%B0%8B%E6%AC%84%E4%BD%8D%E5%AE%B9%E5%99%A8&quot;&gt;Step 2：放一個搜尋欄位容器&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-3:%E6%A8%99%E8%A8%98%E3%80%8C%E7%9C%9F%E6%AD%A3%E8%A6%81%E8%A2%AB%E6%90%9C%E5%B0%8B%E7%9A%84%E5%85%A7%E5%AE%B9%E3%80%8D&quot;&gt;Step 3：標記「真正要被搜尋的內容」&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-4:%E5%88%9D%E5%A7%8B%E5%8C%96-PagefindUI&quot;&gt;Step 4：初始化 PagefindUI&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-5:%E5%BB%BA%E7%B4%A2%E5%BC%95(%E9%80%99%E8%A1%8C%E6%89%8D%E6%98%AF-Pagefind-%E7%9A%84%E6%9C%AC%E9%AB%94)&quot;&gt;Step 5：建索引（這行才是 Pagefind 的本體）&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Step-6:%E6%94%B6%E9%80%B2-package.json&quot;&gt;Step 6：收進 package.json&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E6%9C%80%E5%BE%8C:%E4%B8%8A%E5%82%B3&quot;&gt;最後：上傳&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E9%80%B2%E9%9A%8E%E8%A3%9C%E5%85%85&quot;&gt;進階補充&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Pagefind-%C3%97-Barba.js-%E5%88%87%E9%A0%81%E6%99%82%E8%A6%81%E6%B3%A8%E6%84%8F%E7%9A%84%E4%BA%8B&quot;&gt;Pagefind × Barba.js 切頁時要注意的事&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E5%93%AA%E4%BA%9B%E9%A0%81%E9%9D%A2%E3%80%8C%E4%B8%8D%E8%A9%B2%E8%A2%AB%E6%90%9C%E5%B0%8B%E3%80%8D&quot;&gt;哪些頁面「不該被搜尋」&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#Pagefind-%E7%9A%84%E6%90%9C%E5%B0%8B%E5%93%81%E8%B3%AA,%E5%85%B6%E5%AF%A6%E5%8F%96%E6%B1%BA%E6%96%BC%E4%BD%A0%E7%9A%84-HTML-%E7%B5%90%E6%A7%8B&quot;&gt;Pagefind 的搜尋品質，其實取決於你的 HTML 結構&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-pagefind-simple-approach/#%E7%B5%90%E8%AA%9E&quot;&gt;結語&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id=&quot;一開始的誤會:把-Pagefind-當成「一般前端套件」&quot;&gt;一開始的誤會：把 Pagefind 當成「一般前端套件」&lt;/h2&gt;&lt;p&gt;最一開始，我直覺用熟悉的方式來：&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pnpm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; pagefind&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然後開始想：&lt;ul&gt;&lt;li&gt;CSS 要怎麼 include？&lt;li&gt;JS 要不要丟進 Vite？&lt;li&gt;要不要跟 11ty build 流程整合？&lt;li&gt;能不能 build 完 HTML 就自動跑 Pagefind？&lt;/ul&gt;&lt;p&gt;於是開始把 Pagefind 拉進前端打包流程、寫 script、試著「一次 build 全部搞定」。&lt;p&gt;結果就是： 流程越來越複雜、錯誤越來越難 debug。&lt;p&gt;到這裡才意識到一件事——&lt;p&gt;Pagefind 不是前端套件，它是「建索引的工具」。&lt;p&gt;所以我又執行了&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pnpm&lt;/span&gt; remove pagefind&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;換個想法:Pagefind-只需要做一件事就好&quot;&gt;換個想法：Pagefind 只需要做一件事就好&lt;/h2&gt;&lt;p&gt;我完全換了一個角度：&lt;p&gt;11ty 就負責把 HTML 生出來 Pagefind 只負責「讀這些 HTML，建立搜尋索引」&lt;p&gt;只要守住這個界線，事情瞬間變得很單純。&lt;h3 id=&quot;Step-1:直接-include-Pagefind-產生的-CSS-/-JS&quot;&gt;Step 1：直接 include Pagefind 產生的 CSS / JS&lt;/h3&gt;&lt;p&gt;Pagefind 在建索引時，會自動產生 /pagefind/ 資料夾，裡面就包含 UI 所需的檔案。&lt;p&gt;所以什麼 bundler 都不要碰，直接 include：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/pagefind/pagefind-ui.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/pagefind/pagefind-ui.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;Step-2:放一個搜尋欄位容器&quot;&gt;Step 2：放一個搜尋欄位容器&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;search&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;Step-3:標記「真正要被搜尋的內容」&quot;&gt;Step 3：標記「真正要被搜尋的內容」&lt;/h3&gt;&lt;p&gt;這一步非常重要，也是 Pagefind 最好用的地方之一。&lt;p&gt;記得在文章內容外層加上：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-pagefind-body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  {{ content | safe }}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這代表：&lt;ul&gt;&lt;li&gt;Pagefind 只會索引這個區塊內的文字&lt;li&gt;header、footer、選單、側邊欄都不會被吃進搜尋結果&lt;li&gt;搜尋結果乾淨很多&lt;/ul&gt;&lt;p&gt;（也要注意：一旦用了 data-pagefind-body，沒有加這個 attribute 的頁面就不會被索引，這通常是好事。）&lt;h3 id=&quot;Step-4:初始化-PagefindUI&quot;&gt;Step 4：初始化 PagefindUI&lt;/h3&gt;&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PagefindUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;showSubResults&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;到這一步，前端其實就已經準備好了。&lt;h3 id=&quot;Step-5:建索引(這行才是-Pagefind-的本體)&quot;&gt;Step 5：建索引（這行才是 Pagefind 的本體）&lt;/h3&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pnpm&lt;/span&gt; dlx pagefind &lt;span class=&quot;token parameter variable&quot;&gt;--site&lt;/span&gt; _site &lt;span class=&quot;token parameter variable&quot;&gt;--glob&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;**/*.html&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;重點只有兩個：&lt;ul&gt;&lt;li&gt;_site：11ty build 出來的資料夾&lt;li&gt;**/*.html：全部 HTML 都拿來建索引&lt;/ul&gt;&lt;p&gt;跑完之後，你會看到 _site/pagefind/ 被建立起來。&lt;h3 id=&quot;Step-6:收進-package.json&quot;&gt;Step 6：收進 package.json&lt;/h3&gt;&lt;p&gt;build 11ty site 和建立搜尋索引拆開：&lt;pre class=&quot;language-json&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NODE_ENV=production ELEVENTY_PROFILE=true pnpm exec eleventy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build:pagefind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;pnpm dlx pagefind --site _site --glob &#92;&quot;**/*.html&#92;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;為什麼？&lt;p&gt;因為這樣：&lt;ul&gt;&lt;li&gt;出問題很好 debug&lt;li&gt;不會搞混是 11ty 還是 Pagefind 壞掉&lt;li&gt;想自動化，之後再加一行 pnpm build &amp;amp;&amp;amp; pnpm build:pagefind 就好&lt;/ul&gt;&lt;h3 id=&quot;最後:上傳&quot;&gt;最後：上傳&lt;/h3&gt;&lt;p&gt;只要你的部署流程會把 _site/pagefind/ 一起上傳，搜尋就能直接在純靜態網站上跑起來。&lt;p&gt;不用 server、不用 API、不用資料庫。&lt;p&gt;結束了嗎，對啊，就醬。&lt;h2 id=&quot;進階補充&quot;&gt;進階補充&lt;/h2&gt;&lt;h3 id=&quot;Pagefind-×-Barba.js-切頁時要注意的事&quot;&gt;Pagefind × Barba.js 切頁時要注意的事&lt;/h3&gt;&lt;p&gt;如果你跟我一樣，網站有用 Barba.js 做 PJAX / page transition，那你幾乎一定會踩到這個坑。&lt;p&gt;問題是什麼？&lt;p&gt;PagefindUI 預設會在：DOMContentLoaded 時初始化。&lt;p&gt;但 Barba 切頁時：&lt;ul&gt;&lt;li&gt;不會重新載入整個頁面&lt;li&gt;#search 這個 DOM 可能被重建&lt;li&gt;PagefindUI 早就綁在舊的 DOM 上了&lt;/ul&gt;&lt;p&gt;結果就是：&lt;ul&gt;&lt;li&gt;搜尋框還在&lt;li&gt;但點了沒反應，或結果怪怪的&lt;/ul&gt;&lt;p&gt;最穩的做法：切頁後重新初始化&lt;p&gt;概念只有一句話：&lt;p&gt;只要搜尋欄位被重新 render，就重建 PagefindUI&lt;p&gt;範例（Barba hooks）：&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pagefindInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initPagefind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; searchEl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;searchEl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 避免重複初始化&lt;/span&gt;
  searchEl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  pagefindInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PagefindUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;showSubResults&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; initPagefind&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

barba&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hooks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;afterEnter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;initPagefind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這樣做的好處：&lt;ul&gt;&lt;li&gt;不管是不是 PJAX 切頁&lt;li&gt;只要 #search 出現，就一定能用&lt;li&gt;不會卡在奇怪的「第一次正常，之後失效」&lt;/ul&gt;&lt;h3 id=&quot;哪些頁面「不該被搜尋」&quot;&gt;哪些頁面「不該被搜尋」&lt;/h3&gt;&lt;p&gt;Pagefind 很貼心的一點是：你可以選擇性讓頁面完全不進索引。&lt;p&gt;情境舉例&lt;ul&gt;&lt;li&gt;標籤列表頁&lt;li&gt;分頁頁面（page/2、page/3）&lt;li&gt;純導覽頁、實驗頁&lt;li&gt;404 / redirect 頁&lt;/ul&gt;&lt;p&gt;作法一：根本不加 data-pagefind-body&lt;p&gt;只有「文章內容」才包：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-pagefind-body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  {{ content | safe }}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;其他頁面自然就被排除。&lt;p&gt;作法二：明確標記「不要索引」&lt;p&gt;如果你有某些頁面「結構很像文章，但不該被搜」，可以加：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-pagefind-ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或包在區塊上：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-pagefind-ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  ...
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這在做實驗頁、A/B test、或 draft 頁面時很有用。&lt;h3 id=&quot;Pagefind-的搜尋品質,其實取決於你的-HTML-結構&quot;&gt;Pagefind 的搜尋品質，其實取決於你的 HTML 結構&lt;/h3&gt;&lt;p&gt;Pagefind 不是魔法，它完全相信你的 HTML。&lt;p&gt;所以這幾件事，會直接影響搜尋結果好不好用：&lt;p&gt;1️⃣ 標題階層很重要&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;文章標題&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;段落標題&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;小節&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pagefind 會用這些來：&lt;ul&gt;&lt;li&gt;判斷內容結構&lt;li&gt;顯示搜尋結果摘要&lt;/ul&gt;&lt;p&gt;亂用 div + class，搜尋結果就會很扁平。&lt;p&gt;2️⃣ 不要把整篇文章塞進奇怪的 wrapper&lt;p&gt;例如：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;prose&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        {{ content }}
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這不是不行，但層級越乾淨，搜尋摘要越好看。&lt;p&gt;3️⃣ Code block 其實會被索引（而且有時很棒）&lt;p&gt;這點對技術部落格來說是加分：&lt;ul&gt;&lt;li&gt;指令&lt;li&gt;API 名稱&lt;li&gt;錯誤訊息&lt;/ul&gt;&lt;p&gt;都能被搜到。&lt;p&gt;如果你真的不想讓 code block 被搜，再局部加 data-pagefind-ignore 即可。&lt;h2 id=&quot;結語&quot;&gt;結語&lt;/h2&gt;&lt;p&gt;Pagefind 不複雜，複雜的是我們一開始就想把它變得很複雜，難的是「想一次做到太完美」&lt;p&gt;對我來說，現在這套流程剛剛好：&lt;ul&gt;&lt;li&gt;好理解&lt;li&gt;好 debug&lt;li&gt;出問題也知道在哪一段&lt;/ul&gt;&lt;p&gt;回頭看，其實整個流程只有一句話：&lt;p&gt;HTML 先 build 好，Pagefind 再來掃。&lt;p&gt;一開始是想把它「工程化」、自動化、整合到所有流程裡； 但對假設網站這件事來說，簡單、穩定，才是最重要的。不然就是回復備份流程做得快又方便也是 OK 的啦。&lt;p&gt;(靜態網站不管是備份還是回復舊版本都超方便的啦，一點都不害怕弄壞了什麼)</content>
  </entry>
  <entry>
    <title>在 Eleventy（11ty）文章中做出像 WordPress 的 Feature Image 特色圖片</title>
    <link href="https://kamadiam.com/eleventy-feature-image-wordpress-style/" />
    <updated>2025-12-24T00:00:00Z</updated>
    <id>https://kamadiam.com/eleventy-feature-image-wordpress-style/</id>
    <content type="html">&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E7%9B%AE%E6%A8%99%E6%95%88%E6%9E%9C&quot;&gt;目標效果&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E6%AD%A5%E9%A9%9F-1:%E5%9C%A8%E6%AF%8F%E7%AF%87%E6%96%87%E7%AB%A0-frontmatter-%E5%8A%A0%E4%B8%8A-feature-image-%E8%A8%AD%E5%AE%9A&quot;&gt;步驟 1：在每篇文章 frontmatter 加上 feature image 設定&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E6%AD%A5%E9%A9%9F-2:%E5%9C%A8-post.njk-%E5%8A%A0%E5%85%A5%E6%A2%9D%E4%BB%B6%E9%82%8F%E8%BC%AF&quot;&gt;步驟 2：在 post.njk 加入條件邏輯&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E6%AD%A5%E9%A9%9F-3:%E5%A5%97%E7%94%A8-CSS,%E5%81%9A%E5%87%BA%E3%80%8C%E8%A3%82%E6%88%90%E5%9B%9B%E5%A1%8A%E3%80%8D%E7%9A%84%E6%A0%B8%E5%BF%83%E6%95%88%E6%9E%9C&quot;&gt;步驟 3：套用 CSS，做出「裂成四塊」的核心效果&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#CSS-%E6%8A%80%E8%A1%93%E5%AF%A6%E4%BD%9C%E5%8E%9F%E7%90%86&quot;&gt;CSS 技術實作原理&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E4%B8%80%E5%BC%B5%E5%9C%96%E5%88%87%E5%9B%9B%E5%A1%8A,%E4%B8%8D%E9%9C%80%E8%A6%81%E5%9B%9B%E5%BC%B5%E5%9C%96%E7%89%87&quot;&gt;一張圖切四塊，不需要四張圖片&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E7%82%BA%E4%BB%80%E9%BA%BC%E5%8B%95%E7%95%AB%E5%8F%AA%E7%94%A8-transform?&quot;&gt;為什麼動畫只用 transform？&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/eleventy-feature-image-wordpress-style/#%E6%9C%80%E5%BE%8C:%E6%95%B4%E5%90%88%E5%88%B0-11ty-%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F&quot;&gt;最後：整合到 11ty 的使用方式&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;從 WordPress 搬家到 11ty 之後，有個想保留的一個使用體驗，就是：&lt;p&gt;&lt;strong&gt;每篇文章可以在文章開頭放一張「feature image」&lt;/strong&gt;，並且順手帶出文章摘要，或一些有趣文字。&lt;p&gt;WordPress 裡這件事很自然；到了 11ty，就要自己定規格、自己做模板與樣式。&lt;p&gt;這篇文章分享我現在採用的做法：&lt;p&gt;在 frontmatter 先定義一些資料格式~&lt;ul&gt;&lt;li&gt;放 feature_image（圖片路徑）&lt;li&gt;放 feature_meta_text（文章摘要/或一段簡單文字）&lt;li&gt;放 use_feature_split（要不要啟用 Hover 特效）&lt;/ul&gt;&lt;p&gt;你可以把它當成「像 WordPress 一樣的特色圖片機制」，只是更自由、更可控。&lt;hr&gt;&lt;h2 id=&quot;目標效果&quot;&gt;目標效果&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;一般模式（預設）&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;文章開頭顯示靜態 feature image&lt;/ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;特效模式（可選）&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;hover 時 feature image 裂成四塊飛散&lt;li&gt;同時顯示文章資訊文字（feature_meta_text）&lt;/ul&gt;&lt;/ol&gt;&lt;hr&gt;&lt;h3 id=&quot;步驟-1:在每篇文章-frontmatter-加上-feature-image-設定&quot;&gt;步驟 1：在每篇文章 frontmatter 加上 feature image 設定&lt;/h3&gt;&lt;p&gt;參考如下 frontmatter 範例：&lt;pre class=&quot;language-yml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 文章標題&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 從 WordPress 搬家到 Eleventy（11ty）：你一定會遇到的幾個注意事項整理

&lt;span class=&quot;token comment&quot;&gt;# 文章描述（常用在 SEO、OpenGraph、列表摘要）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 從 WordPress 搬家到 Eleventy 靜態網站生成器的完整指南，整理了遷移過程中常見的注意事項、坑洞與解決方案。包含內容匯出、圖片處理、前端框架整合等實戰經驗分享。

&lt;span class=&quot;token comment&quot;&gt;# Feature image：文章開頭的主圖（你用相對路徑）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;feature_image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../img/feature-images/11ty-notes.png&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 是否啟用「裂開 hover 特效」&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# false = 用一般 &amp;lt;img&gt; 呈現&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# true  = 用特效版本（四塊碎片 + 文字）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;use_feature_split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 特效模式時要顯示的文章資訊文字（簡短、像副標）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;feature_meta_text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; WordPress 到 Eleventy 的遷移之旅

&lt;span class=&quot;token comment&quot;&gt;# 發佈時間（用 ISO 格式很標準）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token datetime number&quot;&gt;2025-12-22T10:00:00.000Z&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# metadata 結構（分類、文章型態、canonical url）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 架設網站
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 靜態網站生成器
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wordpress&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;migration
  &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; https&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//kamadiam.com/wordpress&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;eleventy&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;migration/

&lt;span class=&quot;token comment&quot;&gt;# tags（文章標籤）&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; wordpress
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; eleventy
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 11ty
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 靜態網站
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 網站搬家
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 遷移指南
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 前端開發
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 網站優化

&lt;span class=&quot;token comment&quot;&gt;# 指定 Markdown 的模板引擎, 可以避免不同程式語法衝突&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;templateEngineOverride&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; md
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;frontmatter 可以很簡單的自定義資料格式，可以控制文章的顯示或行為。&lt;ul&gt;&lt;li&gt;feature_meta_text 建議保持「一句話」即可，越短越像 WordPress 的「精選摘要」&lt;li&gt;use_feature_split 預設 false，要用特效的文章再開即可，這個是額外加入的小趣味。&lt;/ul&gt;&lt;hr&gt;&lt;h3 id=&quot;步驟-2:在-post.njk-加入條件邏輯&quot;&gt;步驟 2：在 post.njk 加入條件邏輯&lt;/h3&gt;&lt;p&gt;修改的主要邏輯是：&lt;ul&gt;&lt;li&gt;如果 &lt;strong&gt;feature_image&lt;/strong&gt; 存在 → 即顯示 feature image &lt;img&gt;&lt;li&gt;如果 &lt;strong&gt;use_feature_split&lt;/strong&gt; 且 &lt;strong&gt;feature_image&lt;/strong&gt; 存在 → feature image 要加上特效&lt;/ul&gt;&lt;p&gt;請參考範例，（PS:nunjucks 註解格式為 {# ... #}） ：&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 
&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;
  Feature image 渲染入口：
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; use_feature_split &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;  → 顯示裂開特效版本
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; use_feature_split &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; → 顯示一般 &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; 
#&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 這裏是特效模式：需要 use_feature_split&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; 且有 feature_image #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; use_feature_split and feature_image &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 你自訂的 filter：把 frontmatter 的相對路徑，解析成可用的 &lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt; #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; resolvedImagePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feature_image &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; resolveImagePath &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 確保解析成功才渲染，避免 broken image #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; resolvedImagePath &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;feature-wrap&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# figure：使用 &lt;span class=&quot;token constant&quot;&gt;CSS&lt;/span&gt; 變數 &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;img 把圖片 &lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt; 傳給 &lt;span class=&quot;token constant&quot;&gt;CSS&lt;/span&gt; #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;figure
        &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;feature-split&quot;&lt;/span&gt;
        aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Article feature image&quot;&lt;/span&gt;
        style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;--img: url(&#39;{{ resolvedImagePath }}&#39;)&quot;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 視覺底座：提供圓角&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;背景框（因為不使用 overflow hidden） #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;feature-frame&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;hidden&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 四塊碎片：四個 span 用同一張圖切成 2x2 #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tiles&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;hidden&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tile t1&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tile t2&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tile t3&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tile t4&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 底部文字資訊：如果有 feature_meta_text 才顯示 #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; feature_meta_text &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;feature-text&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; feature_meta_text &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; endif &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;figure&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; endif &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 這裏是一般模式：有 feature_image 就用普通 img #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; elif feature_image &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;# 這裡直接用 feature_image（相對路徑）顯示圖片 #&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;img
    src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{{ feature_image }}&quot;&lt;/span&gt;
    alt&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Feature image for {{ title }}&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;post-feature-image&quot;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; endif &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;&lt;h3 id=&quot;步驟-3:套用-CSS,做出「裂成四塊」的核心效果&quot;&gt;步驟 3：套用 CSS，做出「裂成四塊」的核心效果&lt;/h3&gt;&lt;p&gt;效果就是自由發揮，如果不想只是顯示一張圖，讓文章有趣一點，或是埋藏彩蛋，可以自由修改 html 搭配 css 展現特別效果。&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  feature-wrap：用 padding + 負 margin 擴大 hover 觸發區域
  目的：讓滑鼠不要一定得壓在圖片上，稍微靠近也能觸發
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.feature-wrap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 擴大 hover 區域（包含圖片周圍） */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-2xl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 用負 margin 把版面位置「抵回來」，避免整體被撐大 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-2xl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  feature-split：核心容器（不裁切，碎片可以飛出去）
  --img：圖片 URL（由 inline style 傳進來）
  --radius：圓角
  --spread：裂開距離
  --lift：hover 上浮高度
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.feature-split&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--img&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string url&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-3xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--spread&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--lift&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;aspect-ratio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16 / 9&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* ✅ 不裁切：碎片可以飛出原本框 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; visible&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 初始位置明確指定 translateY(0)，避免 hover 回彈視覺跳一下 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateZ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 只讓 transform 動畫（效能最好） */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transform 620ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  feature-frame：視覺底座
  因為 overflow 沒有 hidden，不能靠裁切做圓角
  所以用這層提供背景/邊框/圓角，讓「合起來」時像一張完整圖
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.feature-frame&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--neutral-color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;pointer-events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  tiles：四塊碎片的容器
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.tiles&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  tile：單一碎片
  技術重點：
  - 每塊 50% x 50%
  - 背景圖放大成 200% 200%（因為只顯示四分之一）
  - 用 background-position 決定顯示哪一個象限
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.tile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* ✅ 同一張圖，放大兩倍再切成四塊 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--img&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; center / 200% 200% no-repeat&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-3xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 合起來時不顯示邊框，裂開時才顯示（避免抖動就用 transition） */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1px solid transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .22&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* ✅ 動畫只做 transform/filter/opacity/border-color（效能好） */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    transform 620ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    filter 620ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    opacity 620ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    border-color 620ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;will-change&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transform&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;backface-visibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; hidden&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  四塊的位置與對應的背景象限
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.t1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token property&quot;&gt;background-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.t2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;background-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100% 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.t3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;background-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.t4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;background-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100% 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  feature-text：hover 時顯示的文字資訊
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.feature-text&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 初始略縮小 + 隱藏 */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-50%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; -50%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0.9&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transform 520ms &lt;span class=&quot;token function&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .85&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; opacity 520ms ease&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;pointer-events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--text-color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--step--1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 500&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;letter-spacing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .2px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.6&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;text-align&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nowrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .92&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;backdrop-filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blur&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;12px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1px solid &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--color-gray-20&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-2xl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; .15&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-2xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--space-2xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 80%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;/* ============================================================
  Hover 動畫（只在支援 hover 的裝置上）
============================================================ */&lt;/span&gt;
&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;hover&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; hover&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;pointer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fine&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 容器上浮（你同時支援 feature-wrap:hover 與 figure:hover） */&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split,
  .feature-split:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--lift&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateZ&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 四塊向四個方向飛散 + 旋轉 */&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .t1,
  .feature-split:hover .t1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-4deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .t2,
  .feature-split:hover .t2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;4deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .t3,
  .feature-split:hover .t3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;3deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .t4,
  .feature-split:hover .t4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--spread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-3deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 碎片顏色更有精神 + 裂開時顯示邊框 */&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .tile,
  .feature-split:hover .tile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brightness&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.92&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saturate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.12&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;contrast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.03&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;border-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--color-gray-20&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 裂縫光出現 */&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .crack,
  .feature-split:hover .crack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* 文字卡片縮放淡入 */&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.feature-wrap:hover .feature-split .feature-text,
  .feature-split:hover .feature-text&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-50%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; -50%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;&lt;h2 id=&quot;CSS-技術實作原理&quot;&gt;CSS 技術實作原理&lt;/h2&gt;&lt;h3 id=&quot;一張圖切四塊,不需要四張圖片&quot;&gt;一張圖切四塊，不需要四張圖片&lt;/h3&gt;&lt;p&gt;每個 .tile 都是同一張背景圖：&lt;ul&gt;&lt;li&gt;tile 本身只有 50% × 50%&lt;li&gt;但背景圖用 200% 200% 放大&lt;li&gt;然後用 background-position 指定顯示哪個象限&lt;/ul&gt;&lt;p&gt;所以你只要準備 &lt;strong&gt;一張 feature image&lt;/strong&gt;，就能切出四塊。&lt;h3 id=&quot;為什麼動畫只用-transform?&quot;&gt;為什麼動畫只用 transform？&lt;/h3&gt;&lt;p&gt;transform（位移/旋轉/縮放）通常可以走 GPU 合成層，效能最好。&lt;p&gt;如果你用 top/left 去動，瀏覽器比較容易重新排版，會卡。&lt;hr&gt;&lt;h2 id=&quot;最後:整合到-11ty-的使用方式&quot;&gt;最後：整合到 11ty 的使用方式&lt;/h2&gt;&lt;p&gt;你的使用方式會長這樣：&lt;ul&gt;&lt;li&gt;一般文章（不需要特效）：use_feature_split: false&lt;li&gt;特別文章（想要效果）：use_feature_split: true&lt;/ul&gt;&lt;p&gt;在 11ty 只要維持一致的 frontmatter key，就能像 WordPress 一樣「每篇都有封面」，而且還能加進你的個人風格（裂開特效、資訊卡片、系列標籤都能玩）。&lt;p&gt;另外 &lt;strong&gt;手機沒有 hover，可以改成「進入視窗」才顯示文字&lt;/strong&gt;，利用 IntersectionObserver 加 style class。&lt;p&gt;以上範例也可以獨立拆成獨立檔案例如 feature_image.njk，讓 post.njk 只要 {% include &amp;quot;feature_image.njk&amp;quot; %} 一行，管理 layout 更省心力。</content>
  </entry>
  <entry>
    <title>從 WordPress 搬家到 Eleventy（11ty）：你一定會遇到的幾個注意事項整理</title>
    <link href="https://kamadiam.com/wordpress-to-eleventy-migration-notes/" />
    <updated>2025-12-22T10:00:00Z</updated>
    <id>https://kamadiam.com/wordpress-to-eleventy-migration-notes/</id>
    <content type="html">&lt;p&gt;WordPress 轉移到 Eleventy（11ty），表面上是「內容匯出＋Markdown 重建」，但實際動手後會發現，&lt;strong&gt;模板語法、網址結構、圖片路徑、建置流程&lt;/strong&gt;，每一項都有細節要顧。&lt;p&gt;這篇文章不是介紹 11ty 是什麼，而是整理我在實際 migrate 過程中，&lt;strong&gt;真的踩到、也真的解掉的幾個坑&lt;/strong&gt;。&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#Svelte-%E8%AA%9E%E6%B3%95%E8%88%87-Nunjucks-%E8%A1%9D%E7%AA%81:%E7%82%BA%E4%BB%80%E9%BA%BC%E6%9C%83%E7%AA%81%E7%84%B6-build-%E5%A4%B1%E6%95%97?&quot;&gt;Svelte 語法與 Nunjucks 衝突：為什麼會突然 build 失敗？&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%95%8F%E9%A1%8C%E6%83%85%E5%A2%83&quot;&gt;問題情境&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E8%A7%A3%E6%B3%95:%E4%BD%BF%E7%94%A8-{%-raw-%}-%E8%88%87-{%-endraw-%}-%E5%8C%85%E8%B5%B7%E4%BE%86&quot;&gt;解法：使用 {% raw %} 與 {% endraw %} 包起來&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%8F%A6%E4%B8%80%E7%A8%AE%E8%A7%A3%E6%B3%95:%E7%9B%B4%E6%8E%A5%E9%81%BF%E9%96%8B-Nunjucks&quot;&gt;另一種解法：直接避開 Nunjucks&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E7%B6%B2%E5%9D%80%E7%B5%90%E6%A7%8B%E8%AA%BF%E6%95%B4&quot;&gt;網址結構調整&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E9%A0%90%E8%A8%AD%E8%A1%8C%E7%82%BA%E7%9A%84%E5%95%8F%E9%A1%8C&quot;&gt;預設行為的問題&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E8%A7%A3%E6%B3%95:%E4%BD%BF%E7%94%A8-permalink-%E8%A6%86%E5%AF%AB&quot;&gt;解法：使用 permalink 覆寫&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%9C%96%E7%89%87%E8%B7%AF%E5%BE%91%E4%B8%80%E5%AE%9A%E6%9C%83%E5%A3%9E:WordPress-%E5%8C%AF%E5%87%BA%E5%BE%8C%E4%BD%A0%E8%A6%81%E8%87%AA%E5%B7%B1%E6%94%B9&quot;&gt;圖片路徑一定會壞：WordPress 匯出後你要自己改&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%B8%B8%E8%A6%8B%E7%8B%80%E6%B3%81&quot;&gt;常見狀況&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E8%A7%A3%E6%B3%95:%E7%B5%B1%E4%B8%80%E8%AA%BF%E6%95%B4%E6%88%90%E4%BD%A0%E5%AF%A6%E9%9A%9B%E7%9A%84%E5%9C%96%E7%89%87%E7%9B%AE%E9%8C%84&quot;&gt;解法：統一調整成你實際的圖片目錄&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%A6%82%E4%BD%95%E8%B7%B3%E9%81%8E%E4%B8%8D%E6%83%B3-build-%E7%9A%84%E6%96%87%E7%AB%A0(Draft-%E6%A9%9F%E5%88%B6)&quot;&gt;如何跳過不想 build 的文章（Draft 機制）&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%9C%A8-frontmatter-%E6%A8%99%E8%A8%98&quot;&gt;在 frontmatter 標記&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E5%9C%A8-Eleventy-%E8%A8%AD%E5%AE%9A%E4%B8%AD%E7%B5%B1%E4%B8%80%E8%99%95%E7%90%86-Draft&quot;&gt;在 Eleventy 設定中統一處理 Draft&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-to-eleventy-migration-notes/#%E7%B5%90%E8%AA%9E:%E6%90%AC%E5%AE%B6%E4%B8%8D%E6%98%AF%E4%B8%80%E6%AC%A1%E6%80%A7%E5%B7%A5%E4%BD%9C,%E8%80%8C%E6%98%AF%E4%B8%80%E6%AE%B5%E6%95%B4%E7%90%86%E9%81%8E%E7%A8%8B&quot;&gt;結語：搬家不是一次性工作，而是一段整理過程&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id=&quot;Svelte-語法與-Nunjucks-衝突:為什麼會突然-build-失敗?&quot;&gt;&lt;strong&gt;Svelte 語法與 Nunjucks 衝突：為什麼會突然 build 失敗？&lt;/strong&gt;&lt;/h2&gt;&lt;h3 id=&quot;問題情境&quot;&gt;&lt;strong&gt;問題情境&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;如果你像我一樣，文章中會放一些 &lt;strong&gt;Svelte / 前端框架的範例碼&lt;/strong&gt;，很快就會遇到這個錯誤：&lt;ul&gt;&lt;li&gt;{#if}&lt;li&gt;{#each}&lt;li&gt;{variable}&lt;/ul&gt;&lt;p&gt;👉 &lt;strong&gt;11ty 會誤以為這是 Nunjucks 語法&lt;/strong&gt;&lt;p&gt;導致：&lt;ul&gt;&lt;li&gt;build 直接報錯&lt;li&gt;或輸出的 HTML 被吃掉一部分&lt;/ul&gt;&lt;h3 id=&quot;解法:使用-{%-raw-%}-與-{%-endraw-%}-包起來&quot;&gt;&lt;strong&gt;解法：使用&lt;/strong&gt; &lt;strong&gt;{% raw %}&lt;/strong&gt; &lt;strong&gt;與&lt;/strong&gt; &lt;strong&gt;{% endraw %}&lt;/strong&gt; &lt;strong&gt;包起來&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;這是最直覺、也最安全的方法。&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;{% raw %}
{#if isOpen}
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;menu&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hello&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
{/if}
{% endraw %}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;📌 &lt;strong&gt;適合情境&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;教學文章&lt;li&gt;Code block 很多&lt;li&gt;不想動全站設定&lt;/ul&gt;&lt;p&gt;📌 &lt;strong&gt;缺點&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;要記得包&lt;li&gt;寫文章時稍微打斷思路&lt;/ul&gt;&lt;hr&gt;&lt;h3 id=&quot;另一種解法:直接避開-Nunjucks&quot;&gt;另一種解法：直接避開 Nunjucks&lt;/h3&gt;&lt;p&gt;如果你某些文章 &lt;strong&gt;完全不需要 Nunjucks 功能&lt;/strong&gt;，其實可以選擇「不讓它解析」。&lt;p&gt;在該篇 Markdown 的 frontmatter 加上：&lt;pre class=&quot;language-yml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;templateEngineOverride&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; md&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這代表：&lt;ul&gt;&lt;li&gt;這篇文章 &lt;strong&gt;只用 Markdown&lt;/strong&gt;&lt;li&gt;不經過 Nunjucks 處理&lt;/ul&gt;&lt;p&gt;📌 &lt;strong&gt;適合情境&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;純技術筆記&lt;li&gt;大量前端框架語法&lt;li&gt;不需要 layout 邏輯的文章&lt;/ul&gt;&lt;p&gt;📌 &lt;strong&gt;注意&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;{{ }}、{% %} 全都會被當純文字&lt;li&gt;不適合需要動態資料的頁面&lt;/ul&gt;&lt;hr&gt;&lt;h2 id=&quot;網址結構調整&quot;&gt;&lt;strong&gt;網址結構調整&lt;/strong&gt;&lt;/h2&gt;&lt;h3 id=&quot;預設行為的問題&quot;&gt;&lt;strong&gt;預設行為的問題&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;使用官方 starter 或 blog 範例時，文章通常會變成：&lt;pre&gt;&lt;code&gt;/blog/your-article/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但很多從 WordPress 搬來的人會希望：&lt;pre&gt;&lt;code&gt;/your-article/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;（尤其是原本就沒有 /blog/ 的站）&lt;hr&gt;&lt;h3 id=&quot;解法:使用-permalink-覆寫&quot;&gt;&lt;strong&gt;解法：使用&lt;/strong&gt; &lt;strong&gt;permalink&lt;/strong&gt; &lt;strong&gt;覆寫&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在文章的資料設定（例如 blog.11tydata.js）中加入：&lt;pre class=&quot;language-yml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/{{ page.fileSlug }}/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這樣產生的網址會是：&lt;pre&gt;&lt;code&gt;/article-name/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;📌 &lt;strong&gt;建議&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;搬家初期就決定好 URL 結構&lt;li&gt;否則後面還要處理 redirect 與 SEO&lt;/ul&gt;&lt;hr&gt;&lt;h2 id=&quot;圖片路徑一定會壞:WordPress-匯出後你要自己改&quot;&gt;&lt;strong&gt;圖片路徑一定會壞：WordPress 匯出後你要自己改&lt;/strong&gt;&lt;/h2&gt;&lt;h3 id=&quot;常見狀況&quot;&gt;&lt;strong&gt;常見狀況&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;從 WordPress 匯出的 Markdown，圖片通常長這樣：&lt;pre class=&quot;language-md&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;![](assets/image-6-OvqQDXqPWqL5.png)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但實際上你在 11ty starter 裡，圖片可能放在：&lt;pre&gt;&lt;code&gt;/img/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或你自己規劃的：&lt;pre&gt;&lt;code&gt;/src/img/
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;&lt;h3 id=&quot;解法:統一調整成你實際的圖片目錄&quot;&gt;&lt;strong&gt;解法：統一調整成你實際的圖片目錄&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;例如我最後改成：&lt;pre class=&quot;language-md&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;![](../img/image-6-OvqQDXqPWqL5.png)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;📌 &lt;strong&gt;實戰建議&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;不要照匯出的目錄走&lt;li&gt;一開始就規劃好：&lt;ul&gt;&lt;li&gt;content&lt;li&gt;img&lt;li&gt;feature-images&lt;/ul&gt;&lt;li&gt;然後「全部改成一致」&lt;/ul&gt;&lt;p&gt;（之後再加 eleventy-img 會輕鬆很多）&lt;hr&gt;&lt;h2 id=&quot;如何跳過不想-build-的文章(Draft-機制)&quot;&gt;&lt;strong&gt;如何跳過不想 build 的文章（Draft 機制）&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;搬家時，很常會遇到：&lt;ul&gt;&lt;li&gt;文章還沒整理完&lt;li&gt;內容需要重寫&lt;li&gt;只想先放著，不想出現在正式站&lt;/ul&gt;&lt;h3 id=&quot;在-frontmatter-標記&quot;&gt;&lt;strong&gt;在 frontmatter 標記&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;本篇文章的 frontmatter 範例&lt;pre class=&quot;language-yml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 從 WordPress 搬家到 Eleventy（11ty）：你一定會遇到的幾個注意事項整理
&lt;span class=&quot;token key atrule&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 從 WordPress 搬家到 Eleventy 靜態網站生成器的完整指南，整理了遷移過程中常見的注意事項、坑洞與解決方案。包含內容匯出、圖片處理、前端框架整合等實戰經驗分享。
&lt;span class=&quot;token key atrule&quot;&gt;feature_image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../img/feature-images/11ty-notes.png&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;use_feature_split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;feature_meta_text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; WordPress 到 Eleventy 的遷移之旅
&lt;span class=&quot;token key atrule&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token datetime number&quot;&gt;2025-12-22T10:00:00.000Z&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 架設網站
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 靜態網站生成器
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wordpress&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;migration
  &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; https&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//kamadiam.com/wordpress&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;eleventy&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;migration/
&lt;span class=&quot;token key atrule&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; wordpress
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; eleventy
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 11ty
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 靜態網站
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 網站搬家
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 遷移指南
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 前端開發
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 網站優化
&lt;span class=&quot;token key atrule&quot;&gt;templateEngineOverride&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; md
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最重要的只有這一行&lt;pre class=&quot;language-yml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;templateEngineOverride&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; md&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;&lt;h3 id=&quot;在-Eleventy-設定中統一處理-Draft&quot;&gt;&lt;strong&gt;在 Eleventy 設定中統一處理 Draft&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在 eleventy.config.js 中修改範例如下：&lt;h4 id=&quot;1️⃣-Preprocessor:正式環境直接不-build&quot;&gt;&lt;strong&gt;1️⃣ Preprocessor：正式環境直接不 build&lt;/strong&gt;&lt;/h4&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPreprocessor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;drafts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;draft&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; (draft)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;draft &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NODE_ENV&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;production&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;👉 開發環境看得到&lt;p&gt;👉 production 直接排除&lt;hr&gt;&lt;h4 id=&quot;2️⃣-Collection-排除-Draft&quot;&gt;&lt;strong&gt;2️⃣ Collection 排除 Draft&lt;/strong&gt;&lt;/h4&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAllPosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;collectionApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; collectionApi
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFilteredByGlob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./content/blog/**/*.md&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;draft&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addCollection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postsSorted&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;collectionApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; collectionApi
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFilteredByGlob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./content/blog/**/*.md&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;draft&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;📌 &lt;strong&gt;好處&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;不會出現在列表頁&lt;li&gt;不會被 sitemap、RSS 收進去&lt;li&gt;非常適合「搬家整理期」&lt;/ul&gt;&lt;hr&gt;&lt;h2 id=&quot;結語:搬家不是一次性工作,而是一段整理過程&quot;&gt;&lt;strong&gt;結語：搬家不是一次性工作，而是一段整理過程&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;從 WordPress 搬到 Eleventy，&lt;strong&gt;最大的差別不是技術，而是控制權&lt;/strong&gt;。&lt;ul&gt;&lt;li&gt;你要自己決定 URL&lt;li&gt;自己決定圖片結構&lt;li&gt;自己決定什麼該被 build、什麼不該&lt;/ul&gt;&lt;p&gt;但一旦整理完，整個網站會變得：&lt;ul&gt;&lt;li&gt;輕&lt;li&gt;可控&lt;li&gt;而且長期維護成本極低&lt;/ul&gt;&lt;p&gt;👉 如果你正在規劃 WordPress → 11ty&lt;p&gt;👉 或正卡在 migrate 的某個細節&lt;p&gt;這些注意事項，真的可以幫你少走很多冤枉路。&lt;p&gt;不要覺得 11ty 很麻煩，不同架構之間搬家本身就是麻煩事，尤其 WordPress 和 11ty 兩個設計概念完全天差地遠。&lt;p&gt;沒有最好的，只有最適合的。</content>
  </entry>
  <entry>
    <title>把文章從 WordPress 搬出來：eleventy-import 的匯出方式</title>
    <link href="https://kamadiam.com/11ty-import-tutorial/" />
    <updated>2025-12-15T10:00:00Z</updated>
    <id>https://kamadiam.com/11ty-import-tutorial/</id>
    <content type="html">&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#eleventy-import,%E7%B5%82%E6%96%BC%E5%8F%AF%E4%BB%A5%E6%8A%8A-WordPress-%E8%B3%87%E6%96%99%E5%A5%BD%E5%A5%BD%E6%90%AC%E5%87%BA%E4%BE%86&quot;&gt;eleventy-import，終於可以把 WordPress 資料好好搬出來&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E7%82%BA%E4%BB%80%E9%BA%BC%E4%B8%80%E8%88%AC-WordPress-%E5%8C%AF%E5%87%BA%E6%96%B9%E5%BC%8F%E9%80%99%E9%BA%BC%E7%97%9B%E8%8B%A6?&quot;&gt;為什麼一般 WordPress 匯出方式這麼痛苦？&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E5%AE%98%E6%96%B9%E5%87%BA%E6%89%8B:11ty-%E7%9A%84-WordPress-%E8%BD%89%E7%A7%BB%E6%95%99%E5%AD%B8&quot;&gt;官方出手：11ty 的 WordPress 轉移教學&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E4%BD%BF%E7%94%A8-eleventy-import-%E5%8C%AF%E5%87%BA-WordPress-%E6%96%87%E7%AB%A0&quot;&gt;使用 eleventy-import 匯出 WordPress 文章&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E7%9B%B4%E6%8E%A5%E5%9F%B7%E8%A1%8C%E4%B8%80%E8%A1%8C%E6%8C%87%E4%BB%A4&quot;&gt;直接執行一行指令&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E5%8C%AF%E5%87%BA%E5%BE%8C%E7%9A%84%E7%9B%AE%E9%8C%84%E7%B5%90%E6%A7%8B&quot;&gt;匯出後的目錄結構&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E4%B8%8B%E4%B8%80%E6%AD%A5:%E9%81%B8%E6%93%87-11ty-Starter&quot;&gt;下一步：選擇 11ty Starter&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#eleventy-base-blog&quot;&gt;eleventy-base-blog&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#eleventy-excellent&quot;&gt;eleventy-excellent&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E6%9C%80%E5%BE%8C%E9%81%B8%E6%93%87&quot;&gt;最後選擇&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E5%95%9F%E5%8B%95-11ty,%E9%A9%97%E6%94%B6%E6%88%90%E6%9E%9C&quot;&gt;啟動 11ty，驗收成果&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/11ty-import-tutorial/#%E5%BE%9E%E9%80%99%E4%B8%80%E5%88%BB%E8%B5%B7,%E6%98%AF%E5%85%A8%E6%96%B0%E7%9A%84%E9%96%8B%E5%A7%8B&quot;&gt;從這一刻起，是全新的開始&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;老實說，&lt;strong&gt;從 WordPress 轉移到其他系統，最痛苦的永遠不是選框架，而是「資料怎麼搬」&lt;/strong&gt;。&lt;p&gt;這點大家應該都心有戚戚焉。&lt;h2 id=&quot;eleventy-import,終於可以把-WordPress-資料好好搬出來&quot;&gt;eleventy-import，終於可以把 WordPress 資料好好搬出來&lt;/h2&gt;&lt;p&gt;11ty 的作者真的很懂這個痛點，直接自己寫了一個官方匯入工具：&lt;strong&gt;eleventy-import&lt;/strong&gt;。&lt;p&gt;在真正遇到它之前，我其實也走過不少冤枉路。&lt;p&gt;一開始的想法很直覺：&lt;p&gt;👉 用 WordPress 外掛把文章匯出成 Markdown，再慢慢整理。&lt;p&gt;問題是——事情完全沒那麼單純。&lt;h3 id=&quot;為什麼一般-WordPress-匯出方式這麼痛苦?&quot;&gt;為什麼一般 WordPress 匯出方式這麼痛苦？&lt;/h3&gt;&lt;p&gt;之前試過幾個 WordPress 匯出外掛，產生出來的檔案大多有這些問題：&lt;ul&gt;&lt;li&gt;夾雜大量 &lt;strong&gt;WordPress 專用標籤&lt;/strong&gt;&lt;li&gt;各種外掛留下來的 &lt;strong&gt;短代碼（shortcode）&lt;/strong&gt;&lt;li&gt;XML / HTML 混在一起，格式不統一&lt;li&gt;有的圖片是外掛語法，還有各種奇怪的包法&lt;/ul&gt;&lt;p&gt;最麻煩的是：&lt;p&gt;👉 &lt;strong&gt;這些雜物沒有固定格式，根本沒辦法用一支 script 全部清乾淨&lt;/strong&gt;&lt;p&gt;每篇文章都像在開盲盒，例外狀況多到讓人直接放棄。&lt;p&gt;於是這件事就這樣被擱著了。&lt;h2 id=&quot;官方出手:11ty-的-WordPress-轉移教學&quot;&gt;官方出手：11ty 的 WordPress 轉移教學&lt;/h2&gt;&lt;p&gt;直到有一天，在 11ty 官網亂逛時，看到這一頁：&lt;p&gt;👉 https://www.11ty.dev/docs/migrate/wordpress/&lt;p&gt;不只寫了完整教學，&lt;strong&gt;作者本人還拍了一支影片，標題是「Escape From WordPress」&lt;/strong&gt;，整個就是用意非常明顯 😂&lt;p&gt;影片在這裡：&lt;p&gt;https://www.youtube.com/watch?v=WuH5QYCdh6w&lt;p&gt;看到這裡才發現：&lt;p&gt;👉 原來 11ty 早就把「從 WordPress 逃離」這件事想好了。&lt;hr&gt;&lt;h2 id=&quot;使用-eleventy-import-匯出-WordPress-文章&quot;&gt;&lt;strong&gt;使用 eleventy-import 匯出 WordPress 文章&lt;/strong&gt;&lt;/h2&gt;&lt;h3 id=&quot;直接執行一行指令&quot;&gt;&lt;strong&gt;直接執行一行指令&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;使用方式非常暴力，也非常爽快：&lt;pre&gt;&lt;code&gt;npx @11ty/import wordpress https://your-site.com/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者如果習慣 pnpm&lt;pre&gt;&lt;code&gt;pnpm dlx @11ty/import wordpress https://your-site.com/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第一次看到這行指令的反應是：&lt;blockquote&gt;&lt;p&gt;不是吧？就這樣？&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;沒了？&lt;/blockquote&gt;&lt;p&gt;結果真的就 &lt;strong&gt;完成了，YA。&lt;/strong&gt;&lt;h2 id=&quot;匯出後的目錄結構&quot;&gt;&lt;strong&gt;匯出後的目錄結構&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;eleventy-import 會直接幫你輸出成 &lt;strong&gt;11ty 最愛的格式&lt;/strong&gt;：&lt;pre&gt;&lt;code&gt;your_project/
  assets/
    image1
    image2

  article1.md
  article2.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;幾個我覺得「非常關鍵」的點：&lt;ul&gt;&lt;li&gt;每一篇文章都是 &lt;strong&gt;乾淨的 Markdown&lt;/strong&gt;&lt;li&gt;所有圖片自動整理進 assets/ 目錄&lt;li&gt;文章內的圖片連結也已經幫你改好&lt;li&gt;幾乎沒有 WordPress 遺毒&lt;/ul&gt;&lt;p&gt;一句話總結：&lt;p&gt;👉 &lt;strong&gt;這個輸出結果，完全就是為了「直接丟進 11ty」而設計的。&lt;/strong&gt;&lt;h2 id=&quot;下一步:選擇-11ty-Starter&quot;&gt;&lt;strong&gt;下一步：選擇 11ty Starter&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;文章資料已經乾乾淨淨了，接下來就是選一個起始專案。&lt;h3 id=&quot;eleventy-base-blog&quot;&gt;eleventy-base-blog&lt;/h3&gt;&lt;p&gt;GitHub：&lt;p&gt;&lt;a href=&quot;https://github.com/11ty/eleventy-base-blog&quot; target=&quot;_blank&quot;&gt;eleventy-base&lt;/a&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;官方範例，結構清楚&lt;li&gt;幾乎沒有多餘抽象&lt;li&gt;非常適合「想自己慢慢加功能」的人&lt;li&gt;好改、不綁架設計&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;缺點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;功能極簡&lt;li&gt;SEO、樣式、搜尋、圖片優化都要自己補&lt;li&gt;一開始看起來有點「什麼都沒有」&lt;/ul&gt;&lt;h3 id=&quot;eleventy-excellent&quot;&gt;&lt;strong&gt;eleventy-excellent&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;網站：&lt;p&gt;&lt;a href=&quot;https://eleventy-excellent.netlify.app/&quot; target=&quot;_blank&quot;&gt;eleventy-excellent&lt;/a&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;幾乎什麼都幫你準備好了&lt;li&gt;包含 SEO、圖片處理、效能最佳化&lt;li&gt;設計完成度高，很快就能上線&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;缺點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;設計與架構選擇比較多是「作者的想法」&lt;li&gt;想大改時，需要先理解一整套設計哲學&lt;li&gt;對我來說，反而有點太滿了&lt;/ul&gt;&lt;h2 id=&quot;最後選擇&quot;&gt;&lt;strong&gt;最後選擇&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;一開始其實是用 &lt;strong&gt;eleventy-excellent&lt;/strong&gt;，因為真的很省事。&lt;p&gt;但實際調整一陣子後發現：&lt;p&gt;👉 &lt;strong&gt;一定會有一些地方「不是自己想要的方式」&lt;/strong&gt;&lt;p&gt;而要改動那些地方，反而得先拆作者原本的設計。&lt;p&gt;最後決定回頭選擇 &lt;strong&gt;eleventy-base-blog&lt;/strong&gt;：&lt;blockquote&gt;&lt;p&gt;從最簡單的開始，&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;需要什麼，再一個一個加。&lt;/blockquote&gt;&lt;h2 id=&quot;啟動-11ty,驗收成果&quot;&gt;&lt;strong&gt;啟動 11ty，驗收成果&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;把剛剛匯出的文章與 assets 目錄，放進：&lt;pre&gt;&lt;code&gt;content/blog/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然後啟動專案：&lt;pre&gt;&lt;code&gt;pnpm run start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;打開瀏覽器，直接進：&lt;pre&gt;&lt;code&gt;http://localhost:8080/文章名稱/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你會看到一件很神奇的事：&lt;ul&gt;&lt;li&gt;文章內容完整&lt;li&gt;圖片全部正常&lt;li&gt;但樣式幾乎全沒了&lt;/ul&gt;&lt;p&gt;這一刻這是感動萬分！。&lt;p&gt;因為這代表：&lt;p&gt;👉 &lt;strong&gt;資料真的已經完全脫離 WordPress 了。&lt;/strong&gt;&lt;h2 id=&quot;從這一刻起,是全新的開始&quot;&gt;&lt;strong&gt;從這一刻起，是全新的開始&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;這樣的網站：&lt;ul&gt;&lt;li&gt;快到不行，幾乎是秒開&lt;li&gt;什麼功能都沒有&lt;li&gt;但結構乾淨、可控、沒有包袱&lt;/ul&gt;&lt;p&gt;這就是取捨啊。&lt;p&gt;WordPress 的功能真的很方便，&lt;p&gt;但當你選擇 11ty，簡單也不是壞事。&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;用效能、掌控感，交換即插即用的便利性。&lt;/strong&gt;&lt;/blockquote&gt;&lt;p&gt;接下來，才是真正有趣的地方。我想要網站愈來愈有趣，而不是愈來愈失去興趣。</content>
  </entry>
  <entry>
    <title>WordPress vs 11ty：各自的優缺點與取捨</title>
    <link href="https://kamadiam.com/wordpress-vs-11ty/" />
    <updated>2025-12-08T10:00:00Z</updated>
    <id>https://kamadiam.com/wordpress-vs-11ty/</id>
    <content type="html">&lt;p&gt;WordPress 作為全球最受歡迎的內容管理系統，已經幫助數百萬人建立了自己的網站。然而，近年來靜態網站生成器如 11ty 也逐漸受到開發者和內容創作者的青睞。這兩種工具各有優缺點，選擇哪一個取決於你的需求、技術背景和維護意願。&lt;p&gt;本文將比較 WordPress 與 11ty，從多個面向分析兩者的差異，幫助你做出最適合的選擇。&lt;div class=&quot;table-of-contents&quot;&gt;&lt;h2 id=&quot;目錄&quot;&gt;目錄&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%E8%88%87%E5%AE%9A%E4%BD%8D&quot;&gt;基本概念與定位&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#WordPress:%E6%88%90%E7%86%9F%E7%9A%84%E5%85%A8%E5%8A%9F%E8%83%BD-CMS&quot;&gt;WordPress：成熟的全功能 CMS&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#11ty:%E7%8F%BE%E4%BB%A3%E5%8C%96%E7%9A%84%E9%9D%9C%E6%85%8B%E7%B6%B2%E7%AB%99%E7%94%9F%E6%88%90%E5%99%A8&quot;&gt;11ty：現代化的靜態網站生成器&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E4%B8%BB%E8%A6%81%E5%B7%AE%E7%95%B0%E6%AF%94%E8%BC%83&quot;&gt;主要差異比較&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E6%8A%80%E8%A1%93%E6%9E%B6%E6%A7%8B&quot;&gt;技術架構&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E9%96%8B%E7%99%BC%E9%AB%94%E9%A9%97&quot;&gt;開發體驗&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E6%95%88%E8%83%BD%E8%A1%A8%E7%8F%BE&quot;&gt;效能表現&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%AE%89%E5%85%A8%E6%80%A7%E8%80%83%E9%87%8F&quot;&gt;安全性考量&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E7%B6%AD%E8%AD%B7%E6%88%90%E6%9C%AC%E8%88%87%E8%A4%87%E9%9B%9C%E5%BA%A6&quot;&gt;維護成本與複雜度&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%85%A7%E5%AE%B9%E7%AE%A1%E7%90%86%E8%88%87%E5%8D%94%E4%BD%9C&quot;&gt;內容管理與協作&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E9%81%A9%E5%90%88%E7%9A%84%E4%BD%BF%E7%94%A8%E6%83%85%E5%A2%83&quot;&gt;適合的使用情境&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E9%81%B8%E6%93%87-WordPress-%E7%9A%84%E6%83%85%E5%A2%83&quot;&gt;選擇 WordPress 的情境&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E9%81%B8%E6%93%87-11ty-%E7%9A%84%E6%83%85%E5%A2%83&quot;&gt;選擇 11ty 的情境&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%AF%A6%E9%9A%9B%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90&quot;&gt;實際案例分析&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#WordPress-%E9%81%A9%E5%90%88%E6%A1%88%E4%BE%8B&quot;&gt;WordPress 適合案例&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#11ty-%E9%81%A9%E5%90%88%E6%A1%88%E4%BE%8B&quot;&gt;11ty 適合案例&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E9%81%B7%E7%A7%BB%E8%88%87%E8%BD%89%E6%8F%9B%E8%80%83%E9%87%8F&quot;&gt;遷移與轉換考量&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%BE%9E-WordPress-%E9%81%B7%E7%A7%BB%E5%88%B0-11ty&quot;&gt;從 WordPress 遷移到 11ty&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E5%BE%9E-11ty-%E9%81%B7%E7%A7%BB%E5%88%B0-WordPress&quot;&gt;從 11ty 遷移到 WordPress&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://kamadiam.com/wordpress-vs-11ty/#%E7%B5%90%E8%AB%96:%E6%B2%92%E6%9C%89%E7%B5%95%E5%B0%8D%E7%9A%84%E3%80%8C%E6%9C%80%E5%A5%BD%E3%80%8D&quot;&gt;結論：沒有絕對的「最好」&lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id=&quot;基本概念與定位&quot;&gt;基本概念與定位&lt;/h2&gt;&lt;h3 id=&quot;WordPress:成熟的全功能-CMS&quot;&gt;WordPress：成熟的全功能 CMS&lt;/h3&gt;&lt;p&gt;WordPress 是一個功能完整的內容管理系統，提供完整的後端管理介面、資料庫儲存、動態內容生成等功能。它最初設計為部落格平台，但現在已經演變成一個全功能的 CMS，可以建立任何類型的網站。&lt;h3 id=&quot;11ty:現代化的靜態網站生成器&quot;&gt;11ty：現代化的靜態網站生成器&lt;/h3&gt;&lt;p&gt;11ty（Eleventy）是一個以 JavaScript 為基礎的靜態網站生成器。它不依賴資料庫，而是將內容檔案轉換為靜態 HTML 檔案，在建置時生成完整網站。&lt;h2 id=&quot;主要差異比較&quot;&gt;主要差異比較&lt;/h2&gt;&lt;h3 id=&quot;技術架構&quot;&gt;技術架構&lt;/h3&gt;&lt;h4 id=&quot;WordPress-的動態架構&quot;&gt;WordPress 的動態架構&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;資料庫驅動&lt;/strong&gt;：所有內容都儲存在 MySQL/PostgreSQL 等資料庫中&lt;li&gt;&lt;strong&gt;動態生成&lt;/strong&gt;：每次頁面請求時，PHP 會從資料庫提取資料並動態生成 HTML&lt;li&gt;&lt;strong&gt;依賴關係&lt;/strong&gt;：需要 PHP 運行環境、資料庫伺服器、Web 伺服器（如 Apache/Nginx）&lt;/ul&gt;&lt;h4 id=&quot;11ty-的靜態架構&quot;&gt;11ty 的靜態架構&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;檔案驅動&lt;/strong&gt;：內容以 Markdown、HTML 等檔案格式儲存&lt;li&gt;&lt;strong&gt;預先建置&lt;/strong&gt;：在開發階段就生成所有靜態檔案&lt;li&gt;&lt;strong&gt;獨立部署&lt;/strong&gt;：只需要靜態檔案伺服器，無需資料庫或特定運行環境&lt;/ul&gt;&lt;h3 id=&quot;開發體驗&quot;&gt;開發體驗&lt;/h3&gt;&lt;h4 id=&quot;WordPress:視覺化編輯優先&quot;&gt;WordPress：視覺化編輯優先&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;所見即所得編輯器&lt;/strong&gt;：古騰堡編輯器讓非技術人員也能輕鬆編輯內容&lt;li&gt;&lt;strong&gt;即時預覽&lt;/strong&gt;：修改後立即在前端看到效果&lt;li&gt;&lt;strong&gt;外掛生態&lt;/strong&gt;：有數萬個外掛可以快速增加功能&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;缺點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;學習曲線&lt;/strong&gt;：雖然編輯簡單，但要客製化主題仍需學習 PHP、WordPress Hook 等&lt;li&gt;&lt;strong&gt;外掛相容性&lt;/strong&gt;：不同外掛間可能衝突，需要花時間測試和調試&lt;/ul&gt;&lt;p&gt;(現代 PHP 和 WordPress 也改善很多開發流程和工具了) 參考： &lt;a href=&quot;https://kamadiam.com/herd-wordpress/&quot;&gt;如何使用 Herd 在本機架設 WordPress 網站&lt;/a&gt;&lt;h4 id=&quot;11ty:程式化開發體驗&quot;&gt;11ty：程式化開發體驗&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;版本控制友好&lt;/strong&gt;：所有內容和設定都以檔案形式存在，可以用 Git 完整管理&lt;li&gt;&lt;strong&gt;完全客製化&lt;/strong&gt;：從頭到尾控制每一個細節&lt;li&gt;&lt;strong&gt;現代開發工具鏈&lt;/strong&gt;：可以使用 npm scripts、現代 CSS 框架、模組化 JavaScript&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;缺點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;學習門檻&lt;/strong&gt;：需要基本程式設計知識&lt;li&gt;&lt;strong&gt;建置步驟&lt;/strong&gt;：每次修改都需要重新建置才能看到效果&lt;/ul&gt;&lt;h3 id=&quot;效能表現&quot;&gt;效能表現&lt;/h3&gt;&lt;h4 id=&quot;WordPress:需要持續優化&quot;&gt;WordPress：需要持續優化&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;初始載入&lt;/strong&gt;：動態生成內容導致首次載入較慢&lt;li&gt;&lt;strong&gt;快取需求&lt;/strong&gt;：需要安裝快取外掛（如 WP Rocket、LiteSpeed Cache）來改善效能&lt;li&gt;&lt;strong&gt;伺服器負載&lt;/strong&gt;：高流量時需要更多伺服器資源&lt;/ul&gt;&lt;h4 id=&quot;11ty:天生高效能&quot;&gt;11ty：天生高效能&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;極快載入&lt;/strong&gt;：純靜態檔案，CDN 快取效果極佳&lt;li&gt;&lt;strong&gt;低伺服器成本&lt;/strong&gt;：可以使用免費的靜態託管服務&lt;li&gt;&lt;strong&gt;無資料庫查詢&lt;/strong&gt;：沒有資料庫延遲問題&lt;/ul&gt;&lt;p&gt;在相同的機器規格上，11ty會消耗較少資源，也不需要資料庫的建置，但你也可以購買專用主機，直接提升效能。&lt;h3 id=&quot;安全性考量&quot;&gt;安全性考量&lt;/h3&gt;&lt;h4 id=&quot;WordPress:常見攻擊目標&quot;&gt;WordPress：常見攻擊目標&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;風險點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;外掛漏洞&lt;/strong&gt;：許多安全性問題來自過時或有漏洞的外掛&lt;li&gt;&lt;strong&gt;PHP 環境&lt;/strong&gt;：動態執行的本質帶來更多攻擊面&lt;li&gt;&lt;strong&gt;資料庫安全&lt;/strong&gt;：需要保護資料庫免於攻擊&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;活躍社群&lt;/strong&gt;：有大量安全性外掛和監控工具&lt;li&gt;&lt;strong&gt;定期更新&lt;/strong&gt;：核心系統和外掛都會定期修補漏洞&lt;/ul&gt;&lt;h4 id=&quot;11ty:本質安全&quot;&gt;11ty：本質安全&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;最小攻擊面&lt;/strong&gt;：沒有資料庫、沒有動態執行，極難被入侵&lt;li&gt;&lt;strong&gt;內容驗證&lt;/strong&gt;：建置時可以驗證所有內容和程式碼&lt;li&gt;&lt;strong&gt;相依性控制&lt;/strong&gt;：可以精確控制所有第三方程式庫&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;考量點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;建置安全&lt;/strong&gt;：需要保護建置過程和部署金鑰&lt;li&gt;&lt;strong&gt;第三方服務&lt;/strong&gt;：如果整合外部服務（如表單、評論），需要注意這些服務的安全性&lt;/ul&gt;&lt;p&gt;11ty 的好處是沒有後台登入功能，會被破解的地方就是主機本身，如果主機使用不夠安全，用什麼架構都一樣不安全。&lt;h3 id=&quot;維護成本與複雜度&quot;&gt;維護成本與複雜度&lt;/h3&gt;&lt;h4 id=&quot;WordPress:持續維護需求高&quot;&gt;WordPress：持續維護需求高&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;定期任務：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;軟體更新&lt;/strong&gt;：核心、主題、外掛都需要定期更新&lt;li&gt;&lt;strong&gt;安全性修補&lt;/strong&gt;：監控並修補已知漏洞&lt;li&gt;&lt;strong&gt;效能優化&lt;/strong&gt;：定期檢查和優化網站速度&lt;li&gt;&lt;strong&gt;備份管理&lt;/strong&gt;：資料庫和檔案的備份策略&lt;/ul&gt;&lt;p&gt;雖然都很簡單的定期更新，就是很繁雜，但外掛版本和 WordPress 版本和 PHP 版本之間的相容性需要考量。&lt;h4 id=&quot;11ty:一次性設定,長期穩定&quot;&gt;11ty：一次性設定，長期穩定&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;維護內容：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;內容更新&lt;/strong&gt;：只需要編輯 Markdown 檔案&lt;li&gt;&lt;strong&gt;相依性更新&lt;/strong&gt;：偶爾更新 npm 套件&lt;li&gt;&lt;strong&gt;重新部署&lt;/strong&gt;：修改後重新建置和部署&lt;/ul&gt;&lt;h3 id=&quot;內容管理與協作&quot;&gt;內容管理與協作&lt;/h3&gt;&lt;h4 id=&quot;WordPress:多人協作友好&quot;&gt;WordPress：多人協作友好&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;角色權限系統&lt;/strong&gt;：支援不同層級的使用者權限&lt;li&gt;&lt;strong&gt;即時協作&lt;/strong&gt;：多個編輯者可以同時工作&lt;li&gt;&lt;strong&gt;審核流程&lt;/strong&gt;：支援草稿、審核、發布流程&lt;/ul&gt;&lt;p&gt;以我個人的情境來說（主要是一人維護與發文），WordPress 的角色權限與協作流程屬於「用得到很強，用不到就比較像是額外的系統功能」。相對地，我更在意的是內容變更是否能被精準追蹤與回溯。&lt;p&gt;而且你也很難追蹤另一個 WordPress 使用者動了什麼東西，改了什麼設定。&lt;h4 id=&quot;11ty:開發者導向協作&quot;&gt;11ty：開發者導向協作&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Git 工作流程&lt;/strong&gt;：任何微小變動都清清楚楚，輕易追蹤管理版本。&lt;li&gt;&lt;strong&gt;內容即程式碼&lt;/strong&gt;：內容和程式碼使用相同工具管理&lt;li&gt;&lt;strong&gt;版本歷史&lt;/strong&gt;：完整的內容修改歷史記錄&lt;/ul&gt;&lt;h2 id=&quot;適合的使用情境&quot;&gt;適合的使用情境&lt;/h2&gt;&lt;h3 id=&quot;選擇-WordPress-的情境&quot;&gt;選擇 WordPress 的情境&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;非技術使用者&lt;/strong&gt;：如果你不熟悉程式設計，但需要快速建立網站&lt;li&gt;&lt;strong&gt;複雜功能需求&lt;/strong&gt;：需要會員系統、電子商務、複雜表單等動態功能&lt;li&gt;&lt;strong&gt;多人協作內容&lt;/strong&gt;：有多個內容編輯者，需要完善的權限管理&lt;li&gt;&lt;strong&gt;預算有限&lt;/strong&gt;：不想花時間學習技術，希望快速上線&lt;li&gt;&lt;strong&gt;經常變更內容&lt;/strong&gt;：網站內容需要頻繁更新，希望即時生效&lt;/ol&gt;&lt;h3 id=&quot;選擇-11ty-的情境&quot;&gt;選擇 11ty 的情境&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;技術背景使用者&lt;/strong&gt;：熟悉 HTML、CSS、JavaScript，有程式設計基礎&lt;li&gt;&lt;strong&gt;效能至上&lt;/strong&gt;：對網站載入速度有極高要求&lt;li&gt;&lt;strong&gt;安全性重視&lt;/strong&gt;：希望最小化安全風險&lt;li&gt;&lt;strong&gt;長期維護考量&lt;/strong&gt;：希望降低長期維護成本&lt;li&gt;&lt;strong&gt;個人/小型專案&lt;/strong&gt;：部落格、作品集、文件網站等&lt;li&gt;&lt;strong&gt;版本控制需求&lt;/strong&gt;：需要完整的內容版本歷史和協作流程&lt;/ol&gt;&lt;p&gt;這些只是比較適合的點，並不代表這個功能一定得用某個技術才行。&lt;h2 id=&quot;實際案例分析&quot;&gt;實際案例分析&lt;/h2&gt;&lt;h3 id=&quot;WordPress-適合案例&quot;&gt;WordPress 適合案例&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;新聞網站&lt;/strong&gt;：需要頻繁更新內容、多個編輯者協作&lt;li&gt;&lt;strong&gt;企業網站&lt;/strong&gt;：需要 CMS 整合、聯絡表單、會員系統&lt;li&gt;&lt;strong&gt;電子商務&lt;/strong&gt;：需要購物車、付款閘道、庫存管理&lt;li&gt;&lt;strong&gt;社群平台&lt;/strong&gt;：需要用戶生成內容、評論系統&lt;/ul&gt;&lt;h3 id=&quot;11ty-適合案例&quot;&gt;11ty 適合案例&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;個人部落格&lt;/strong&gt;：內容創作者專注於寫作而非維護&lt;li&gt;&lt;strong&gt;產品文件&lt;/strong&gt;：技術文件、API 文件等需要版本控制&lt;li&gt;&lt;strong&gt;作品集網站&lt;/strong&gt;：設計師、開發者的個人展示網站&lt;li&gt;&lt;strong&gt;公司官網&lt;/strong&gt;：簡單的企業介紹頁面，重視品牌形象&lt;/ul&gt;&lt;p&gt;事實上 11ty 能做的事，WordPress 都做得到，但選擇 11ty 通常不是太功能上的選擇，很多是想在技術上架構上簡單透明一點。&lt;h2 id=&quot;遷移與轉換考量&quot;&gt;遷移與轉換考量&lt;/h2&gt;&lt;h3 id=&quot;從-WordPress-遷移到-11ty&quot;&gt;從 WordPress 遷移到 11ty&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;大幅改善效能和安全性&lt;li&gt;降低託管成本&lt;li&gt;獲得更多控制權&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;挑戰：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;需要將動態功能改為靜態或外部服務&lt;li&gt;失去所見即所得編輯體驗&lt;li&gt;需要學習新的工作流程&lt;/ul&gt;&lt;h3 id=&quot;從-11ty-遷移到-WordPress&quot;&gt;從 11ty 遷移到 WordPress&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;優點：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;快速增加複雜功能&lt;li&gt;降低內容編輯門檻&lt;li&gt;支援更多非技術使用者&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;挑戰：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;效能下降&lt;li&gt;維護複雜度增加&lt;li&gt;安全性風險提高&lt;/ul&gt;&lt;h2 id=&quot;結論:沒有絕對的「最好」&quot;&gt;結論：沒有絕對的「最好」&lt;/h2&gt;&lt;p&gt;WordPress 和 11ty 代表兩種不同的網站建置哲學：&lt;ul&gt;&lt;li&gt;&lt;strong&gt;WordPress&lt;/strong&gt; 強調易用性和功能完整性，適合需要快速上線、複雜功能、或多人協作的專案&lt;li&gt;&lt;strong&gt;11ty&lt;/strong&gt; 強調效能、安全性和開發體驗，適合技術背景的使用者和重視長期維護的專案&lt;/ul&gt;&lt;p&gt;最終的選擇應該基於：&lt;ol&gt;&lt;li&gt;&lt;strong&gt;你的技術能力&lt;/strong&gt;：熟悉程式設計嗎？&lt;li&gt;&lt;strong&gt;專案需求&lt;/strong&gt;：需要哪些功能？預算多少？&lt;li&gt;&lt;strong&gt;維護意願&lt;/strong&gt;：願意投入多少時間在網站維護上？&lt;li&gt;&lt;strong&gt;成長規劃&lt;/strong&gt;：網站未來可能如何演變？&lt;/ol&gt;&lt;p&gt;建議你可以先評估自己的需求，必要時甚至可以考慮混合使用兩者。例如，使用 11ty 建立主要內容網站，WordPress 作為後台內容管理系統。&lt;p&gt;無論選擇哪一個工具，重點是找到最適合自己工作流程和需求的解決方案。技術工具應該服務於內容創作，而不是成為創作的障礙。&lt;p&gt;WordPress 看很多了，來看看幾個 11ty 的網站&lt;ul&gt;&lt;li&gt;https://chrisburnell.com/&lt;li&gt;https://www.zachleat.com/&lt;li&gt;https://eleventy-excellent.netlify.app/&lt;/ul&gt;&lt;hr&gt;&lt;p&gt;&lt;strong&gt;相關資源：&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty 官方文件&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress 官方網站&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://jamstack.org/generators/&quot;&gt;靜態網站生成器比較&lt;/a&gt;&lt;li&gt;&lt;a href=&quot;https://www.netlify.com/blog/2020/04/14/what-is-a-static-site-generator-and-3-ways-to-find-the-best-one/&quot;&gt;What is a Static Site Generator? And 3 ways to find the best one&lt;/a&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>1 個程式範例，快速學習 JavaScript 物件導向語法</title>
    <link href="https://kamadiam.com/javascript-oop/" />
    <updated>2024-01-01T00:27:42Z</updated>
    <id>https://kamadiam.com/javascript-oop/</id>
    <content type="html">&lt;p&gt;當深入 JavaScript 的核心時，傳統的物件導向編程（OOP）技術顯得非常重要。這種編程風格不僅為程式碼提供了清晰的結構，而且還促進了模組化和重用，這對於大型和複雜的應用程式開發尤為關鍵。&lt;p&gt;&lt;strong&gt;為什麼要學習 JavaScript OOP？&lt;/strong&gt;&lt;p&gt;JavaScript 雖然最初是基於原型的語言，但 ES6（ES2015）引入了類別（class）語法，讓開發者能夠使用更傳統的物件導向編程方式。這種方式讓程式碼更容易理解、維護和擴展。&lt;p&gt;本篇文章將透過一個完整的範例，一步步探討 JavaScript 中傳統物件導向編程的關鍵概念，包括類別的定義、公共和私有屬性的宣告、建構函數、方法的使用，以及類別的繼承等。這將幫助你深入理解 JavaScript 中的 OOP，並將這些知識應用於編程實踐中。&lt;p&gt;&lt;strong&gt;完整 OOP 語法範例：&lt;/strong&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 定義一個類別 (Define a Class)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 類別是 JavaScript 中用於建立物件的模板。它封裝了相關的屬性和方法。&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Car&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 公共屬性 (Declare a Public Property)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 公共屬性可以在類別實例的任何地方被存取和修改。&lt;/span&gt;
    color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 私有屬性 (Declare a Private Property)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 私有屬性僅在定義它們的類別內部可存取，外部無法直接存取。&lt;/span&gt;
    #brand&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 建構函數 (Declare Constructor)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 建構函數是在建立類別實例時自動呼叫的特殊方法，用於初始化類別的屬性。&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;brand&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;#brand &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; brand&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 公共方法 (Declare a Public Method)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 公共方法可以被類別實例及繼承該類別的其他類別的實例呼叫。&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;This is a &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; car.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 私有方法 (Declare a Private Method)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 私有方法僅能在定義它的類別內部被呼叫，對外部是不可見的。&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;#privateMethod&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Brand is &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;#brand&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Getter 和 Setter&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Getter 和 Setter 用於對類別的私有屬性進行安全的存取和更新。&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;#privateMethod&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;newBrand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;#brand &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newBrand&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 靜態方法和屬性 (Static Methods and Fields)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 靜態方法和屬性屬於類別本身，而不是類別的任何特定實例。&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; numberOfWheels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;carDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Cars usually have &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;numberOfWheels&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; wheels.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 擴展一個類別 (Extend a Class)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 使用 &#39;extends&#39; 關鍵字建立一個新類別，繼承另一個類別的屬性和方法。&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ElectricCar&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Car&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;brand&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batteryLife&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;brand&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 呼叫父類別建構函數&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;batteryLife &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batteryLife&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 覆寫方法&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;This is a &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; electric car with a battery life of &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;batteryLife&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; hours.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 建立一個實例 (Create an Instance)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 使用 &#39;new&#39; 關鍵字和類別名稱建立該類別的一個新實例。&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; myCar &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ElectricCar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Tesla&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;red&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 呼叫方法 (Call a Method)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 透過類別實例呼叫在類別中定義的方法。&lt;/span&gt;
myCar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// This is a red electric car with a battery life of 24 hours.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 點表示法 vs 括號表示法 (Dot vs Bracket Notation)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 使用點表示法或括號表示法存取物件的屬性。點表示法更直觀，而括號表示法在屬性名為變數時很有用。&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myCar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// red (點表示法)&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myCar&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;color&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// red (括號表示法)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;這個範例透過詳細的註解解釋了 JavaScript 中的關鍵物件導向概念，包括如何定義類別、宣告屬性和方法、建立和使用實例，以及如何實現繼承和多型性。透過這個實際的範例，你可以更好地理解和掌握 JavaScript 的物件導向特性。&lt;p&gt;&lt;strong&gt;範例說明：&lt;/strong&gt;&lt;p&gt;這個範例建立了一個 &lt;code&gt;Car&lt;/code&gt; 類別作為基礎類別，然後建立了一個 &lt;code&gt;ElectricCar&lt;/code&gt; 類別來繼承它。這展示了：&lt;ul&gt;&lt;li&gt;如何定義類別和屬性&lt;li&gt;如何使用建構函數初始化物件&lt;li&gt;如何定義公共和私有方法&lt;li&gt;如何使用繼承擴展類別功能&lt;li&gt;如何覆寫父類別的方法&lt;/ul&gt;&lt;h2 id=&quot;重點整理&quot;&gt;重點整理&lt;/h2&gt;&lt;p&gt;以下是 JavaScript 物件導向編程的關鍵概念：&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;類別（Class）&lt;/strong&gt;：用於建立物件的模板，封裝了相關的屬性和方法。類別定義了物件的結構和行為。&lt;li&gt;&lt;p&gt;&lt;strong&gt;公共與私有屬性&lt;/strong&gt;：公共屬性可被外部存取和修改，私有屬性（以 &lt;code&gt;#&lt;/code&gt; 開頭）僅在類別內部可存取，這提供了更好的封裝性。&lt;li&gt;&lt;p&gt;&lt;strong&gt;建構函數（Constructor）&lt;/strong&gt;：在建立實例時自動呼叫的特殊方法，用於初始化物件的屬性。這是建立物件時的第一個步驟。&lt;li&gt;&lt;p&gt;&lt;strong&gt;繼承（Inheritance）&lt;/strong&gt;：使用 &lt;code&gt;extends&lt;/code&gt; 關鍵字讓子類別繼承父類別的屬性和方法。這允許你重用程式碼並建立更複雜的類別層次結構。&lt;li&gt;&lt;p&gt;&lt;strong&gt;靜態方法與屬性&lt;/strong&gt;：屬於類別本身，不需要建立實例即可使用。通常用於工具函數或類別層級的資料。&lt;li&gt;&lt;p&gt;&lt;strong&gt;Getter 和 Setter&lt;/strong&gt;：提供安全的方式存取和修改私有屬性。這允許你在存取屬性時執行額外的邏輯，例如驗證或計算。&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;實際應用：&lt;/strong&gt;&lt;p&gt;透過這些概念，你可以建立結構清晰、易於維護的 JavaScript 程式碼。物件導向編程特別適合：&lt;ul&gt;&lt;li&gt;大型應用程式的開發&lt;li&gt;需要重用程式碼的場景&lt;li&gt;需要模組化和封裝的專案&lt;li&gt;團隊協作開發&lt;/ul&gt;&lt;p&gt;掌握這些概念後，你就能夠寫出更專業、更易於維護的 JavaScript 程式碼。</content>
  </entry>
  <entry>
    <title>如何在 SvelteKit 中管理前端環境變數</title>
    <link href="https://kamadiam.com/sveltekit-env/" />
    <updated>2023-12-30T01:06:48Z</updated>
    <id>https://kamadiam.com/sveltekit-env/</id>
    <content type="html">&lt;p&gt;大家都知道後端節點（如 Node.js）可以輕鬆地透過 &lt;code&gt;.env&lt;/code&gt; 檔案或 &lt;code&gt;process&lt;/code&gt; 物件來存取環境變數。但在純前端應用程式，尤其是使用如 SvelteKit 這樣的現代框架時，這個任務看起來就沒那麼直觀了。本文將介紹如何在 SvelteKit 中有效地管理和存取環境變數。&lt;h2 id=&quot;在-Node.js-中讀取-.env-檔案&quot;&gt;在 Node.js 中讀取 &lt;code&gt;.env&lt;/code&gt; 檔案&lt;/h2&gt;&lt;p&gt;在 Node.js 應用程式中，環境變數通常透過 &lt;code&gt;.env&lt;/code&gt; 檔案來管理。這些變數可以用來儲存應用程式配置、機密鑰匙或其他環境特定的設定。下面是如何在 Node.js 中讀取 &lt;code&gt;.env&lt;/code&gt; 檔案的範例：&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;dotenv&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

dotenv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;YOUR_ENV_VARIABLE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在上述程式碼中，我們使用 &lt;code&gt;dotenv&lt;/code&gt; 函式庫來載入 &lt;code&gt;.env&lt;/code&gt; 檔案中的變數。然後，你可以透過 Node.js 的 &lt;code&gt;process.env&lt;/code&gt; 物件來存取這些變數。&lt;h2 id=&quot;在-SvelteKit-中管理環境變數&quot;&gt;在 SvelteKit 中管理環境變數&lt;/h2&gt;&lt;p&gt;SvelteKit 是一個基於 Svelte 的全端框架，提供了一套更高層次的抽象，特別是在管理環境變數時。在 SvelteKit 中，環境變數不是直接讀取 &lt;code&gt;.env&lt;/code&gt; 檔案中的變數。相反，它們需要透過特定的配置來使其在前端程式碼中可用。&lt;p&gt;SvelteKit 不能直接讀取 &lt;code&gt;.env&lt;/code&gt; 檔案的環境變數，意思是它們不是自動地、直接地從 &lt;code&gt;.env&lt;/code&gt; 檔案讀取並暴露給前端程式碼。這與 Node.js 中的處理方式有所不同，Node.js 可以直接透過 &lt;code&gt;process.env&lt;/code&gt; 存取 &lt;code&gt;.env&lt;/code&gt; 檔案中的變數。&lt;p&gt;在 SvelteKit 中，雖然 &lt;code&gt;.env&lt;/code&gt; 檔案仍然用於定義環境變數，但這些變數需要透過 SvelteKit 和其底層的建置工具（Vite）的特定配置來暴露。有一個重要規則：在 &lt;code&gt;.env&lt;/code&gt; 檔案中定義的變數需要以 &lt;code&gt;PUBLIC_&lt;/code&gt; 開頭，這樣 Vite 才會在建置過程中將它們暴露給前端程式碼。&lt;p&gt;所以，當我們在 SvelteKit 中談論環境變數時，它們確實是在 &lt;code&gt;.env&lt;/code&gt; 檔案中定義的，但它們的暴露和存取方式是由 SvelteKit 和 Vite 的配置決定的，而非直接從 &lt;code&gt;.env&lt;/code&gt; 檔案自動讀取。這是一個重要的安全機制，確保只有明確標記為公開的變數才會暴露給前端。&lt;h2 id=&quot;讀取環境變數範例&quot;&gt;讀取環境變數範例&lt;/h2&gt;&lt;h3 id=&quot;步驟-1:創建-.env-檔案&quot;&gt;步驟 1：創建 &lt;code&gt;.env&lt;/code&gt; 檔案&lt;/h3&gt;&lt;p&gt;首先，在你的 SvelteKit 專案根目錄下創建一個 &lt;code&gt;.env&lt;/code&gt; 檔案。例如：&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;PUBLIC_CLIENT_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test-id&quot;&lt;/span&gt;

&lt;span class=&quot;token constant&quot;&gt;PUBLIC_CALLBACK&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://localhost:5173/oauth2callback&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 SvelteKit 中，所有要公開的環境變數都應以 &lt;code&gt;PUBLIC_&lt;/code&gt; 開頭，這樣它們才會被 Vite（SvelteKit 底層的構建工具）公開給前端。&lt;h3 id=&quot;步驟-2:存取環境變數&quot;&gt;步驟 2：存取環境變數&lt;/h3&gt;&lt;p&gt;在 SvelteKit 應用程式中，可以直接 &lt;code&gt;import&lt;/code&gt; $env/static/public 來存取這些變數：&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PUBLIC_CALLBACK&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PUBLIC_CLIENT_ID&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$env/static/public&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; redirect_uri &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PUBLIC_CALLBACK&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PUBLIC_CLIENT_ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;步驟-3:切換開發環境與正式環境&quot;&gt;步驟 3：切換開發環境與正式環境&lt;/h3&gt;&lt;p&gt;你可以在專案根目錄放兩個 &lt;code&gt;.env&lt;/code&gt; 檔案，分別是 &lt;code&gt;.env&lt;/code&gt; 和 &lt;code&gt;.env.production&lt;/code&gt;。這樣當你在本機開發使用 &lt;code&gt;pnpm run dev&lt;/code&gt; 時，程式會使用 &lt;code&gt;.env&lt;/code&gt; 的變數，而當你使用 &lt;code&gt;pnpm run build&lt;/code&gt; 時，就會改為使用 &lt;code&gt;.env.production&lt;/code&gt; 中的變數。這讓你可以輕鬆地在開發和正式環境之間切換不同的配置。&lt;p&gt;完整說明請參考 &lt;a href=&quot;https://kit.svelte.dev/docs/modules#$env-static-public&quot;&gt;$env/static/public&lt;/a&gt;</content>
  </entry>
</feed>