Cookbook snippet · tier 2
純 CSS 分頁切換
用 :has() + radio 做分頁,零 JS。被選的分頁內容顯示,其餘隱藏。
Live example
兩個系統的差異主要在
ld binding 順序 —— 當 dlopen 第二個 .so 時,cgi 模式會踩到 binding 雷,worker 不再可被 reuse。p50 差異:morpheus
2.1ms vs synoscgi 5.6ms,**2.7×**。p99 在 reuse 開的條件下差距縮小到 **1.8×**。2021/01 內部 mail《WebAPI Worker Reuse Investigate》是改
env-guard 路徑的源頭;`SZK_ENV_IN_SYNOAPID` 之後才補上。完整食譜 (HTML + JS · 複製改寫用)
Tabs using
:has()+ radio buttons. Zero JS. The selected tab's content is shown via CSS sibling/has selectors.
When to use
- Show 2-5 alternative views of the same concept
- Hide secondary content behind labels (only when not redundant)
- "Code · diagram · prose" triple-view of a single idea
Complete snippet (paste-and-tweak)
<div class="vg-w-tabs-EXAMPLE">
<style>
.vg-w-tabs-EXAMPLE { display: grid; gap: var(--s-2); }
.vg-w-tabs-EXAMPLE input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.vg-w-tabs-EXAMPLE .tabs { display: flex; gap: var(--s-2); border-bottom: 1px solid var(--line); }
.vg-w-tabs-EXAMPLE .tab { font-family: var(--sans); font-size: var(--fs-sm); padding: var(--s-1) var(--s-2); cursor: pointer; color: var(--muted); }
.vg-w-tabs-EXAMPLE .panel { display: none; padding: var(--s-2); }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t1:checked) .panel-1 { display: block; }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t1:checked) [for="vg-w-tabs-EXAMPLE-t1"] { color: var(--accent-text); border-bottom: 2px solid var(--accent); }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t2:checked) .panel-2 { display: block; }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t2:checked) [for="vg-w-tabs-EXAMPLE-t2"] { color: var(--accent-text); border-bottom: 2px solid var(--accent); }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t3:checked) .panel-3 { display: block; }
.vg-w-tabs-EXAMPLE:has(#vg-w-tabs-EXAMPLE-t3:checked) [for="vg-w-tabs-EXAMPLE-t3"] { color: var(--accent-text); border-bottom: 2px solid var(--accent); }
</style>
<input type="radio" id="vg-w-tabs-EXAMPLE-t1" name="vg-w-tabs-EXAMPLE-sel" checked />
<input type="radio" id="vg-w-tabs-EXAMPLE-t2" name="vg-w-tabs-EXAMPLE-sel" />
<input type="radio" id="vg-w-tabs-EXAMPLE-t3" name="vg-w-tabs-EXAMPLE-sel" />
<div class="tabs">
<label class="tab" for="vg-w-tabs-EXAMPLE-t1">code</label>
<label class="tab" for="vg-w-tabs-EXAMPLE-t2">diagram</label>
<label class="tab" for="vg-w-tabs-EXAMPLE-t3">prose</label>
</div>
<div class="panel panel-1">code goes here</div>
<div class="panel panel-2">diagram goes here</div>
<div class="panel panel-3">prose goes here</div>
</div>
Gotchas
- All three views must add value — if one is redundant with the surrounding prose, delete it.
nameattribute on radios must match across all in the group; use the widget id as the prefix to avoid collision with other widgets on the same page.- Don't use tabs when 2-3 things should be visible at once — side-by-side is often better.
:has()browser support is broad in 2026 (Chromium, Safari, Firefox). Safe.