Warum von KI erstellte Landingpages alle gleich aussehen und die Lösung dafür
TuBrief 편집팀
2026년 8월 22일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
Für Solopreneure, die alles von der Konzeption bis zum Deployment alleine stemmen, wirken Cursor oder Claude Code wie Lebensretter. Ein paar Zeilen Prompt und in nur 10 Minuten steht eine überzeugende Website.
Das Problem kommt danach. Werden Sie den Deploy-Button drücken und auf den Bildschirm blicken, stellt sich ein Déjà-vu ein. Lila Farbverlaufs-Buttons, die Inter-Font, ein dreispaltiges Kartenlayout exakt in der Mitte. Es riecht nach einer Vorlage, die man irgendwo schon mal gesehen hat. Äußerlich sieht alles sauber aus, aber es führt nicht zu Käufen oder Registrierungen von Nutzern. Die Leute merken sofort, wenn eine Seite wie aus der Fabrik gedruckt aussieht, und schließen den Tab.
LLMs arbeiten auf Basis statistischer Mittelwerte. Wenn man ihnen keine Regeln vorgibt, fallen sie auf die im Web am häufigsten verwendeten Tailwind-Standard-Presets und Shadcn UI-Standardwerte zurück. Sobald man den Prompt „Erstelle eine saubere und stylische Landingpage“ wirft, spuckt die KI unidentifizierbare Inline-Pixelwerte wie w-[320px] oder top-[117px] aus und ruiniert das Layout.
Versucht man, dieses Problem durch Prompt-Anpassungen zu lösen, wird man schnell müde. Man muss eine Pipeline aufbauen, die bei jeder Code-Generierung Design-Regeln erzwingt und regelwidrigen Code im Commit-Schritt physisch blockiert.
Cursor liest .cursor/rules/*.mdc, Claude Code liest CLAUDE.md und Open-Source-Tools lesen AGENTS.md. Wenn man in diesen Dateien Markendesign-Tokens definiert, hindert das die KI daran, ab dem Code-Generierungsschritt beliebige Styles zu verwenden.
Wenn eine Regeldatei 500 Zeilen überschreitet, steigen die Kosten für den Kontext, der bei jeder Sitzung eingelesen werden muss, und die Befolgungseigenschaft des Modells sinkt. Sie sollte übersichtlich um die 200 bis 300 Zeilen lang verfasst sein.
Erstellen Sie .cursor/rules/design-system.mdc im Stammverzeichnis des Projekts und fügen Sie den folgenden Inhalt ein:
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`
Wenn Sie diese Regel einfügen, sinkt die Häufigkeit, mit der die KI willkürliche Werte in Klammern oder Hex-Codes direkt einfügt, spürbar.
Prompts allein reichen nicht aus. Die KI ignoriert oft Regeln und schummelt sich heimlich Inline-Pixelwerte ein. Durch die Verknüpfung von Stylelint und Git Pre-commit Hooks blockieren Sie den Weg für hartcodierte Styles in Ihr Repository.
Installieren Sie die Tools und initialisieren Sie Husky:
`bash
pnpm add -D husky lint-staged stylelint stylelint-declaration-strict-value
npx husky init
`
Erstellen Sie stylelint.config.mjs im Stammverzeichnis des Projekts. Dies ist eine Konfiguration, die einen Build-Fehler auslöst, falls beliebige Farb- oder Pixelwerte eingegeben werden:
`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;
`
Fügen Sie die lint-staged-Konfiguration zur package.json hinzu:
`json
{
"lint-staged": {
"*.{css,scss,tsx,jsx}": [
"stylelint --fix",
"eslint --max-warnings=0"
]
}
}
`
Registrieren Sie die folgende einzelne Zeile in der Datei .husky/pre-commit:
`bash
npx lint-staged
`
Jedes Mal, wenn Sie nun git commit ausführen, wird der gestagte Code statisch analysiert. Sollte sich Code wie margin: 17px eingeschlichen haben, den die KI eigenmächtig eingefügt hat, schlägt der Commit selbst fehl. Dadurch können Sie schätzungsweise 5 Stunden pro Woche an Zeit einsparen, die sonst für Style-Korrekturen draufgegangen wären.
Die statische Analyse prüft nur Textregeln. Probleme wie sich überlappende Elemente oder auf Mobilbildschirmen kaputte Menüs erfordern es, den Browser tatsächlich zu starten. Da man den Viewport nicht jedes Mal manuell verkleinern und vergrößern kann, wird der Snapshot-Vergleich mit Playwright automatisiert.
Erstellen Sie die Datei 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'] } },
],
});
`
Schreiben Sie das Testskript zur Überprüfung von 5 zentralen UI-Bereichen (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: Desktop Hero Section Rendering', 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: Mobile Navigation Menu Viewport Rendering', 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: Pricing Card Grid Alignment', 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: Main CTA Button Hover State', async ({ page }) => {
const ctaButton = page.locator('button#primary-cta');
await ctaButton.hover();
await expect(ctaButton).toHaveScreenshot('cta-button-hover.png');
});
test('TC5: Login Modal Layout', 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');
});
});
`
Registrieren Sie die Befehle in der package.json:
`json
{
"scripts": {
"test:visual": "playwright test",
"test:visual:update": "playwright test --update-snapshots"
}
}
`
Mit nur einem einzigen Befehl pnpm test:visual im Terminal lassen sich fehlerhafte Layouts auf Desktop- und Mobil-Viewports innerhalb einer Minute aufspüren. Die anstrengende, mühsame Überprüfung bei manueller Anpassung der Bildschirmgröße entfällt komplett.
Wenn man eine Struktur aufbaut, bei der die KI-Eingaben durch Regeldateien kontrolliert, der Zufluss falscher Styles über Git Hooks gestoppt und Layoutfehler mit Playwright überprüft werden, lässt sich die Design-Konsistenz selbst bei Solopreneur-Projekten wahren.