Animated Tabs
介绍
指示条用 transform 平移和缩放跟随当前标签,面板淡入上移。
纯 HTML、CSS 与少量原生 JS,没有框架依赖。复制提示词交给 Claude Code、Cursor、Trae 或 Codex,模型会把 Animated Tabs 加进你的项目并换成你的配色。
适用场景
官网顶部导航、标签切换、分段控制、侧边导航和页脚。
安装
订阅 Builder 后,用 8pt CLI 装进项目,或在已接入 8pt MCP 的编辑器里直接调用。
$ npm i -g @8pt-dev/cli && 8pt add animated-tabs
mcp › 使用 8pt MCP 调用 get_component("animated-tabs")
代码
Animated Tabs 的源码,动效只用 transform 与 opacity,并尊重减少动态效果设置。
<div class="x-tabs">
<div class="x-tabs__list" role="tablist">
<button role="tab" aria-selected="true">概览</button>
<button role="tab">组件</button>
<button role="tab">Skill</button>
<button role="tab">MCP</button>
<span class="x-tabs__ink" aria-hidden="true"></span>
</div>
<div class="x-tabs__panels">
<div class="on"><b>概览</b><p>两条货架:UI 与 Skill。</p></div>
<div><b>组件</b><p>可直接运行的原生组件。</p></div>
<div><b>Skill</b><p>可复用的完整工作流程。</p></div>
….x-tabs{width:min(400px,100%);color:var(--d-fg,#fff)}
.x-tabs__list{position:relative;display:flex;gap:4px;border-bottom:1px solid var(--d-line,rgba(255,255,255,.1))}
.x-tabs__list button{padding:12px 14px;border:0;background:transparent;color:var(--d-muted,#a0a0ab);font:600 14px/1 var(--d-font,system-ui,sans-serif);cursor:pointer;transition:color .25s}
.x-tabs__list button[aria-selected=true]{color:var(--d-fg,#fff)}
.x-tabs__ink{position:absolute;left:0;bottom:-1px;width:100px;height:2px;border-radius:2px;background:var(--d-accent,#4D74FF);transform-origin:left;transition:transform .45s cubic-bezier(.2,.9,.2,1)}
.x-tabs__panels{display:grid;padding-top:18px}
.x-tabs__panels>div{grid-area:1/1;opacity:0;transform:translateY(8px);transition:opacity .3s,transform .35s cubic-bezier(.2,.9,.2,1);pointer-events:none}
.x-tabs__panels>div.on{opacity:1;transform:none;pointer-events:auto}
.x-tabs__panels b{font:600 16px/1.3 var(--d-font,system-ui,sans-serif)}
.x-tabs__panels p{margin:6px 0 0;font:14px/1.6 var(--d-font,system-ui,sans-serif);color:var(--d-muted,#a0a0ab)}const init = (root) => {
const list = root.querySelector('.x-tabs__list'), tabs = [...list.querySelectorAll('button')];
const ink = list.querySelector('.x-tabs__ink'), panels = root.querySelectorAll('.x-tabs__panels > div');
const go = (i) => {
const t = tabs[i];
ink.style.transform = `translateX(${t.offsetLeft}px) scaleX(${t.offsetWidth / 100})`;
tabs.forEach((x, j) => x.setAttribute('aria-selected', String(i === j)));
panels.forEach((p, j) => p.classList.toggle('on', i === j));
};
tabs.forEach((t, i) => t.addEventListener('click', () => go(i)));
const ro = new ResizeObserver(() => go(Math.max(0, tabs.findIndex(t => t.getAttribute('aria-selected') === 'true'))));
ro.observe(list);
…订阅 Builder 查看完整源码。查看价格