Project: Build a SaaS Product Landing Page using CSS Grid

Step-by-step project guide. Learn how to build a responsive SaaS product landing page using HTML5 and CSS Grid.

Introduction

In our first capstone project, we used Flexbox to build a personal portfolio. Flexbox is excellent for lining up items in a single row or column. However, when you need to align complex elements (like a multi-column pricing layout or a structured features matrix) along both rows and columns simultaneously, you need a two-dimensional layout engine.

In this project, you will build a SaaS Product Landing Page using CSS Grid. We will use grid-template-areas to skeleton the page, design a responsive pricing table, and create a features grid that wraps smoothly, making it a great addition to your frontend placement portfolio.


What You Will Learn

  • Structuring a multi-section product landing page.
  • Layout mapping using grid-template-areas.
  • Designing a responsive 3-column pricing grid.
  • Creating a features grid using repeat(auto-fit, minmax(...)).
  • Applying styling accents like gradients and glassmorphism.

Prerequisites


Step 1: The HTML5 Markup Structure

Create a saas.html file with sections for the navbar, hero banner, feature blocks, pricing tables, and footer:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SaaS Product Landing Page</title>
  <link rel="stylesheet" href="saas.css">
</head>
<body>

  <!-- Main Skeleton Container -->
  <div class="layout-wrapper">
    
    <!-- Header -->
    <header class="header">
      <div class="logo">SaaSify</div>
      <nav class="nav">
        <a href="#features">Features</a>
        <a href="#pricing">Pricing</a>
        <button class="btn-cta">Start Free</button>
      </nav>
    </header>

    <!-- Hero Area -->
    <section class="hero-section">
      <h1>The Modern Workspace <br><span class="gradient-text">Redefined</span></h1>
      <p>Streamline your development workflows, track progress in real-time, and collaborate globally in a single glassmorphic workspace console.</p>
      <div class="hero-buttons">
        <button class="btn-primary">Get Started</button>
        <button class="btn-secondary">Watch Demo</button>
      </div>
    </section>

    <!-- Features Area -->
    <section id="features" class="features-section">
      <h2>Why Teams Choose SaaSify</h2>
      <div class="features-grid">
        
        <!-- Feature 1 -->
        <div class="feature-card">
          <div class="feature-icon">⚡</div>
          <h3>Real-time Sync</h3>
          <p>Sync development assets across global teams instantly with no latency issues.</p>
        </div>

        <!-- Feature 2 -->
        <div class="feature-card">
          <div class="feature-icon">🛡️</div>
          <h3>Secure Backups</h3>
          <p>Enterprise-grade encryption protecting your repository assets continuously.</p>
        </div>

        <!-- Feature 3 -->
        <div class="feature-card">
          <div class="feature-icon">📊</div>
          <h3>Console Analytics</h3>
          <p>Inspect project velocities and deployments with integrated charts.</p>
        </div>

      </div>
    </section>

    <!-- Pricing Area -->
    <section id="pricing" class="pricing-section">
      <h2>Simple, Transparent Pricing</h2>
      <div class="pricing-grid">
        
        <!-- Tier 1 -->
        <div class="price-card">
          <h3>Hobby</h3>
          <div class="price">$0<span>/mo</span></div>
          <p>Essential widgets for solo creators.</p>
          <button class="btn-card">Get Started</button>
        </div>

        <!-- Tier 2 (Featured) -->
        <div class="price-card featured">
          <div class="badge">Popular</div>
          <h3>Startup</h3>
          <div class="price">$29<span>/mo</span></div>
          <p>Advanced metrics and team integration libraries.</p>
          <button class="btn-card primary">Get Started</button>
        </div>

        <!-- Tier 3 -->
        <div class="price-card">
          <h3>Enterprise</h3>
          <div class="price">Custom</div>
          <p>Dedicated instances and custom SLA options.</p>
          <button class="btn-card">Contact Sales</button>
        </div>

      </div>
    </section>

    <!-- Footer -->
    <footer class="footer">
      <p>&copy; 2026 SaaSify Inc. All rights reserved.</p>
    </footer>

  </div>

</body>
</html>

Step 2: The CSS stylesheet (saas.css)

Create a saas.css stylesheet, defining custom properties, a background gradient, and grid areas:

/* ==========================================================================
   Design Tokens & Resets
   ========================================================================== */
:root {
  --bg-dark: #090d16;
  --bg-glass: rgba(255, 255, 255, 0.03);
  --border-glass: rgba(255, 255, 255, 0.08);
  --color-accent: #38bdf8;
  --color-accent-hover: #0ea5e9;
  --text-white: #ffffff;
  --text-muted: #64748b;
  --font-sans: 'Inter', system-ui, sans-serif;
}

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: var(--bg-dark);
  background-image: radial-gradient(circle at top right, #0c1c38, var(--bg-dark));
  color: var(--text-white);
  font-family: var(--font-sans);
  line-height: 1.6;
  overflow-x: hidden;
}

/* ==========================================================================
   Grid Area Template Map
   ========================================================================== */
.layout-wrapper {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto;
  
  /* Map out layout sections */
  grid-template-areas:
    "header"
    "hero"
    "features"
    "pricing"
    "footer";
}

.header { grid-area: header; }
.hero-section { grid-area: hero; }
.features-section { grid-area: features; }
.pricing-section { grid-area: pricing; }
.footer { grid-area: footer; }

/* ==========================================================================
   Header Navbar
   ========================================================================== */
.header {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  padding: 24px 8%;
}

.logo {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--text-white);
}

.nav {
  justify-self: end; /* Align navigation elements to right */
  display: flex;
  align-items: center;
  gap: 32px;
}

.nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s;
}

.nav a:hover {
  color: var(--text-white);
}

.btn-cta {
  background-color: #ffffff;
  color: #000000;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s;
}

.btn-cta:hover {
  opacity: 0.9;
}

/* ==========================================================================
   Hero Section
   ========================================================================== */
.hero-section {
  padding: 100px 8% 80px 8%;
  text-align: center;
  max-width: 900px;
  margin: 0 auto;
}

.hero-section h1 {
  font-size: 4rem;
  font-weight: 900;
  line-height: 1.1;
  margin-bottom: 24px;
}

.gradient-text {
  background: linear-gradient(135deg, #38bdf8, #818cf8);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.hero-section p {
  font-size: 1.25rem;
  color: var(--text-muted);
  margin-bottom: 40px;
}

.hero-buttons {
  display: flex;
  justify-content: center;
  gap: 16px;
}

.btn-primary {
  background-color: var(--color-accent);
  color: #000;
  border: none;
  padding: 14px 28px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-primary:hover {
  background-color: var(--color-accent-hover);
}

.btn-secondary {
  background-color: var(--bg-glass);
  color: #fff;
  border: 1px solid var(--border-glass);
  padding: 14px 28px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-secondary:hover {
  background-color: rgba(255, 255, 255, 0.08);
}

/* ==========================================================================
   Features Section (CSS Grid Auto-Fit)
   ========================================================================== */
.features-section {
  padding: 80px 8%;
  max-width: 1200px;
  margin: 0 auto;
  text-align: center;
}

.features-section h2 {
  font-size: 2.5rem;
  margin-bottom: 48px;
}

.features-grid {
  display: grid;
  /* Auto column wrapping: minimum 300px, max spans space */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 32px;
}

.feature-card {
  background: var(--bg-glass);
  border: 1px solid var(--border-glass);
  padding: 40px 32px;
  border-radius: 16px;
  text-align: left;
  transition: border-color 0.3s;
}

.feature-card:hover {
  border-color: rgba(56, 189, 248, 0.3);
}

.feature-icon {
  font-size: 2.5rem;
  margin-bottom: 24px;
}

.feature-card h3 {
  font-size: 1.5rem;
  margin-bottom: 12px;
}

.feature-card p {
  color: var(--text-muted);
}

/* ==========================================================================
   Pricing Section (CSS Grid Multi-Column)
   ========================================================================== */
.pricing-section {
  padding: 80px 8%;
  max-width: 1200px;
  margin: 0 auto;
  text-align: center;
}

.pricing-section h2 {
  font-size: 2.5rem;
  margin-bottom: 48px;
}

.pricing-grid {
  display: grid;
  /* Fixed 3 columns layout */
  grid-template-columns: 1fr 1fr 1fr;
  gap: 32px;
  align-items: center;
}

.price-card {
  background: var(--bg-glass);
  border: 1px solid var(--border-glass);
  padding: 48px 32px;
  border-radius: 20px;
  text-align: center;
  position: relative;
}

.price-card.featured {
  border: 2px solid var(--color-accent);
  background: rgba(56, 189, 248, 0.02);
  /* Push featured card up slightly to make it stand out */
  transform: translateY(-8px); 
}

.badge {
  position: absolute;
  top: 16px;
  right: 16px;
  background-color: var(--color-accent);
  color: #000;
  padding: 4px 12px;
  font-size: 0.75rem;
  font-weight: 700;
  border-radius: 20px;
  text-transform: uppercase;
}

.price {
  font-size: 3rem;
  font-weight: 800;
  margin: 24px 0;
}

.price span {
  font-size: 1rem;
  color: var(--text-muted);
}

.btn-card {
  width: 100%;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid var(--border-glass);
  background: transparent;
  color: white;
  font-weight: 600;
  cursor: pointer;
  margin-top: 32px;
  transition: all 0.2s;
}

.btn-card:hover {
  background: rgba(255, 255, 255, 0.05);
}

.btn-card.primary {
  background-color: var(--color-accent);
  color: #000;
  border: none;
}

.btn-card.primary:hover {
  background-color: var(--color-accent-hover);
}

/* ==========================================================================
   Footer Section
   ========================================================================== */
.footer {
  padding: 48px 8%;
  border-top: 1px solid var(--border-glass);
  text-align: center;
  color: var(--text-muted);
  font-size: 0.875rem;
}

Responsive Layouts (Media Queries)

Add media queries at the bottom of saas.css to collapse pricing grids and adjust hero font sizing on mobile viewports:

@media (max-width: 992px) {
  .pricing-grid {
    grid-template-columns: 1fr; /* Collapse pricing columns into vertical stack */
    gap: 24px;
  }
  
  .price-card.featured {
    transform: none; /* Reset 3D transformation offsets */
  }
  
  .hero-section h1 {
    font-size: 2.75rem;
  }
}

@media (max-width: 768px) {
  .header {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 16px;
  }
  
  .nav {
    justify-self: center;
  }
}

Summary

This SaaS product landing page maps structural layout blocks via grid-template-areas templates. Features matrices are wrapped automatically using Grid auto-fit and minmax() functions, while pricing listings collapse into single-column stacks under tablet breakpoints.


Related Articles

Next Tutorial

Ready for a complex frontend project? Let's build a responsive dashboard UI: Project: Responsive Admin Dashboard.