Best Practices & Real Project - vdsology
Chapter 11 — Best Practices & Real Project
Part 1 — Best Practices
HTML Best Practices
1. Always have one <h1> per page
<!-- ✅ Good -->
<h1>My Site</h1>
<h2>About Us</h2>
2. Never skip heading levels
<!-- ✅ Good -->
<h1>Title</h1>
<h2>Subtitle</h2>
<h3>Sub-subtitle</h3>
3. Always write alt text on images
<img src="team.jpg" alt="The Acme team at their 2026 office">
<img src="divider.svg" alt=""> <!-- empty for decorative -->
4. Use semantic HTML always
<!-- ✅ Good -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
5. Keep HTML for structure, CSS for appearance
<!-- ✅ Good -->
<p class="warning">Warning</p>
CSS Best Practices
1. Always start with a reset
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
2. Use variables for every repeated value
:root { --primary: #2563eb; --radius: 8px; }
3. Mobile first always
.grid { grid-template-columns: 1fr; }
@media (min-width: 768px) { .grid { grid-template-columns: repeat(4, 1fr); } }
4. Organize your CSS in this order
/* 1. Reset */
/* 2. Design tokens */
/* 3. Base styles */
/* 4. Layout */
/* 5. Components */
/* 6. Utilities */
/* 7. Media queries */
5. Name things by purpose
/* ✅ Good */
.button-danger { }
.section-title { }
6. Keep selectors flat
/* ✅ Good */
.card-title { color: red; }
7. Always style focus states
:focus { outline: none; }
:focus-visible {
outline: 3px solid var(--color-primary);
outline-offset: 3px;
}
Part 2 — The Real Project (SaaS Landing Page)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flowbase — Build faster</title>
<style>
/* ── 1. RESET ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img, video, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; }
p, h1, h2, h3, h4 { overflow-wrap: break-word; }
/* ── 2. DESIGN TOKENS ── */
:root {
--color-primary: #2563eb;
--color-primary-dark: #1d4ed8;
--color-secondary: #7c3aed;
--color-success: #16a34a;
--color-text: #111827;
--color-text-muted: #6b7280;
--color-bg: #ffffff;
--color-bg-subtle: #f9fafb;
--color-border: #e5e7eb;
--color-card: #ffffff;
--font: system-ui, Arial, sans-serif;
--text-sm: 0.875rem; --text-base: 1rem;
--text-lg: 1.125rem; --text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: clamp(1.75rem, 4vw, 2.25rem);
--text-hero: clamp(2.25rem, 6vw, 3.75rem);
--sp-xs: 4px; --sp-sm: 8px; --sp-md: 16px;
--sp-lg: 24px; --sp-xl: 40px; --sp-2xl: 64px; --sp-3xl: 96px;
--radius-sm: 6px; --radius-md: 12px;
--radius-lg: 20px; --radius-full: 9999px;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
--shadow-md: 0 4px 16px rgba(0,0,0,0.08);
--shadow-lg: 0 12px 40px rgba(0,0,0,0.12);
--ease: 200ms ease; --ease-slow: 400ms ease;
--container: 1160px; --nav-height: 68px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-text: #f9fafb;
--color-text-muted: #9ca3af;
--color-bg: #0f0f0f;
--color-bg-subtle: #1a1a1a;
--color-border: #2a2a2a;
--color-card: #1a1a1a;
}
}
/* ── 3. BASE ── */
html { scroll-behavior: smooth; font-size: 100%; }
body { font-family: var(--font); font-size: var(--text-base); color: var(--color-text); background: var(--color-bg); line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: var(--color-primary); text-decoration: none; transition: color var(--ease); }
a:hover { color: var(--color-primary-dark); }
:focus { outline: none; }
:focus-visible { outline: 3px solid var(--color-primary); outline-offset: 3px; border-radius: var(--radius-sm); }
/* ── 4. LAYOUT ── */
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-md); }
@media (min-width: 768px) { .container { padding: 0 var(--sp-xl); } }
.section { padding: var(--sp-2xl) 0; }
@media (min-width: 768px) { .section { padding: var(--sp-3xl) 0; } }
/* ── 5. COMPONENTS ── */
.btn {
display: inline-flex; align-items: center; justify-content: center;
gap: var(--sp-sm); padding: 12px var(--sp-lg); border-radius: var(--radius-md);
font-size: var(--text-base); font-weight: 600; border: 2px solid transparent;
cursor: pointer; white-space: nowrap;
transition: background var(--ease), color var(--ease), border-color var(--ease), transform 100ms ease, box-shadow var(--ease);
}
.btn:active { transform: scale(0.97); }
.btn-primary { background: var(--color-primary); color: white; }
.btn-primary:hover { background: var(--color-primary-dark); color: white; box-shadow: 0 4px 16px rgba(37,99,235,0.35); }
.btn-outline { background: transparent; color: var(--color-text); border-color: var(--color-border); }
.btn-outline:hover { border-color: var(--color-primary); color: var(--color-primary); }
.btn-lg { padding: 14px 32px; font-size: var(--text-lg); border-radius: var(--radius-lg); }
.badge { display: inline-flex; align-items: center; gap: var(--sp-xs); padding: 6px var(--sp-md); background: rgba(37,99,235,0.1); color: var(--color-primary); border-radius: var(--radius-full); font-size: var(--text-sm); font-weight: 600; }
/* NAV */
.nav { position: sticky; top: 0; z-index: 100; height: var(--nav-height); background: rgba(255,255,255,0.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--color-border); }
@media (prefers-color-scheme: dark) { .nav { background: rgba(15,15,15,0.85); } }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 100%; }
.nav-logo { font-size: var(--text-xl); font-weight: 800; color: var(--color-text); letter-spacing: -0.5px; }
.nav-logo span { color: var(--color-primary); }
.nav-links { display: none; align-items: center; gap: var(--sp-xl); list-style: none; }
@media (min-width: 768px) { .nav-links { display: flex; } }
.nav-links a { color: var(--color-text-muted); font-size: var(--text-sm); font-weight: 500; }
.nav-links a:hover { color: var(--color-text); }
.nav-actions { display: flex; align-items: center; gap: var(--sp-sm); }
.nav-actions .btn-outline { display: none; }
@media (min-width: 640px) { .nav-actions .btn-outline { display: inline-flex; } }
/* HERO */
.hero { padding: var(--sp-3xl) 0 var(--sp-2xl); text-align: center; overflow: hidden; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: translateY(0); } }
.hero-badge { animation: fadeUp 500ms ease-out forwards; margin-bottom: var(--sp-lg); }
.hero-title { font-size: var(--text-hero); font-weight: 800; line-height: 1.1; letter-spacing: -1.5px; margin-bottom: var(--sp-lg); opacity: 0; animation: fadeUp 500ms ease-out 100ms forwards; }
.hero-title .gradient { background: linear-gradient(135deg, var(--color-primary), var(--color-secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.hero-subtitle { font-size: clamp(var(--text-base), 2vw, var(--text-xl)); color: var(--color-text-muted); max-width: 580px; margin: 0 auto var(--sp-xl); opacity: 0; animation: fadeUp 500ms ease-out 200ms forwards; }
.hero-actions { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--sp-md); margin-bottom: var(--sp-2xl); opacity: 0; animation: fadeUp 500ms ease-out 300ms forwards; }
.hero-social-proof { opacity: 0; animation: fadeUp 500ms ease-out 400ms forwards; color: var(--color-text-muted); font-size: var(--text-sm); }
.hero-image { margin-top: var(--sp-2xl); background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: var(--radius-lg); height: 380px; display: flex; align-items: center; justify-content: center; color: var(--color-text-muted); font-size: var(--text-lg); font-weight: 500; opacity: 0; animation: fadeUp 600ms ease-out 500ms forwards; box-shadow: var(--shadow-lg); }
/* FEATURES */
.features { background: var(--color-bg-subtle); }
.section-header { text-align: center; margin-bottom: var(--sp-2xl); }
.section-label { display: block; font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 1.5px; color: var(--color-primary); margin-bottom: var(--sp-md); }
.section-title { font-size: var(--text-3xl); font-weight: 800; letter-spacing: -0.5px; margin-bottom: var(--sp-md); }
.section-subtitle { font-size: var(--text-lg); color: var(--color-text-muted); max-width: 500px; margin: 0 auto; }
.feature-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-lg); }
@media (min-width: 640px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .feature-grid { grid-template-columns: repeat(3, 1fr); } }
.feature-card { background: var(--color-card); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--sp-lg); transition: transform var(--ease), box-shadow var(--ease); }
.feature-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.feature-icon { width: 48px; height: 48px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin-bottom: var(--sp-md); }
.feature-icon.blue { background: rgba(37,99,235,0.1); }
.feature-icon.purple { background: rgba(124,58,237,0.1); }
.feature-icon.green { background: rgba(22,163,74,0.1); }
.feature-card h3 { font-size: var(--text-lg); font-weight: 700; margin-bottom: var(--sp-sm); }
.feature-card p { color: var(--color-text-muted); font-size: var(--text-sm); line-height: 1.7; }
/* PRICING */
.pricing-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-lg); align-items: start; }
@media (min-width: 768px) { .pricing-grid { grid-template-columns: repeat(3, 1fr); } }
.pricing-card { background: var(--color-card); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--sp-lg); position: relative; transition: box-shadow var(--ease); }
.pricing-card:hover { box-shadow: var(--shadow-md); }
.pricing-card.featured { border-color: var(--color-primary); border-width: 2px; box-shadow: var(--shadow-md); }
.pricing-popular { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); background: var(--color-primary); color: white; font-size: var(--text-sm); font-weight: 700; padding: 4px 16px; border-radius: var(--radius-full); white-space: nowrap; }
.pricing-plan { font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--color-text-muted); margin-bottom: var(--sp-md); }
.pricing-price { margin-bottom: var(--sp-md); }
.pricing-price .amount { font-size: 2.5rem; font-weight: 800; letter-spacing: -1px; line-height: 1; }
.pricing-price .period { font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 4px; }
.pricing-desc { font-size: var(--text-sm); color: var(--color-text-muted); padding-bottom: var(--sp-lg); margin-bottom: var(--sp-lg); border-bottom: 1px solid var(--color-border); }
.pricing-features { list-style: none; display: flex; flex-direction: column; gap: var(--sp-sm); margin-bottom: var(--sp-lg); }
.pricing-features li { display: flex; align-items: center; gap: var(--sp-sm); font-size: var(--text-sm); }
.pricing-features li::before { content: "✓"; font-weight: 800; color: var(--color-success); flex-shrink: 0; }
.pricing-card .btn { width: 100%; }
/* FOOTER */
.footer { background: var(--color-bg-subtle); border-top: 1px solid var(--color-border); padding: var(--sp-2xl) 0 var(--sp-xl); }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-2xl); margin-bottom: var(--sp-2xl); }
@media (min-width: 640px) { .footer-grid { grid-template-columns: 2fr repeat(3, 1fr); } }
.footer-brand p { color: var(--color-text-muted); font-size: var(--text-sm); margin-top: var(--sp-sm); max-width: 260px; line-height: 1.7; }
.footer-col h4 { font-size: var(--text-sm); font-weight: 700; margin-bottom: var(--sp-md); }
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: var(--sp-sm); }
.footer-col ul a { color: var(--color-text-muted); font-size: var(--text-sm); }
.footer-col ul a:hover { color: var(--color-text); }
.footer-bottom { padding-top: var(--sp-lg); border-top: 1px solid var(--color-border); display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-md); }
.footer-bottom p { font-size: var(--text-sm); color: var(--color-text-muted); }
/* ACCESSIBILITY */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border-width: 0; }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
</style>
</head>
<body>
<header>
<nav class="nav" aria-label="Main navigation">
<div class="container nav-inner">
<a href="/" class="nav-logo" aria-label="Flowbase home">Flow<span>base</span></a>
<ul class="nav-links" role="list">
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#">Docs</a></li>
<li><a href="#">Blog</a></li>
</ul>
<div class="nav-actions">
<a href="#" class="btn btn-outline">Log in</a>
<a href="#" class="btn btn-primary">Get started</a>
</div>
</div>
</nav>
</header>
<main>
<section class="hero section">
<div class="container">
<div class="hero-badge"><span class="badge">🚀 Just shipped v3.0</span></div>
<h1 class="hero-title">Build products<br><span class="gradient">10× faster</span></h1>
<p class="hero-subtitle">Flowbase gives your team the components, tools, and workflows to ship production-ready software — without the boilerplate.</p>
<div class="hero-actions">
<a href="#" class="btn btn-primary btn-lg">Start for free</a>
<a href="#" class="btn btn-outline btn-lg">View demo →</a>
</div>
<p class="hero-social-proof">Trusted by 12,000+ developers · No credit card required</p>
<div class="hero-image" role="img" aria-label="Product screenshot">[ Product Screenshot ]</div>
</div>
</section>
<section class="features section" id="features">
<div class="container">
<div class="section-header">
<span class="section-label">Features</span>
<h2 class="section-title">Everything your team needs</h2>
<p class="section-subtitle">Stop stitching tools together. Flowbase has it all built in.</p>
</div>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon blue" aria-hidden="true">⚡</div>
<h3>Instant deploys</h3>
<p>Push your code and go live in seconds. Zero config, automatic rollbacks, global CDN included.</p>
</div>
<div class="feature-card">
<div class="feature-icon purple" aria-hidden="true">🎨</div>
<h3>Design system</h3>
<p>A complete set of accessible components built to match your brand out of the box.</p>
</div>
<div class="feature-card">
<div class="feature-icon green" aria-hidden="true">🔐</div>
<h3>Auth built in</h3>
<p>Login, signup, OAuth, and permissions — fully working in minutes, not weeks.</p>
</div>
<div class="feature-card">
<div class="feature-icon blue" aria-hidden="true">📊</div>
<h3>Analytics</h3>
<p>Real-time dashboards showing exactly how users move through your product.</p>
</div>
<div class="feature-card">
<div class="feature-icon purple" aria-hidden="true">🤖</div>
<h3>AI assistant</h3>
<p>Generate components, write tests, and debug errors with AI that understands your codebase.</p>
</div>
<div class="feature-card">
<div class="feature-icon green" aria-hidden="true">🌍</div>
<h3>Global edge</h3>
<p>Deploy to 35 regions worldwide. Your users get sub-50ms response times everywhere.</p>
</div>
</div>
</div>
</section>
<section class="section" id="pricing">
<div class="container">
<div class="section-header">
<span class="section-label">Pricing</span>
<h2 class="section-title">Simple, honest pricing</h2>
<p class="section-subtitle">Start free. Scale as you grow. No surprise bills.</p>
</div>
<div class="pricing-grid">
<div class="pricing-card">
<p class="pricing-plan">Starter</p>
<div class="pricing-price"><div class="amount">$0</div><div class="period">Free forever</div></div>
<p class="pricing-desc">Perfect for side projects and learning.</p>
<ul class="pricing-features"><li>3 projects</li><li>10GB bandwidth</li><li>Community support</li><li>Basic analytics</li></ul>
<a href="#" class="btn btn-outline">Get started free</a>
</div>
<div class="pricing-card featured">
<span class="pricing-popular">Most popular</span>
<p class="pricing-plan">Pro</p>
<div class="pricing-price"><div class="amount">$29</div><div class="period">per month</div></div>
<p class="pricing-desc">For professionals shipping real products.</p>
<ul class="pricing-features"><li>Unlimited projects</li><li>500GB bandwidth</li><li>Priority support</li><li>Advanced analytics</li><li>AI assistant</li><li>Custom domains</li></ul>
<a href="#" class="btn btn-primary">Start free trial</a>
</div>
<div class="pricing-card">
<p class="pricing-plan">Team</p>
<div class="pricing-price"><div class="amount">$99</div><div class="period">per month</div></div>
<p class="pricing-desc">For growing teams building together.</p>
<ul class="pricing-features"><li>Everything in Pro</li><li>Up to 20 seats</li><li>SSO & audit logs</li><li>Dedicated support</li><li>SLA guarantee</li></ul>
<a href="#" class="btn btn-outline">Contact sales</a>
</div>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<a href="/" class="nav-logo">Flow<span>base</span></a>
<p>Building the tools that help developers ship faster, every day.</p>
</div>
<div class="footer-col">
<h4>Product</h4>
<ul role="list"><li><a href="#">Features</a></li><li><a href="#">Pricing</a></li><li><a href="#">Changelog</a></li><li><a href="#">Roadmap</a></li></ul>
</div>
<div class="footer-col">
<h4>Company</h4>
<ul role="list"><li><a href="#">About</a></li><li><a href="#">Blog</a></li><li><a href="#">Careers</a></li><li><a href="#">Press</a></li></ul>
</div>
<div class="footer-col">
<h4>Legal</h4>
<ul role="list"><li><a href="#">Privacy</a></li><li><a href="#">Terms</a></li><li><a href="#">Security</a></li><li><a href="#">Cookies</a></li></ul>
</div>
</div>
<div class="footer-bottom">
<p>© 2026 Flowbase, Inc. All rights reserved.</p>
<p>Made with HTML & CSS 🎨</p>
</div>
</div>
</footer>
</body>
</html>
Tags: #CSS #css #vdsology #webdevelopment #vdsologyCSS #CSS3 #CSSreference #CSSreference2026
Write a comment