Skip to content

Phase 2: Creating Layouts Guide

Timeline: 4-8 hours
Typical Effort: Building 1-2 Site Designs with responsive markup
Output: Complete Site Design with header, navigation, content area, footer

Overview

In Phase 1, you planned your site structure and decided how many Layouts you needed. Phase 2 is where you build those Layouts (referred to as "Site Designs" in the SkyCMS editor UI) in SkyCMS.

In the context of SkyCMS, a Layout (or Site Design) is the structural container that defines: - Overall page structure (where content goes) - Header and footer areas - Navigation placement - Responsive breakpoints - Global HTML structure

This guide walks you through creating your first Site Design, adding variations, and ensuring mobile responsiveness.


Why Layouts Matter: The DRY Principle

One of the most important benefits of using Layouts (Site Designs) is that they help you stay DRYDon't Repeat Yourself.

Without Layouts: Code Repetition Problem

Imagine building a website with 50 pages without layouts:

<!-- Page 1: home.html -->
<!DOCTYPE html>
<html>
<head>...</head>
<body>
  <header>...same header code...</header>
  <nav>...same navigation code...</nav>
  <main>
    <!-- Unique home page content -->
  </main>
  <footer>...same footer code...</footer>
</body>
</html>

<!-- Page 2: about.html -->
<!DOCTYPE html>
<html>
<head>...</head>
<body>
  <header>...same header code...</header>
  <nav>...same navigation code...</nav>
  <main>
    <!-- Unique about page content -->
  </main>
  <footer>...same footer code...</footer>
</body>
</html>

<!-- ... 48 more pages with identical header/nav/footer -->

The Problem: - Header/nav/footer code repeated 50 times - Need to update logo? Edit 50 files - Fix footer bug? Edit 50 files - Add menu item? Edit 50 files - High risk of inconsistency and errors - Massive maintenance burden

With Layouts: DRY Approach

Using a Layout, you write shared code once:

<!-- Layout (Site Design) - Written ONCE -->
<!DOCTYPE html>
<html>
<head>...</head>
<body>
  <header>...header code...</header>
  <nav>...navigation code...</nav>
  <main>
    @RenderBody()  <!-- Pages insert their unique content here -->
  </main>
  <footer>...footer code...</footer>
</body>
</html>

<!-- Page 1: Only unique content -->
<h1>Welcome Home</h1>
<p>Home page content...</p>

<!-- Page 2: Only unique content -->
<h1>About Us</h1>
<p>About page content...</p>

<!-- ... 48 more pages with ONLY their unique content -->

The Benefits: - Header/nav/footer written once in the Layout - Update logo? Edit 1 file (the Layout) - Fix footer bug? Edit 1 file (automatically applied to all 50 pages) - Add menu item? Edit 1 file (appears on all pages instantly) - Zero inconsistency risk — all pages use identical structure - Minimal maintenance — changes propagate automatically - Faster development — focus on unique content, not repeated boilerplate

Real-World Impact

Consider a typical website project:

Without Layouts (Repetition): - 50 pages × 150 lines of repeated code = 7,500 lines of duplicate code - Logo update: 50 file edits × 2 minutes = 100 minutes - Navigation change: 50 file edits × 3 minutes = 150 minutes - Risk: Miss 3 pages → broken consistency

With Layouts (DRY): - 1 Layout × 150 lines = 150 lines (shared code) - 50 pages × 30 lines = 1,500 lines (unique content only) - Logo update: 1 file edit × 2 minutes = 2 minutes - Navigation change: 1 file edit × 3 minutes = 3 minutes - Risk: Zero — one source of truth

Savings: 5,850 fewer lines of code, 245 minutes saved on simple updates

Staying DRY Throughout Development

The DRY principle extends beyond just layouts:

Good DRY Practices:

<!-- Layout: Define reusable CSS variables once -->
<style>
  :root {
    --primary-color: #0066cc;
    --font-main: Arial, sans-serif;
  }
</style>

<!-- Use variables everywhere (not repeated values) -->
<button style="background: var(--primary-color);">Click</button>

<!-- Layout: Define common classes once -->
<style>
  .btn-primary { background: var(--primary-color); padding: 10px 20px; }
</style>

<!-- Reuse classes (don't repeat styles) -->
<button class="btn-primary">Click</button>

Avoid Repetition:

<!-- Bad: Repeated inline styles -->
<button style="background: #0066cc; padding: 10px 20px;">Click</button>
<button style="background: #0066cc; padding: 10px 20px;">Submit</button>
<button style="background: #0066cc; padding: 10px 20px;">Go</button>

<!-- Good: Define once, reuse -->
<style>.btn { background: #0066cc; padding: 10px 20px; }</style>
<button class="btn">Click</button>
<button class="btn">Submit</button>
<button class="btn">Go</button>

The Bottom Line

Layouts are essential for staying DRY. By centralizing shared markup, styles, and scripts in your Site Design, you write less code, maintain it more easily, and ensure perfect consistency across your entire website.

This is not just a convenience — it's a fundamental best practice in professional web development.


Important: You Have Complete Design Freedom

Before we dive into step-by-step instructions, let's be clear about what you can do:

Framework Flexibility

SkyCMS comes with Bootstrap and Tailwind CSS frameworks pre-configured as options, but they are: - Completely optional — use them if they suit your project - Not required — you can write 100% custom CSS - Not limiting — you can use a completely different framework if you prefer

Your Options

Option 1: Use Built-in Frameworks (Recommended for Speed) - Bootstrap 5 is available and configured - Tailwind CSS is available and configured - Choose whichever aligns with your design preferences - Fastest path to a responsive Site Design

Option 2: Custom CSS Only - Write your own CSS from scratch - Use your own preferred methodology (BEM, Atomic, etc.) - Complete control over styling and behavior - Takes more time but results in minimal code

Option 3: Different Framework - Want Material Design? Use it. - Want Foundation? Use it. - Want CSS Grid with custom layouts? Go for it. - SkyCMS doesn't dictate your tech stack

Option 4: Minimal Layout or No Layout - If you want each page to have its own unique design - If you're using a per-page theme or CSS framework - You can create a minimal layout (just the <html>, <body>, and @RenderBody()) - Or define no layout at all for each page that needs complete independence - This gives you maximum flexibility for highly customized designs

The Key Point

Your Site Design reflects your design needs and technical preferences. SkyCMS provides the structure; you provide the creativity.

We'll show examples using Bootstrap and Tailwind because they're popular and pre-configured, but every technique shown can be adapted to any framework or custom CSS.


Core Concepts: How Layouts Work in SkyCMS

Before creating your first Site Design, understand how it functions within SkyCMS:

The Layout File Structure

A Layout in SkyCMS is a Razor template that defines: 1. The overall HTML document structure 2. Where templates will render their content (@RenderBody()) 3. Common elements (header, navigation, footer) 4. Required stylesheets and scripts 5. Responsive behavior

Basic Layout Template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title</title>

    <!-- Bootstrap CSS (if using Bootstrap) -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- Your custom CSS -->
    <link href="/css/site.css" rel="stylesheet">
</head>
<body>
    <!-- HEADER -->
    <header class="site-header">
        <div class="container">
            <div class="logo">
                <h1>Site Logo/Name</h1>
            </div>
        </div>
    </header>

    <!-- NAVIGATION -->
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container">
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item"><a class="nav-link" href="/">Home</a></li>
                    <li class="nav-item"><a class="nav-link" href="/about">About</a></li>
                    <li class="nav-item"><a class="nav-link" href="/contact">Contact</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- MAIN CONTENT -->
    <main class="main-content">
        <div class="container">
            @RenderBody()
        </div>
    </main>

    <!-- FOOTER -->
    <footer class="site-footer bg-dark text-white">
        <div class="container">
            <p>&copy; 2025 Your Company. All rights reserved.</p>
        </div>
    </footer>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

The key line is @RenderBody() — this is where template content renders.


Decision Framework: Choosing Your Design Approach

Before building, decide which design approach fits your project:

Decision Tree

START: How should your site look?

├─ All pages look similar with consistent header/nav/footer
│  └─ Do you want to use an existing framework?
│     ├─ YES, Bootstrap → Follow "Bootstrap Approach" below
│     ├─ YES, Tailwind → Follow "Tailwind Approach" below
│     └─ NO, custom CSS → Follow "Custom CSS Approach" below
│
├─ Pages have varying designs but share header/nav/footer
│  └─ Use minimal layout with per-page CSS/frameworks
│     See "Minimal Layout Approach" below
│
└─ Each page has completely unique design (no shared layout)
   └─ Use no layout (each page is independent)
      See "Independent Page Design" below

When to use: You want responsive design fast, don't need heavily customized styling, prefer CSS classes over custom CSS.

Pros: - Pre-built responsive components (navbar, grid, buttons, forms) - Extensive documentation and community support - Quick to implement - Accessible by default

Cons: - Requires learning Bootstrap class naming - Default design looks "Bootstrap-like" - Need customization via CSS overrides for unique branding

Timeline: 3-4 hours for a complete Site Design

Approach 2: Tailwind CSS Framework

When to use: You want a modern utility-first approach, prefer building with classes, want a lightweight framework.

Pros: - Highly customizable via configuration - Utility-first approach (compose designs from small classes) - Minimal output CSS when purged - Great documentation - Modern and popular

Cons: - Steeper learning curve if unfamiliar with utility-first - Requires understanding composition vs components - Build process needed for custom configuration

Timeline: 4-5 hours for a complete Site Design (includes setup)

Approach 3: Custom CSS Only

When to use: You have specific design needs, want maximum control, prefer minimal dependencies.

Pros: - Complete control over every pixel - No framework constraints - Lighter payload (only your CSS) - Full creative freedom

Cons: - More CSS to write - Responsive design is your responsibility - No pre-built components

Timeline: 6-8 hours for a complete responsive Site Design

Approach 4: Minimal Layout + Per-Page Flexibility

When to use: Some pages need shared elements (header/nav), others need completely custom designs.

Pros: - Flexibility to use different frameworks per page - Shared navigation doesn't repeat - Pages can have unique styling

Cons: - Multiple design systems across site - Harder to maintain consistency - More complexity

Timeline: 4-6 hours plus additional time per page

Approach 5: No Layout (Complete Page Independence)

When to use: Each page needs a completely unique design, or you're using per-page theme systems.

Pros: - Maximum flexibility - Each page can be optimized independently - Use whatever framework/CSS makes sense per page

Cons: - No automatic shared elements - Harder to maintain consistency - Content creators must understand layout independence

Timeline: Varies greatly depending on per-page complexity


Step-by-Step: Creating Your First Site Design

Let's walk through creating a standard Site Design using Bootstrap (the quickest approach).

Step 1: Access the Layout Manager

In SkyCMS Admin: 1. Navigate to Content ManagementLayouts 2. Click Create New Layout button 3. You'll see a form with these fields: - Layout Name: How you'll identify this in templates - Layout Code: The Razor template HTML/markup - Description: Notes about when to use this layout

Step 2: Name Your Site Design

Choose a clear, descriptive name:

Good Names: - "Main Site Design" (primary layout) - "Landing Page Design" (hero-focused) - "Admin Design" (for internal pages) - "Blog Design" (if blog pages differ from main)

Poor Names: - "Layout" (too generic) - "Template" (confusing with templates in Phase 3) - "Site1" (not descriptive)

Our Example: "Main Site Design"

Step 3: Write the Markup

Start with a basic structure and build from there. Here's a Bootstrap example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Your Site Name</title>

    <!-- Bootstrap CSS from CDN -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- Your custom styles -->
    <style>
        :root {
            --primary-color: #0066cc;
            --secondary-color: #6c757d;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            line-height: 1.6;
            color: #333;
        }

        .site-header {
            background-color: #fff;
            border-bottom: 1px solid #ddd;
            padding: 1rem 0;
        }

        .site-header .logo h1 {
            margin: 0;
            font-size: 1.5rem;
            color: var(--primary-color);
        }

        .main-content {
            min-height: calc(100vh - 300px);
            padding: 2rem 0;
        }

        .site-footer {
            background-color: #333;
            color: #fff;
            padding: 2rem 0;
            margin-top: 3rem;
        }

        @media (max-width: 768px) {
            .site-header .logo h1 {
                font-size: 1.25rem;
            }
        }
    </style>
</head>
<body>
    <!-- HEADER -->
    <header class="site-header">
        <div class="container">
            <div class="logo">
                <h1>Your Company</h1>
            </div>
        </div>
    </header>

    <!-- NAVIGATION -->
    <nav class="navbar navbar-expand-lg navbar-light bg-light sticky-top">
        <div class="container">
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="/">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/about">About</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/services">Services</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/blog">Blog</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/contact">Contact</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- MAIN CONTENT AREA -->
    <main class="main-content">
        <div class="container">
            @RenderBody()
        </div>
    </main>

    <!-- FOOTER -->
    <footer class="site-footer">
        <div class="container">
            <div class="row">
                <div class="col-md-4">
                    <h5>About</h5>
                    <p>Brief company description here.</p>
                </div>
                <div class="col-md-4">
                    <h5>Links</h5>
                    <ul class="list-unstyled">
                        <li><a href="/privacy" class="text-white-50">Privacy Policy</a></li>
                        <li><a href="/terms" class="text-white-50">Terms of Service</a></li>
                    </ul>
                </div>
                <div class="col-md-4">
                    <h5>Contact</h5>
                    <p>Email: <a href="mailto:[email protected]" class="text-white-50">[email protected]</a></p>
                </div>
            </div>
            <hr class="text-white-50">
            <p class="text-center text-white-50 mb-0">&copy; 2025 Your Company. All rights reserved.</p>
        </div>
    </footer>

    <!-- Bootstrap JS Bundle (includes Popper) -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Step 4: Test on Different Screen Sizes

Before saving: 1. Open browser DevTools (F12) 2. Toggle device toolbar (Ctrl+Shift+M or Cmd+Shift+M) 3. Test at multiple breakpoints: - Mobile: 375px, 480px - Tablet: 768px, 1024px - Desktop: 1440px, 1920px

Verify: - Header and navigation are readable - Main content area is accessible - Footer displays correctly - All text is visible (no overflow)

Step 5: Save Your Site Design

Click Save Layout in SkyCMS. The system will: 1. Validate the Razor syntax 2. Store the markup 3. Make it available for templates to use

Step 6: Create Variations (Optional)

Once you have a main Site Design, you might create variations:

Example Variations: - Main Site Design (header + nav + footer) - Landing Page Design (no nav, hero focused) - Blog Design (with sidebar)

To create a variation: 1. Create new layout 2. Use similar structure but modify sections as needed 3. Name clearly (e.g., "Landing Page Design")


Real-World Example: E-Commerce Site Design

Here's a complete, production-ready Site Design for an e-commerce site:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - E-Store</title>

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- Font Awesome for icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

    <style>
        :root {
            --primary: #0066cc;
            --secondary: #666;
            --light-bg: #f8f9fa;
            --border-color: #dee2e6;
        }

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

        body {
            font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            color: #333;
            background-color: #fff;
        }

        /* Header */
        .site-header {
            background-color: #fff;
            border-bottom: 1px solid var(--border-color);
            padding: 1rem 0;
        }

        .site-header .logo {
            font-size: 1.5rem;
            font-weight: bold;
            color: var(--primary);
        }

        .site-header .header-icons {
            display: flex;
            gap: 1rem;
            align-items: center;
        }

        .site-header .cart-icon {
            position: relative;
        }

        .site-header .cart-count {
            position: absolute;
            top: -8px;
            right: -8px;
            background-color: #dc3545;
            color: white;
            border-radius: 50%;
            width: 20px;
            height: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.75rem;
        }

        /* Navigation */
        .navbar {
            background-color: var(--light-bg) !important;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }

        .navbar-nav .nav-link {
            color: #333 !important;
            font-weight: 500;
            margin-left: 1rem;
        }

        .navbar-nav .nav-link:hover {
            color: var(--primary) !important;
        }

        .navbar-nav .nav-link.active {
            color: var(--primary) !important;
            border-bottom: 2px solid var(--primary);
        }

        /* Main Content */
        .main-content {
            min-height: calc(100vh - 400px);
            padding: 2rem 0;
        }

        /* Footer */
        .site-footer {
            background-color: #333;
            color: #fff;
            padding: 3rem 0 1rem;
            margin-top: 4rem;
        }

        .site-footer h5 {
            color: var(--primary);
            margin-bottom: 1rem;
            font-weight: 600;
        }

        .site-footer a {
            color: #bbb;
            text-decoration: none;
        }

        .site-footer a:hover {
            color: var(--primary);
        }

        .footer-divider {
            border-top: 1px solid #555;
            margin: 2rem 0;
        }

        .footer-bottom {
            text-align: center;
            padding-top: 1rem;
            border-top: 1px solid #555;
            font-size: 0.9rem;
            color: #999;
        }

        /* Responsive */
        @media (max-width: 768px) {
            .site-header .header-icons {
                gap: 0.5rem;
            }

            .navbar-nav .nav-link {
                margin-left: 0;
                padding: 0.5rem 0;
            }

            .site-footer {
                padding: 2rem 0 1rem;
            }
        }
    </style>
</head>
<body>
    <!-- HEADER -->
    <header class="site-header">
        <div class="container">
            <div class="d-flex justify-content-between align-items-center">
                <div class="logo">E-Store</div>
                <div class="header-icons">
                    <div class="search-box" style="flex: 1; margin: 0 2rem;">
                        <input type="search" class="form-control form-control-sm" placeholder="Search products...">
                    </div>
                    <div class="cart-icon">
                        <i class="fas fa-shopping-cart fa-lg"></i>
                        <span class="cart-count">3</span>
                    </div>
                    <div class="account-icon">
                        <i class="fas fa-user fa-lg"></i>
                    </div>
                </div>
            </div>
        </div>
    </header>

    <!-- NAVIGATION -->
    <nav class="navbar navbar-expand-lg sticky-top">
        <div class="container">
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link active" href="/">Home</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" id="categoriesDropdown" role="button" data-bs-toggle="dropdown">
                            Categories
                        </a>
                        <ul class="dropdown-menu" aria-labelledby="categoriesDropdown">
                            <li><a class="dropdown-item" href="/category/electronics">Electronics</a></li>
                            <li><a class="dropdown-item" href="/category/clothing">Clothing</a></li>
                            <li><a class="dropdown-item" href="/category/books">Books</a></li>
                        </ul>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/deals">Deals</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/about">About</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/contact">Contact</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- MAIN CONTENT AREA -->
    <main class="main-content">
        <div class="container">
            @RenderBody()
        </div>
    </main>

    <!-- FOOTER -->
    <footer class="site-footer">
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                    <h5>Shop</h5>
                    <ul class="list-unstyled">
                        <li><a href="/category/electronics">Electronics</a></li>
                        <li><a href="/category/clothing">Clothing</a></li>
                        <li><a href="/category/books">Books</a></li>
                        <li><a href="/deals">All Deals</a></li>
                    </ul>
                </div>
                <div class="col-md-3">
                    <h5>Customer Service</h5>
                    <ul class="list-unstyled">
                        <li><a href="/contact">Contact Us</a></li>
                        <li><a href="/faq">FAQ</a></li>
                        <li><a href="/shipping">Shipping Info</a></li>
                        <li><a href="/returns">Returns</a></li>
                    </ul>
                </div>
                <div class="col-md-3">
                    <h5>Company</h5>
                    <ul class="list-unstyled">
                        <li><a href="/about">About Us</a></li>
                        <li><a href="/careers">Careers</a></li>
                        <li><a href="/press">Press</a></li>
                        <li><a href="/blog">Blog</a></li>
                    </ul>
                </div>
                <div class="col-md-3">
                    <h5>Connect</h5>
                    <div style="display: flex; gap: 1rem;">
                        <a href="#"><i class="fab fa-facebook fa-lg"></i></a>
                        <a href="#"><i class="fab fa-twitter fa-lg"></i></a>
                        <a href="#"><i class="fab fa-instagram fa-lg"></i></a>
                        <a href="#"><i class="fab fa-linkedin fa-lg"></i></a>
                    </div>
                </div>
            </div>
            <div class="footer-divider"></div>
            <div class="footer-bottom">
                <p>&copy; 2025 E-Store. All rights reserved. | <a href="/privacy">Privacy</a> | <a href="/terms">Terms</a> | <a href="/cookies">Cookie Policy</a></p>
            </div>
        </div>
    </footer>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Best Practices for Site Designs

1. Always Include Viewport Meta Tag

<meta name="viewport" content="width=device-width, initial-scale=1.0">

This ensures proper rendering on mobile devices.

2. Use Semantic HTML

<!-- Good -->
<header>...</header>
<nav>...</nav>
<main>...</main>
<footer>...</footer>

<!-- Avoid -->
<div class="header">...</div>
<div class="nav">...</div>
<div class="main">...</div>
<div class="footer">...</div>

3. Keep Layouts Focused

A Site Design should define: - ✅ Structure (header, nav, footer) - ✅ Responsive breakpoints - ✅ Global styles (typography, spacing)

A Site Design should NOT: - ❌ Define page-specific content (that's for templates) - ❌ Include too much decorative code - ❌ Have hard-coded menu items (use dynamic navigation instead)

4. Use CSS Classes for Flexibility

<!-- Good: Use classes for styling -->
<div class="site-header">
    <div class="container">
        <h1 class="site-title">My Site</h1>
    </div>
</div>

<!-- Avoid: Inline styles -->
<div style="background-color: blue; padding: 20px;">
    <h1 style="color: white; font-size: 24px;">My Site</h1>
</div>

5. Test Responsive Behavior

Before publishing, verify: - [ ] Mobile (320px, 480px) - [ ] Tablet (768px) - [ ] Desktop (1024px+) - [ ] Large displays (1920px)

6. Optimize Performance

<!-- Minimize render-blocking resources -->
<link rel="stylesheet" href="critical.css">

<!-- Defer non-critical JS -->
<script defer src="analytics.js"></script>

<!-- Use modern image formats -->
<img src="logo.webp" alt="Logo" loading="lazy">

7. Consider Accessibility

<!-- Use semantic elements -->
<button class="hamburger" aria-label="Toggle navigation">
    <span class="hamburger-icon"></span>
</button>

<!-- Provide alt text -->
<img src="banner.jpg" alt="Welcome banner with company logo">

<!-- Use proper heading hierarchy -->
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>

When to Modify vs. Create New

When to Modify Existing Site Design

You should edit an existing Site Design when: - ✅ Updating colors (maintain consistency) - ✅ Adjusting spacing or sizing - ✅ Adding minor CSS classes - ✅ Fixing responsive issues

When to Create a New Site Design

You should create a new Site Design when: - ✅ Pages need fundamentally different structure - ✅ A section needs different navigation or footer - ✅ Landing pages have a different visual approach - ✅ Admin pages look completely different


Advanced: Custom CSS with Minimal Layout

If you prefer complete design control, create a minimal Site Design that pages can customize:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title</title>
</head>
<body>
    @RenderBody()

    <!-- Optional: Global footer script or analytics -->
    <script src="/js/analytics.js"></script>
</body>
</html>

Then each template or page can include its own CSS framework, custom styles, and unique design. This gives maximum flexibility but requires more coordination.


Tips and Best Practices for Site Designs

Philosophy: Simplicity and Flexibility

SkyCMS is designed to place as few restrictions as possible on how web developers implement the UI and framework. You have complete control over your technology choices, design approach, and implementation strategy. The system provides structure without limiting creativity or technical decisions.

Keep things as simple as possible. Simpler Site Designs: - Load faster (better performance) - Are easier to maintain and update - Have fewer potential points of failure - Make debugging easier - Reduce complexity for team members

Start minimal and add complexity only when necessary.


Performance Optimization

Use CDNs for Common Libraries

Recommendation: Use Content Delivery Networks (CDNs) for popular CSS and JavaScript libraries.

Why CDNs improve performance:

<!-- Good: Use CDN for popular libraries -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>

Benefits: 1. Browser caching — Users likely already have these files cached from other sites 2. Reduced server load — CDN handles delivery, not your server 3. Geographic distribution — CDN serves files from nearest location 4. High availability — CDN uptime typically exceeds individual servers 5. Bandwidth savings — Less traffic from your hosting

When NOT to use CDNs:

Version control concerns - You need to lock specific library versions - You can't tolerate unexpected updates or changes - Your deployment process requires fixed dependencies

Privacy and data sovereignty - You need to keep all web traffic private - Regulatory requirements prevent external requests - Corporate policies prohibit third-party resources

Custom libraries - You've modified the library code - You have proprietary or internal-only libraries - You need libraries not available on CDNs

Offline/intranet applications - App must work without internet access - Internal-only network with no external access

In these cases, self-host your CSS/JS libraries:

<!-- Self-hosted alternative -->
<link href="/css/vendor/bootstrap.min.css" rel="stylesheet">
<script src="/js/vendor/bootstrap.bundle.min.js"></script>

Minify CSS and JavaScript for Production

Always minify resources before deployment:

<!-- Development: Use readable versions -->
<link href="/css/site.css" rel="stylesheet">

<!-- Production: Use minified versions -->
<link href="/css/site.min.css" rel="stylesheet">

Benefits: - Reduces file size by 30-70% - Faster downloads and page loads - Less bandwidth consumption

Tools: - CSS: cssnano, clean-css, UglifyCSS - JavaScript: UglifyJS, Terser, esbuild

Implement Lazy Loading

Load images and resources only when needed:

<!-- Lazy load images -->
<img src="logo.jpg" alt="Logo" loading="lazy">

<!-- Defer non-critical JavaScript -->
<script defer src="/js/analytics.js"></script>
<script defer src="/js/comments.js"></script>

What to lazy load: - Below-the-fold images - Non-critical JavaScript - Social media widgets - Ads and tracking scripts

What NOT to lazy load: - Above-the-fold images - Critical CSS - Core functionality scripts

Use Critical CSS

Inline critical above-the-fold CSS to eliminate render-blocking:

<head>
    <!-- Inline critical CSS -->
    <style>
        /* Critical styles for above-the-fold content */
        body { margin: 0; font-family: sans-serif; }
        .header { background: #fff; padding: 1rem; }
        .nav { display: flex; gap: 1rem; }
    </style>

    <!-- Load full CSS asynchronously -->
    <link rel="preload" href="/css/site.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="/css/site.css"></noscript>
</head>

Benefits: - Faster initial render - Improved perceived performance - Better Core Web Vitals scores

Tools: - Critical (npm package) - Penthouse - Critters (Next.js built-in)

Optimize Images

<!-- Use modern image formats -->
<picture>
  <source srcset="hero.webp" type="image/webp">
  <source srcset="hero.jpg" type="image/jpeg">
  <img src="hero.jpg" alt="Hero image" loading="lazy">
</picture>

<!-- Responsive images -->
<img srcset="logo-small.jpg 480w, logo-medium.jpg 800w, logo-large.jpg 1200w"
     sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px"
     src="logo-medium.jpg" alt="Logo">

Image optimization tips: - Use WebP format (70-80% smaller than JPEG) - Implement responsive images with srcset - Compress images before upload - Set appropriate dimensions (don't serve 4K images for 400px display)

Reduce HTTP Requests

<!-- Bad: Multiple separate files -->
<link href="/css/reset.css" rel="stylesheet">
<link href="/css/layout.css" rel="stylesheet">
<link href="/css/typography.css" rel="stylesheet">
<link href="/css/components.css" rel="stylesheet">

<!-- Good: Combined file -->
<link href="/css/site.css" rel="stylesheet">

Strategies: - Combine CSS files into one - Combine JavaScript files into one - Use CSS sprites for icons - Inline small SVGs instead of external files

Preload and Prefetch Resources

<head>
    <!-- Preload critical resources -->
    <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="/css/critical.css" as="style">

    <!-- Prefetch resources for next page -->
    <link rel="prefetch" href="/about">
    <link rel="prefetch" href="/images/about-hero.jpg">

    <!-- DNS prefetch for external resources -->
    <link rel="dns-prefetch" href="https://fonts.googleapis.com">
</head>

Maintainability Best Practices

Use CSS Custom Properties (Variables)

Makes theming and updates much easier:

:root {
    /* Colors */
    --primary-color: #0066cc;
    --secondary-color: #6c757d;
    --text-color: #333;
    --bg-color: #fff;

    /* Spacing */
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 2rem;

    /* Typography */
    --font-main: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-heading: Georgia, serif;
    --font-size-base: 1rem;
    --font-size-lg: 1.25rem;
}

/* Use variables throughout */
body {
    font-family: var(--font-main);
    font-size: var(--font-size-base);
    color: var(--text-color);
    background-color: var(--bg-color);
}

.btn-primary {
    background-color: var(--primary-color);
    padding: var(--spacing-md) var(--spacing-lg);
}

Benefits: - Single source of truth for design values - Easy theme switching (including dark mode) - Consistent styling across site - Quick global changes

Avoid Inline Styles

<!-- Bad: Inline styles are hard to maintain -->
<div style="background-color: blue; padding: 20px; margin: 10px; font-size: 16px;">
    Content
</div>

<!-- Good: Use CSS classes -->
<div class="card">
    Content
</div>

Why classes are better: - Reusable across multiple elements - Easier to update globally - Better performance (classes are cached) - Separation of concerns (HTML for structure, CSS for style)

Comment Your Code

<!-- HEADER SECTION
     Sticky header with logo and navigation
     Responsive: Hamburger menu on mobile (<768px) -->
<header class="site-header">
    <!-- Logo -->
    <div class="logo">
        <h1>Company Name</h1>
    </div>

    <!-- Main Navigation -->
    <nav class="main-nav">
        <!-- ... -->
    </nav>
</header>
/* =================================
   HEADER STYLES
   ================================= */

/* Logo section - fixed height for consistency */
.logo {
    height: 60px;
    display: flex;
    align-items: center;
}

/* Mobile: Stack navigation vertically below 768px */
@media (max-width: 768px) {
    .main-nav {
        display: none; /* Hidden by default, shown via JS toggle */
    }
}

Keep Selectors Simple

/* Bad: Overly specific selectors */
body div.container section.main-content article.post div.content p.text {
    font-size: 1rem;
}

/* Good: Simple, maintainable selectors */
.post-content p {
    font-size: 1rem;
}

Version Your Custom CSS/JS Files (Cache Busting)

<!-- Add version query string for cache busting -->
<link href="/css/site.css?v=2.1.0" rel="stylesheet">
<script src="/js/site.js?v=2.1.0"></script>

<!-- Or use hash-based versioning (build tools) -->
<link href="/css/site.a3f5b8.css" rel="stylesheet">
<script src="/js/site.e9c2d1.js"></script>

When to update version: - After CSS changes - After JavaScript updates - After bug fixes - During deployments


Accessibility Best Practices

Use Semantic HTML

<!-- Good: Semantic elements -->
<header>
    <nav>
        <ul>
            <li><a href="/">Home</a></li>
        </ul>
    </nav>
</header>

<main>
    <article>
        <h1>Article Title</h1>
        <p>Content</p>
    </article>
</main>

<footer>
    <p>&copy; 2025 Company</p>
</footer>

<!-- Avoid: Generic div soup -->
<div class="header">
    <div class="nav">
        <div class="menu">...</div>
    </div>
</div>

Benefits: - Better screen reader support - Improved SEO - Clearer code structure - Better browser parsing

Add ARIA Labels Where Needed

<!-- Navigation toggle button -->
<button class="hamburger" 
        aria-label="Toggle navigation menu" 
        aria-expanded="false">
    <span class="hamburger-icon"></span>
</button>

<!-- Search form -->
<form role="search">
    <label for="search">Search</label>
    <input type="search" id="search" aria-label="Search the website">
    <button type="submit" aria-label="Submit search">Search</button>
</form>

<!-- Skip to main content link -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<main id="main-content">...</main>

Ensure Sufficient Color Contrast

/* Bad: Low contrast (fails WCAG) */
.text {
    color: #999;
    background-color: #fff;
}

/* Good: High contrast (passes WCAG AA) */
.text {
    color: #333;
    background-color: #fff;
}

/* Tool: Use contrast checker to verify */

WCAG Standards: - AA: 4.5:1 contrast ratio for normal text - AA: 3:1 contrast ratio for large text - AAA: 7:1 contrast ratio for normal text

Support Keyboard Navigation

/* Always show focus indicators */
a:focus,
button:focus,
input:focus {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* Never remove focus outline without replacement */
/* Bad: */
*:focus { outline: none; }

/* Good: Custom focus style */
*:focus {
    outline: 2px solid #0066cc;
}

Security Best Practices

Use Subresource Integrity (SRI) for CDN Resources

<!-- With SRI: Prevents tampered files from loading -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" 
        integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
        crossorigin="anonymous"></script>

<!-- Without SRI: Vulnerable to CDN compromise -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>

How to get SRI hashes: - Most CDNs provide them (jsdelivr, cdnjs, unpkg) - Generate with: openssl dgst -sha384 -binary file.js | openssl base64 -A

Always Use HTTPS for External Resources

<!-- Good: HTTPS only -->
<link href="https://fonts.googleapis.com/css2?family=Roboto" rel="stylesheet">

<!-- Bad: HTTP (insecure) -->
<link href="http://fonts.googleapis.com/css2?family=Roboto" rel="stylesheet">

<!-- Bad: Protocol-relative URLs (deprecated) -->
<link href="//fonts.googleapis.com/css2?family=Roboto" rel="stylesheet">

Implement Content Security Policy (CSP)

<head>
    <!-- Define Content Security Policy -->
    <meta http-equiv="Content-Security-Policy" 
          content="default-src 'self'; 
                   script-src 'self' https://cdn.jsdelivr.net; 
                   style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
                   font-src 'self' https://fonts.gstatic.com;">
</head>

Benefits: - Prevents XSS attacks - Restricts resource loading - Mitigates injection attacks


Development Workflow Best Practices

Mobile-First Responsive Design

/* Mobile-first: Base styles for mobile */
.container {
    width: 100%;
    padding: 1rem;
}

.grid {
    display: block; /* Stacked on mobile */
}

/* Tablet and up */
@media (min-width: 768px) {
    .container {
        max-width: 720px;
        margin: 0 auto;
    }

    .grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Desktop and up */
@media (min-width: 1024px) {
    .container {
        max-width: 960px;
    }

    .grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

Why mobile-first: - Majority of traffic is mobile - Easier to scale up than down - Better performance on mobile devices - Forces focus on essential content

Test Across Browsers and Devices

Minimum testing matrix: - [ ] Chrome (latest) - [ ] Firefox (latest) - [ ] Safari (latest) - [ ] Edge (latest) - [ ] Mobile Safari (iOS) - [ ] Chrome Mobile (Android)

Screen sizes to test: - [ ] Mobile: 375px, 414px (iPhone) - [ ] Tablet: 768px, 1024px (iPad) - [ ] Desktop: 1366px, 1920px - [ ] Large: 2560px+ (4K monitors)

Tools: - Browser DevTools device emulation - BrowserStack or LambdaTest - Real device testing when possible

Consider Dark Mode Support

/* Light mode (default) */
:root {
    --bg-color: #ffffff;
    --text-color: #333333;
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
    :root {
        --bg-color: #1a1a1a;
        --text-color: #e0e0e0;
    }
}

/* Use variables throughout */
body {
    background-color: var(--bg-color);
    color: var(--text-color);
}

Benefits: - Better user experience - Reduces eye strain - Saves battery on OLED screens - Modern, expected feature


Font Optimization

<head>
    <!-- Preload fonts -->
    <link rel="preload" href="/fonts/main-regular.woff2" as="font" type="font/woff2" crossorigin>

    <!-- Font display strategy -->
    <style>
        @font-face {
            font-family: 'CustomFont';
            src: url('/fonts/main-regular.woff2') format('woff2');
            font-display: swap; /* Show fallback immediately, swap when loaded */
        }
    </style>
</head>

Font display options: - swap: Show fallback immediately (best for most cases) - block: Wait briefly for font (can cause flash) - fallback: Show fallback, swap if font loads quickly - optional: Let browser decide based on connection speed

Best practices: - Subset fonts (include only needed characters) - Use WOFF2 format (best compression) - Limit number of font families (1-2 max) - Limit font weights loaded (only what you use)


Common Issues and Solutions

Issue: Navigation items are hard-coded

Problem: You manually typed menu items instead of using dynamic navigation

Solution: Use a navigation management system or data structure that templates can loop through

Issue: Mobile menu doesn't work

Problem: JavaScript for toggle button isn't loading or Bootstrap JS missing

Solution: - Verify <script src="proxy.php?url=https%3A%2F%2Fdocs.sky-cms.com%2Fbootstrap.bundle.min.js"></script> is included - Check that data attributes are correct: data-bs-toggle="collapse"

Issue: Responsive design breaks at certain widths

Problem: Bootstrap breakpoints don't match your wireframe

Solution: - Test at Bootstrap's standard breakpoints (sm: 576px, md: 768px, lg: 992px, xl: 1200px) - Or customize breakpoints if using Tailwind

Problem: Content is shorter than viewport, footer floats

Solution:

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

main {
    flex: 1;
}


Security Considerations

Protect Against XSS (Cross-Site Scripting)

Always sanitize user input in layouts:

<!-- Good: Razor automatically encodes -->
<h1>@ViewBag.Title</h1>

<!-- Bad: Unencoded HTML -->
<h1>@Html.Raw(ViewBag.Title)</h1>

Validate External Resources

When including external CSS/JS: - ✅ Use HTTPS URLs only - ✅ Verify CDN integrity with Subresource Integrity (SRI) - ✅ Keep libraries updated

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" 
        integrity="sha384-..." 
        crossorigin="anonymous"></script>

Checklist: Site Design Completion

Before moving to Phase 3, verify you have:

  • [ ] Site Design Created
  • Name clearly describes purpose
  • Includes header, navigation, main content area, footer

  • [ ] Responsive Design Tested

  • Works at 375px (mobile)
  • Works at 768px (tablet)
  • Works at 1024px+ (desktop)
  • No horizontal overflow or text cutoff

  • [ ] Framework Chosen

  • Bootstrap, Tailwind, custom CSS, or other
  • All needed CSS/JS files included

  • [ ] Performance Verified

  • CSS/JS resources load correctly
  • Page renders without console errors
  • Load time is acceptable

  • [ ] Documentation Added

  • Site Design has clear name and description
  • Any special classes or conventions documented

  • [ ] Navigation Clear

  • Main menu items are visible and clickable
  • Mobile menu works on small screens
  • Link paths are correct (or will be filled by content team)

Next Steps

Once you've created your Site Design(s):

  1. Test with a template — Phase 3 will walk you through creating templates that use your Site Design
  2. Iterate if needed — After Phase 3, you might realize design adjustments needed; that's normal
  3. Proceed to Phase 3 — Creating Templates that use your Site Design

Resources

Framework Documentation


Duration Estimate: 4-8 hours
Key Deliverable: One or more complete Site Designs ready for Phase 3

When to Proceed to Phase 3: When your Site Design renders correctly, is responsive, and you're satisfied with the structure and styling.