整页搭配
给 AI 的 Markdown用户要做一整页(一个首页、一个落地页、一个后台页),不知道几个组件放在一起怎么搭时,照这四套改。每套都是从上到下的结构、每块用什么、关键代码;组件的参数和装法看各自的说明。
四套都守同样的规矩:一页一个主角,点缀最多三个,手机上没有看不到的内容,开了减弱动态效果内容全在。表里的导航和基础手感(缓动、滚动出现、悬停上浮)不算在「挑 1 到 3 个」里,算数的只有主角和点缀;表里列了二选一、可选的,挑最贴的一个,不要全上。照抄结构,文字、图片、颜色换成用户自己的;风格和配色先按「风格顾问」定,别直接用这里示例的颜色。
一、本地小店首页(咖啡店、餐厅、门店、工作室)
客人多半从地图、点评点进来,用手机看。首屏不放要等的大动效,一张好照片就是主角。
| 位置 | 用什么 | 要点 |
|---|---|---|
| 顶部 | 顶部导航栏 Navbar,手机上 汉堡菜单 Hamburger Menu | 入口 3 到 5 个:菜单、关于、到店、预约 |
| 首屏 | 不用组件:好照片加店名、营业时间、两个按钮 | 第一眼就看到店名和按钮 |
| 品牌故事 | 逐字点亮 Scroll Text Highlight | 50 到 150 字,强调色换成店的颜色 |
| 数字 | 数字滚动 Count Up | 只放真实数字:开店几年、卖出多少杯 |
| 菜单、环境照片 | 滚动出现 Scroll Reveal | 同一排依次出现 |
| 地址、营业时间、电话 | 不加动效 | 客人要马上看清 |
| 全站 | 缓动 Easing | 过渡统一成先快后慢 |
首屏(不用组件,照片压到 300KB 以内):
<section className="relative grid min-h-svh items-end">
<img src="/images/hero.jpg" alt="店里的吧台" className="absolute inset-0 size-full object-cover" />
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
<div className="relative px-6 pb-14 text-white md:px-12">
<h1 className="text-4xl font-black md:text-6xl">店名</h1>
<p className="mt-3 text-white/85">每天 8:00–20:00 · 地址</p>
<div className="mt-6 flex gap-3">
<a href="#menu" className="rounded-full bg-white px-6 py-3 text-sm font-bold text-stone-900">看菜单</a>
<a href="地图链接" className="rounded-full border border-white/70 px-6 py-3 text-sm font-bold">到店路线</a>
</div>
</div>
</section>
故事和数字:
const {ref, inView} = useInView<HTMLDivElement>();
<section className="px-6 py-28">
<ScrollHighlight text={STORY} accent={['最想强调的词']} className="mx-auto max-w-3xl text-[26px] font-bold leading-[1.55] md:text-[40px] [--hl:#B4642D]" />
<div ref={ref} className="mx-auto mt-16 grid max-w-3xl grid-cols-3 text-center">
<div><b className="text-4xl"><CountUp to={6} run={inView} suffix=" 年" /></b><p>开店</p></div>
<div><b className="text-4xl"><CountUp to={12} run={inView} delay={150} suffix=" 万杯" /></b><p>卖出</p></div>
<div><b className="text-4xl"><CountUp to={4.9} decimals={1} run={inView} delay={300} /></b><p>点评</p></div>
</div>
</section>
菜单每张卡外面包一层 <Reveal delay={(i % 3) * 60}>。
二、作品集首页(设计师、摄影、工作室)
电脑访问为主,首屏要有一个让人记住的主角,作品区安静地让作品说话。
| 位置 | 用什么 | 要点 |
|---|---|---|
| 顶部 | 顶部导航栏 Navbar,入口少;手机上 汉堡菜单 Hamburger Menu | 名字、作品、关于、联系 |
| 首屏(主角) | 图片拖尾 Image Trail | 8 张以上好图,不能重复;手机上换成一张静态大图 |
| 作品区 | 滚动出现 Scroll Reveal + 悬停上浮 Hover Lift | 同一页里作品区不再放主角 |
| 作品详情 | 共享元素转场 Shared Element Transition | 点作品卡,图飞到详情页 |
| 联系按钮 | 磁吸 Magnetic | 只给这一个按钮 |
| 全站(可选) | 光标跟随 Custom Cursor | 和图片拖尾都跟鼠标,二选一;选了图片拖尾就不加 |
首屏:
const TRAIL = ['01', '02', '03', '04', '05', '06', '07', '08'].map((n) => `/works/${n}.webp`);
<ImageTrail images={TRAIL} className="h-svh">
{/* 没有鼠标的设备铺一张代表作 */}
<img src="/works/01.webp" alt="" className="absolute inset-0 hidden size-full object-cover opacity-40 [@media(hover:none)]:block" />
<div className="relative grid h-full place-items-center px-6 text-center">
<h1 className="text-5xl font-black md:text-8xl">你的名字</h1>
</div>
</ImageTrail>
作品区:
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{WORKS.map((w, i) => (
<Reveal key={w.title} delay={(i % 3) * 60}>
{/* 浅色网站传 tone="light";用路由时传 as={Link} */}
<LiftCard href={w.href} className="p-3">
<img src={w.img} alt={w.title} className="aspect-[4/3] w-full rounded-2xl object-cover" />
<p className="px-2 pb-2 pt-4 font-bold">{w.title}</p>
</LiftCard>
</Reveal>
))}
</div>
联系按钮:<Magnetic><a href="mailto:…" className="…">联系我</a></Magnetic>,感应范围不占位置,直接包住原来的按钮。
三、软件产品落地页(SaaS、AI 工具)
用户来判断"靠不靠谱、值不值"。首屏一个氛围主角,下面每一块都在讲清楚功能和价格。
| 位置 | 用什么 | 要点 |
|---|---|---|
| 顶部 | 吸顶导航 Sticky Header,功能多时加 超级菜单 Mega Menu | 右边一个主按钮「免费试用」 |
| 首屏(主角) | 流体背景 Fluid Background(柔和)或 点阵波纹 Dot Grid(开发者) | 标题和按钮第一眼就在 |
| 首屏标题 | 打字机 Typewriter 轮换后半句(可选) | 和乱码解码二选一 |
| 首屏按钮 | 磁吸 Magnetic | 只给主按钮 |
| 客户 Logo | 跑马灯 Marquee | 5 个以上 |
| 功能 | 滚动叙事 Scroll Storytelling(每个功能一张截图)或深色卡片加 聚光 Spotlight | 二选一 |
| 数字 | 数字滚动 Count Up | 3 到 4 个真实数字 |
| 价格 | 推荐的那一档加 边缘流光 Border Beam | 只给一张 |
| 其余段落 | 滚动出现 Scroll Reveal | — |
首屏:左边一句话加按钮,右边放产品真实的样子(一张截图或一个能动的演示卡)。别做成「居中大标题加紫色光斑」,那是 AI 产品最常见的默认样子;背景颜色用风格顾问定的品牌色。
// 颜色写在组件外面:每次渲染传新数组,流体背景会重新开始
const FLUID: [string, string, string, string] = ['#0B0A09', '#2A1A12', '#7A3A1C', '#E09A4B']; // 换成品牌色
<section className="relative isolate min-h-svh overflow-hidden text-white">
<FluidBackground colors={FLUID} speed={0.6} className="absolute inset-0 -z-10" />
<div className="mx-auto grid min-h-svh max-w-6xl items-center gap-12 px-6 lg:grid-cols-2">
<div>
<h1 className="text-5xl font-black leading-tight md:text-6xl">一句话说清它帮人做什么</h1>
<p className="mt-5 text-white/70">再一句说清给谁用、省了什么事</p>
<Magnetic className="mt-9"><a href="/signup" className="inline-block rounded-full bg-white px-8 py-4 font-bold text-black">免费试用</a></Magnetic>
</div>
{/* 右边:产品截图,或者用打字机做一个会自己演示的卡片 */}
</div>
</section>
四、后台列表页(管理系统、数据表格)
用户天天用,要快、要稳。不放主角和点缀,只做手感。
| 位置 | 用什么 | 要点 |
|---|---|---|
| 左边 | 侧边栏 Sidebar | 分组、可折叠;手机上用汉堡菜单打开 |
| 顶部 | 面包屑 Breadcrumb | 告诉用户在第几层 |
| 同一条记录的几组信息 | 标签页 Tabs | 详情、日志、设置 |
| 表格加载 | 流光 Shimmer 的骨架屏 | 只在第一次没数据、超过 0.3 秒时显示 |
| 筛选、排序、增删 | 布局动画 Layout Animation | 0.2 秒、不过冲;翻页直接换 |
| 翻页 | 分页 Pagination | 翻页后滚回表格顶部 |
| 开关、收藏 | 弹性 Spring | 删除确认这类弹窗不弹跳 |
| 全站 | 缓动 Easing | 所有过渡 0.15 到 0.2 秒 |
全站曲线(Tailwind v4,写在入口的 CSS 里,现有的 transition 全部跟着变):
@theme {
--default-transition-timing-function: cubic-bezier(.22, 1, .36, 1);
--default-transition-duration: 180ms;
--ease-out: cubic-bezier(.22, 1, .36, 1);
}
表格:
function Rows({rows}: {rows: Order[]}) {
// 0.2 秒、不过冲:后台用这一组参数
const root = useFlip(rows.map((r) => r.id).join(','), {duration: 200, easing: 'cubic-bezier(.22,1,.36,1)'});
return (
<tbody ref={root as never}>
{rows.map((r) => <tr key={r.id} data-flip={String(r.id)}>{/* 原来的单元格 */}</tr>)}
</tbody>
);
}
<table className={loading && rows.length ? 'opacity-60 transition-opacity' : ''} aria-busy={loading}>
<thead>{/* 原来的表头 */}</thead>
{loading && !rows.length
? <tbody>{Array.from({length: 8}, (_, i) => <tr key={i}><td colSpan={4} className="p-3"><Skeleton className="h-4 w-full" /></td></tr>)}</tbody>
: <Rows key={page} rows={rows} />}
</table>
- 骨架屏只在第一次没数据时出现;之后筛选、排序、翻页重新请求时,旧数据留着、变淡一点。
key={page}:翻页时整张表直接换,不播动画;同一页里的筛选、排序、增删才会滑。