<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>UI on Tarragon</title><link>https://tarrragon.github.io/blog/tags/ui/</link><description>Recent content in UI on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Sat, 25 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/ui/index.xml" rel="self" type="application/rss+xml"/><item><title>從色塊 placeholder 開始的漸進式 UI 除錯</title><link>https://tarrragon.github.io/blog/report/placeholder-driven-ui-debug/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/report/placeholder-driven-ui-debug/</guid><description>&lt;h2 id="核心原則">核心原則&lt;/h2>
&lt;p>&lt;strong>UI 除錯的最小可驗證單位是「一個有明顯邊界的色塊」。&lt;/strong> 版型用色塊先驗證 grid / flex / absolute 是否如預期排在該在的位置，確定後再串實際內容。一次組裝完整 UI 在版型錯時 debug 困難 — 顏色、字型、邊距、padding 全部一起出問題、根因混雜難辨。&lt;/p>
&lt;hr>
&lt;h2 id="為什麼色塊比實際內容更適合-debug">為什麼色塊比實際內容更適合 debug&lt;/h2>
&lt;h3 id="商業邏輯">商業邏輯&lt;/h3>
&lt;p>UI 由「位置、尺寸、視覺樣式、互動」四層組成。Debug 時要分層處理 — 一次只解一層、解完再下一層。&lt;/p>
&lt;p>色塊把後三層都拿掉、只留「位置與尺寸」 — 看到的就是 layout 規則的純粹結果。實際內容把所有層混在一起、看到的位置可能受字型 advance、line-height、margin collapse 等多重因素影響、難以歸因。&lt;/p>
&lt;h3 id="漸進式組裝順序">漸進式組裝順序&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;th>驗證重點&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>色塊（紅 / 藍背景、固定 width / height）&lt;/td>
 &lt;td>grid / flex / absolute 排對位置嗎？&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>加 placeholder 文字&lt;/td>
 &lt;td>文字尺寸符合預期嗎？換行行為對嗎？&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>加 padding / border / 圓角等視覺樣式&lt;/td>
 &lt;td>視覺樣式不破壞 layout 嗎？&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4&lt;/td>
 &lt;td>換上實際內容 / 接上資料&lt;/td>
 &lt;td>動態內容變動時 layout 還對嗎？&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5&lt;/td>
 &lt;td>加互動（hover / click / focus）&lt;/td>
 &lt;td>互動狀態下 layout 還對嗎？&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>每階段獨立驗證、有問題就停在那階段修。&lt;/p>
&lt;hr>
&lt;h2 id="這次任務的實際應用">這次任務的實際應用&lt;/h2>
&lt;h3 id="觀察">觀察&lt;/h3>
&lt;p>要驗證搜尋頁的版型：「左側 filter sidebar + 右側中央內容（H1、search input、results）」。&lt;/p>
&lt;p>第一次嘗試：直接把 Pagefind UI 組起來、調 CSS。結果版型錯時不知道是哪層問題 — 是 grid 排序錯？是 sidebar 寬度錯？是 padding 推到位置不對？&lt;/p>
&lt;h3 id="判讀">判讀&lt;/h3>
&lt;p>退回最小可驗證單位：把 filter 整個換成一個寫死寬度的紅色色塊：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">aside&lt;/span> &lt;span class="na">class&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;search-filter-debug&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> filter 區（先寫死寬度與底色驗證版型）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">aside&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nc">search-filter-debug&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> &lt;span class="k">width&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">400&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &lt;span class="k">background&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">red&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> &lt;span class="k">min-height&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">240&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> &lt;span class="k">position&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">absolute&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> &lt;span class="c">/* ... */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>紅色背景一眼看出色塊在哪 — 確認了：&lt;/p>
&lt;ul>
&lt;li>色塊在 main 左外側（符合）&lt;/li>
&lt;li>色塊頂端對齊 H1（符合）&lt;/li>
&lt;li>寬度 400px、與 main 間距 2rem（符合）&lt;/li>
&lt;/ul>
&lt;p>版型驗證後再換上實際 filter UI。&lt;/p>
&lt;h3 id="執行的迭代步驟">執行的迭代步驟&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>步驟&lt;/th>
 &lt;th>動作&lt;/th>
 &lt;th>驗證&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>紅色色塊代替 filter&lt;/td>
 &lt;td>layout 對嗎？看色塊的位置&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>色塊頂端對齊 results 頂端（用 padding-top）&lt;/td>
 &lt;td>對齊基準對嗎？看頂緣連線&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>確認多 viewport 下色塊行為&lt;/td>
 &lt;td>響應式 OK 嗎？拉視窗&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4&lt;/td>
 &lt;td>拿掉色塊、JS 把 pagefind filter 搬進來&lt;/td>
 &lt;td>真實內容套上後位置一致嗎？&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5&lt;/td>
 &lt;td>細部視覺調整（邊框、間距）&lt;/td>
 &lt;td>視覺樣式 OK 嗎？&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>每步只驗證一件事、有問題就停。&lt;/p>
&lt;hr>
&lt;h2 id="內在屬性比較兩種除錯起點">內在屬性比較：兩種除錯起點&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>起點&lt;/th>
 &lt;th>Debug 難度&lt;/th>
 &lt;th>修復速度&lt;/th>
 &lt;th>適用情境&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>一次組裝完整 UI&lt;/td>
 &lt;td>高 — 多層問題交織&lt;/td>
 &lt;td>慢 — 不知該改哪層&lt;/td>
 &lt;td>UI 簡單、一次到位有把握&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>從色塊漸進組裝&lt;/td>
 &lt;td>低 — 每階段問題單純&lt;/td>
 &lt;td>快 — 一次解一個&lt;/td>
 &lt;td>複雜 layout、多元件協作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>漸進的成本是「多寫一個過渡版本」、收益是「debug 範圍縮到最小」&lt;/strong>。多元件 layout 永遠選漸進。&lt;/p></description><content:encoded><![CDATA[<h2 id="核心原則">核心原則</h2>
<p><strong>UI 除錯的最小可驗證單位是「一個有明顯邊界的色塊」。</strong> 版型用色塊先驗證 grid / flex / absolute 是否如預期排在該在的位置，確定後再串實際內容。一次組裝完整 UI 在版型錯時 debug 困難 — 顏色、字型、邊距、padding 全部一起出問題、根因混雜難辨。</p>
<hr>
<h2 id="為什麼色塊比實際內容更適合-debug">為什麼色塊比實際內容更適合 debug</h2>
<h3 id="商業邏輯">商業邏輯</h3>
<p>UI 由「位置、尺寸、視覺樣式、互動」四層組成。Debug 時要分層處理 — 一次只解一層、解完再下一層。</p>
<p>色塊把後三層都拿掉、只留「位置與尺寸」 — 看到的就是 layout 規則的純粹結果。實際內容把所有層混在一起、看到的位置可能受字型 advance、line-height、margin collapse 等多重因素影響、難以歸因。</p>
<h3 id="漸進式組裝順序">漸進式組裝順序</h3>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>內容</th>
          <th>驗證重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>色塊（紅 / 藍背景、固定 width / height）</td>
          <td>grid / flex / absolute 排對位置嗎？</td>
      </tr>
      <tr>
          <td>2</td>
          <td>加 placeholder 文字</td>
          <td>文字尺寸符合預期嗎？換行行為對嗎？</td>
      </tr>
      <tr>
          <td>3</td>
          <td>加 padding / border / 圓角等視覺樣式</td>
          <td>視覺樣式不破壞 layout 嗎？</td>
      </tr>
      <tr>
          <td>4</td>
          <td>換上實際內容 / 接上資料</td>
          <td>動態內容變動時 layout 還對嗎？</td>
      </tr>
      <tr>
          <td>5</td>
          <td>加互動（hover / click / focus）</td>
          <td>互動狀態下 layout 還對嗎？</td>
      </tr>
  </tbody>
</table>
<p>每階段獨立驗證、有問題就停在那階段修。</p>
<hr>
<h2 id="這次任務的實際應用">這次任務的實際應用</h2>
<h3 id="觀察">觀察</h3>
<p>要驗證搜尋頁的版型：「左側 filter sidebar + 右側中央內容（H1、search input、results）」。</p>
<p>第一次嘗試：直接把 Pagefind UI 組起來、調 CSS。結果版型錯時不知道是哪層問題 — 是 grid 排序錯？是 sidebar 寬度錯？是 padding 推到位置不對？</p>
<h3 id="判讀">判讀</h3>
<p>退回最小可驗證單位：把 filter 整個換成一個寫死寬度的紅色色塊：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">&lt;</span><span class="nt">aside</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;search-filter-debug&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  filter 區（先寫死寬度與底色驗證版型）
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="p">&lt;/</span><span class="nt">aside</span><span class="p">&gt;</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">.</span><span class="nc">search-filter-debug</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  <span class="k">width</span><span class="p">:</span> <span class="mi">400</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">  <span class="k">min-height</span><span class="p">:</span> <span class="mi">240</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">  <span class="k">position</span><span class="p">:</span> <span class="kc">absolute</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">  <span class="c">/* ... */</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>紅色背景一眼看出色塊在哪 — 確認了：</p>
<ul>
<li>色塊在 main 左外側（符合）</li>
<li>色塊頂端對齊 H1（符合）</li>
<li>寬度 400px、與 main 間距 2rem（符合）</li>
</ul>
<p>版型驗證後再換上實際 filter UI。</p>
<h3 id="執行的迭代步驟">執行的迭代步驟</h3>
<table>
  <thead>
      <tr>
          <th>步驟</th>
          <th>動作</th>
          <th>驗證</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>紅色色塊代替 filter</td>
          <td>layout 對嗎？看色塊的位置</td>
      </tr>
      <tr>
          <td>2</td>
          <td>色塊頂端對齊 results 頂端（用 padding-top）</td>
          <td>對齊基準對嗎？看頂緣連線</td>
      </tr>
      <tr>
          <td>3</td>
          <td>確認多 viewport 下色塊行為</td>
          <td>響應式 OK 嗎？拉視窗</td>
      </tr>
      <tr>
          <td>4</td>
          <td>拿掉色塊、JS 把 pagefind filter 搬進來</td>
          <td>真實內容套上後位置一致嗎？</td>
      </tr>
      <tr>
          <td>5</td>
          <td>細部視覺調整（邊框、間距）</td>
          <td>視覺樣式 OK 嗎？</td>
      </tr>
  </tbody>
</table>
<p>每步只驗證一件事、有問題就停。</p>
<hr>
<h2 id="內在屬性比較兩種除錯起點">內在屬性比較：兩種除錯起點</h2>
<table>
  <thead>
      <tr>
          <th>起點</th>
          <th>Debug 難度</th>
          <th>修復速度</th>
          <th>適用情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一次組裝完整 UI</td>
          <td>高 — 多層問題交織</td>
          <td>慢 — 不知該改哪層</td>
          <td>UI 簡單、一次到位有把握</td>
      </tr>
      <tr>
          <td>從色塊漸進組裝</td>
          <td>低 — 每階段問題單純</td>
          <td>快 — 一次解一個</td>
          <td>複雜 layout、多元件協作</td>
      </tr>
  </tbody>
</table>
<p><strong>漸進的成本是「多寫一個過渡版本」、收益是「debug 範圍縮到最小」</strong>。多元件 layout 永遠選漸進。</p>
<hr>
<h2 id="色塊的設計要點">色塊的設計要點</h2>
<h3 id="1-顏色明顯易於辨識">1. 顏色明顯、易於辨識</h3>
<p>紅色、洋紅、亮藍 — 跟頁面其他元素差異大。debug 完拿掉、不影響正式設計。</p>
<h3 id="2-邊界清楚">2. 邊界清楚</h3>
<p>寫死 width / height / min-height、不要讓色塊「自適應」 — 自適應時看不出色塊本身有沒有按預期擺放（可能是它縮成 0 還是真的擺對位置）。</p>
<h3 id="3-內含可辨識的標籤">3. 內含可辨識的標籤</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">&lt;</span><span class="nt">aside</span><span class="p">&gt;</span>filter 區（先寫死寬度與底色驗證版型）<span class="p">&lt;/</span><span class="nt">aside</span><span class="p">&gt;</span></span></span></code></pre></div><p>文字標明這是什麼、目前是「驗證版型」狀態 — 不會被誤認為正式設計。</p>
<h3 id="4-拆解成最小可驗證的單位">4. 拆解成最小可驗證的單位</h3>
<p>要驗證「左欄 + 右欄」就用兩個色塊。不要在第一階段就加 filter 內容、search input 等元件 — 那些是後續階段。</p>
<hr>
<h2 id="設計取捨ui-debug-的起點選擇">設計取捨：UI debug 的起點選擇</h2>
<p>四種做法、各自機會成本不同。這個專案選 A（色塊漸進組裝）當預設、其他做法在特定情境合理。</p>
<h3 id="a色塊-placeholder-漸進組裝這個專案的預設">A：色塊 placeholder 漸進組裝（這個專案的預設）</h3>
<ul>
<li><strong>機制</strong>：先用寫死寬度的彩色色塊代替每個區塊、確認 layout 後再加內容、再加樣式</li>
<li><strong>選 A 的理由</strong>：每階段只解一個問題、debug 範圍縮到最小</li>
<li><strong>適合</strong>：複雜 layout、多元件協作、不確定 layout 規則對不對</li>
<li><strong>代價</strong>：多一個過渡版本、總時間略長（但 debug 時間短得多）</li>
</ul>
<h3 id="b一次組裝完整-ui">B：一次組裝完整 UI</h3>
<ul>
<li><strong>機制</strong>：直接把 layout + 內容 + 樣式全部寫好、看結果</li>
<li><strong>跟 A 的取捨</strong>：B 一次到位（如果一次對）、A 漸進；B 在版型錯時 debug 困難（多層問題交織）</li>
<li><strong>B 比 A 好的情境</strong>：簡單 layout（&lt; 3 元件、無複雜共存）、有 100% 把握一次到位</li>
</ul>
<h3 id="c用-wireframe-工具figma--sketch">C：用 wireframe 工具（Figma / Sketch）</h3>
<ul>
<li><strong>機制</strong>：先在設計工具畫 wireframe、確認設計後再進實作</li>
<li><strong>跟 A 的取捨</strong>：C 在設計階段確認、A 在實作階段確認；C 適合「設計尚未確定」、A 適合「設計確定但實作有 layout 風險」</li>
<li><strong>C 比 A 好的情境</strong>：設計階段 — 還沒進實作、不確定要做什麼</li>
</ul>
<h3 id="d直接用真實內容-debug-版型">D：直接用真實內容 debug 版型</h3>
<ul>
<li><strong>機制</strong>：拿真實 pagefind UI / 文章內容當 debug 對象</li>
<li><strong>成本特別高的原因</strong>：內容自帶字型 / padding / margin、跟版型問題混在一起、debug 從哪下手都可能錯</li>
<li><strong>D 是反模式</strong>：真實內容適合驗證、不適合 debug — 內容自帶字型 / padding / margin、跟版型問題混在一起、debug 從哪下手都可能錯</li>
</ul>
<hr>
<h2 id="判讀徵兆">判讀徵兆</h2>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>對應的階段問題</th>
          <th>第一個該嘗試的動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Layout 一試就錯、不知改哪</td>
          <td>沒做色塊驗證、多層問題交織</td>
          <td>退回色塊 placeholder、單獨驗證 layout</td>
      </tr>
      <tr>
          <td>改 padding 視覺對了、互動後又壞</td>
          <td>樣式調整跑在 layout 確認之前</td>
          <td>退回最簡 layout、確認穩定後再加樣式</td>
      </tr>
      <tr>
          <td>真實內容套上後位置變了</td>
          <td>內容尺寸跟色塊預設不一樣</td>
          <td>量真實內容尺寸、回頭調 layout 規則或固定容器尺寸</td>
      </tr>
      <tr>
          <td>Debug 時間遠超估算</td>
          <td>起點選錯（從複雜 UI 開始）</td>
          <td>退到色塊重來、會比繼續調快</td>
      </tr>
  </tbody>
</table>
<p><strong>核心原則</strong>：UI 除錯的速度跟「起點的簡單度」成正比。從色塊出發、永遠比從完整 UI 出發快。</p>
<p>跟 <a href="../verification-timeline-checkpoints/">#68 驗收的時間軸</a> 的關係：placeholder 漸進是 Checkpoint 2「開發中」的具體做法 — 每階段只引入一個變數、邏輯錯誤跟視覺錯誤能即時 catch。跳階段（直接寫真實內容 + 完整樣式）= 把開發中 checkpoint collapse 成單次驗收、漏掉的失敗會推到 ship 前 / ship 後。</p>
]]></content:encoded></item></channel></rss>