AI 制作的落地页看起来千篇一律的原因与解决方案
TuBrief 편집팀
2026년 8월 22일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
对于从策划到部署全权包办的独立开发者来说,Cursor 或 Claude Code 就像是救世主。只要敲几行提示词,10分钟内就能凭空变出一个像模像样的网页。
问题接踵而至。当你点击部署按钮并查看屏幕时,会产生一种既视感。紫色渐变按钮、Inter 字体、正中间的三栏卡片布局,到处都是似曾相识的模板气息。表面上看很整洁,但却无法带来用户的付费或注册。人们能敏锐地察觉到那些像是工厂流水线生产出来的页面,然后毫不犹豫地关掉网页。
大语言模型(LLM)基于统计平均值运作。如果不给它设定规则,它就会退回到网络上最常见 Tailwind 默认预设和 Shadcn UI 默认值。“请帮我做一个干净且精致的落地页”这句提示词刚一出口,AI 就会抛出 w-[320px]、top-[117px] 这种不明所以的内联像素值,把布局搞得一团糟。
如果想通过修改提示词来解决这个问题,你会感到身心俱疲。你必须构建一套流水线:在每次生成代码时强制执行品牌规则,并在提交阶段从物理上拦截违规代码。
Cursor 会读取 .cursor/rules/*.mdc,Claude Code 读取 CLAUDE.md,而开源工具则读取 AGENTS.md。如果在这些文件中定义好品牌设计代币(Design Tokens),AI 在代码生成阶段就无法随意使用任意样式。
如果规则文件超过 500 行,每次会话需要加载的上下文成本就会增加,模型的指令遵循率也会下降。因此应当将其精简控制在 200 到 300 行左右。
在项目根目录下创建 .cursor/rules/design-system.mdc 并写入以下内容:
bg-[#123456] or h-[117px].pnpm lint:style to verify token compliance before completing tasks.var(--color-bg-primary) (Tailwind: bg-brand-primary)var(--color-bg-secondary) (Tailwind: bg-brand-secondary)var(--color-text-main) (Tailwind: text-brand-main)var(--color-text-muted) (Tailwind: text-brand-muted)var(--color-accent-default) (Tailwind: bg-brand-accent)var(--space-1): 0.25rem (4px)var(--space-2): 0.5rem (8px)var(--space-4): 1.0rem (16px)var(--space-6): 1.5rem (24px)var(--space-8): 2.0rem (32px)text-brand-h1 -> Font: Inter, Weight: 700, Size: 2.5rem, Tracking: -0.02emtext-brand-body -> Font: Inter, Weight: 400, Size: 1.0rem, Leading: 1.5`
加入这个规则后,AI 直接注入方括号任意值或 Hex 颜色的频率会明显减少。
光靠提示词是不够的。AI 经常会无视规则,悄悄塞入内联像素值。通过将 Stylelint 和 Git Pre-commit 钩子结合起来,可以阻断硬编码样式进入代码仓库的路径。
安装工具并初始化 Husky:
`bash
pnpm add -D husky lint-staged stylelint stylelint-declaration-strict-value
npx husky init
`
在项目根目录下创建 stylelint.config.mjs。该配置的作用是:当出现任意颜色代码或像素值时触发构建错误。
`javascript
import type { Config } from "stylelint";
export default {
plugins: ["stylelint-declaration-strict-value"],
rules: {
"scale-unlimited/declaration-strict-value": [
["/color/", "font-size", "/margin/", "/padding/"],
{
ignoreVariables: false,
ignoreFunctions: false,
ignoreKeywords: {
"": ["transparent", "inherit", "currentColor", "auto", "0"]
},
message: "Design System Violation: Hardcoded value for '{property}' is forbidden. Use CSS Design Tokens instead."
}
]
}
} satisfies Config;
`
在 package.json 中添加 lint-staged 配置:
`json
{
"lint-staged": {
"*.{css,scss,tsx,jsx}": [
"stylelint --fix",
"eslint --max-warnings=0"
]
}
}
`
在 .husky/pre-commit 文件中注册下面这行命令:
`bash
npx lint-staged
`
现在,每次执行 git commit 时都会对暂存的代码进行静态分析。如果存在 AI 擅自加入的 margin: 17px 之类的代码,提交本身就会失败。每周大约可以节省 5 个小时用于修改样式的时间。
静态分析只能检查文本规则。元素重叠或移动端菜单崩坏等问题,必须亲自启动浏览器才能发现。我们不可能每次都手动拉伸缩小视口,因此可以通过 Playwright 自动化进行快照比对。
创建 playwright.config.ts 文件:
`typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/visual',
snapshotPixelRatioTemplate: '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{ext}',
expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.01,
threshold: 0.2,
animations: 'disabled',
},
},
webServer: {
command: 'pnpm dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
projects: [
{ name: 'Desktop Chrome', use: { ...devices['Desktop Chrome'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 13'] } },
],
});
`
编写用于验证 5 个核心 UI 位置的测试脚本(tests/visual/landing-page.spec.ts):
`typescript
import { test, expect } from '@playwright/test';
test.describe('Visual Regression Guardrails', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000');
await page.evaluate(() => document.fonts.ready);
});
test('TC1: 桌面端 Hero 区块渲染', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 });
const heroSection = page.locator('section#hero');
await expect(heroSection).toBeVisible();
await expect(heroSection).toHaveScreenshot('hero-desktop.png', { maxDiffPixelRatio: 0.01 });
});
test('TC2: 移动端导航菜单视口渲染', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
const navBar = page.locator('header#main-nav');
await expect(navBar).toHaveScreenshot('nav-mobile.png');
});
test('TC3: 价格卡片网格对齐', async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 800 });
const pricingGrid = page.locator('div#pricing-cards');
await expect(pricingGrid).toHaveScreenshot('pricing-grid.png', {
mask: [page.locator('.dynamic-price-timestamp')]
});
});
test('TC4: 主 CTA 按钮悬停状态', async ({ page }) => {
const ctaButton = page.locator('button#primary-cta');
await ctaButton.hover();
await expect(ctaButton).toHaveScreenshot('cta-button-hover.png');
});
test('TC5: 登录模态框布局', async ({ page }) => {
await page.click('button#open-login-modal');
const modalDialog = page.locator('div[role="dialog"]');
await expect(modalDialog).toBeVisible();
await expect(modalDialog).toHaveScreenshot('login-modal.png');
});
});
`
在 package.json 中注册命令:
`json
{
"scripts": {
"test:visual": "playwright test",
"test:visual:update": "playwright test --update-snapshots"
}
}
`
只要在终端中敲击一行 pnpm test:visual,就能在 1 分钟内捕捉到桌面端和移动端视口中损坏的布局。这样就能摆脱手动调整屏幕大小、盯到眼花的繁琐检查工作。
通过使用规则文件控制 AI 的输入、利用 Git 钩子防止错误样式的流入、借助 Playwright 检查页面破损,具备这样一套架构后,即使在独立开发项目中也能保持设计的一致性。