Ghost CMS Theme CSS Editing Guide

Table of Contents

  1. Understanding Ghost Theme Structure
  2. CSS Editing Methods
  3. Theme Development Environment Setup
  4. CSS File Structure and Organization
  5. Code Injection Method
  6. Direct Theme File Editing
  7. Advanced CSS Techniques
  8. Performance Optimization
  9. Testing and Debugging
  10. Deployment Best Practices

Understanding Ghost Theme Structure

Ghost themes follow a specific directory structure that determines how CSS is loaded and applied:

theme-name/
├── assets/
│   ├── css/
│   │   ├── screen.css (main stylesheet)
│   │   ├── print.css (print styles)
│   │   └── custom.css (custom modifications)
│   ├── js/
│   └── images/
├── partials/
├── package.json
├── index.hbs
├── post.hbs
├── page.hbs
└── default.hbs

Key CSS Files

  • screen.css: Primary stylesheet containing all visual styles
  • print.css: Print-specific styles for better printing experience
  • custom.css: Optional file for theme customizations

CSS Editing Methods

  • Pros: No file system access required, easy to implement
  • Cons: Limited to additions, cannot modify existing rules efficiently
  • Best for: Small customizations, color changes, typography adjustments

Method 2: Direct Theme Editing

  • Pros: Complete control, can modify any aspect
  • Cons: Requires file system access, version control recommended
  • Best for: Major customizations, theme development

Method 3: Child Theme Creation

  • Pros: Preserves original theme, update-safe
  • Cons: Requires advanced knowledge
  • Best for: Extensive modifications while maintaining updateability

Theme Development Environment Setup

Local Development Setup

  1. Install Ghost CLI
npm install ghost-cli@latest -g
  1. Create Local Ghost Instance
mkdir my-ghost-site
cd my-ghost-site
ghost install local
  1. Access Theme Directory
cd content/themes/
  1. Set Up Version Control
git init
git add .
git commit -m "Initial theme backup"
  • Code Editor: VS Code with Ghost theme extensions
  • Browser DevTools: Chrome/Firefox Developer Tools
  • CSS Preprocessor: Sass/SCSS for advanced development
  • Build Tools: Gulp or Webpack for asset compilation

CSS File Structure and Organization

/* ==========================================================================
   TABLE OF CONTENTS
   ========================================================================== */

/*
 1. VARIABLES & MIXINS
 2. BASE STYLES
 3. TYPOGRAPHY
 4. LAYOUT
 5. COMPONENTS
 6. UTILITIES
 7. MEDIA QUERIES
*/

/* ==========================================================================
   1. VARIABLES & MIXINS
   ========================================================================== */

:root {
    /* Color Palette */
    --primary-color: #667eea;
    --secondary-color: #764ba2;
    --accent-color: #f093fb;
    --text-primary: #2d3748;
    --text-secondary: #718096;
    --bg-primary: #ffffff;
    --bg-secondary: #f7fafc;
    
    /* Typography */
    --font-primary: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-secondary: Georgia, serif;
    --font-mono: 'SF Mono', Monaco, monospace;
    
    /* Spacing */
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 2rem;
    --spacing-xl: 4rem;
    
    /* Breakpoints */
    --breakpoint-sm: 576px;
    --breakpoint-md: 768px;
    --breakpoint-lg: 992px;
    --breakpoint-xl: 1200px;
    
    /* Shadows */
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
    
    /* Transitions */
    --transition-fast: 0.15s ease;
    --transition-base: 0.3s ease;
    --transition-slow: 0.5s ease;
}

/* ==========================================================================
   2. BASE STYLES
   ========================================================================== */

html {
    font-size: 62.5%; /* 1rem = 10px */
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-primary);
    font-size: 1.6rem;
    line-height: 1.6;
    color: var(--text-primary);
    background-color: var(--bg-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

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

/* ==========================================================================
   3. TYPOGRAPHY
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-primary);
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: var(--spacing-md);
    color: var(--text-primary);
}

h1 { font-size: 3.2rem; }
h2 { font-size: 2.8rem; }
h3 { font-size: 2.4rem; }
h4 { font-size: 2.0rem; }
h5 { font-size: 1.8rem; }
h6 { font-size: 1.6rem; }

p {
    margin-bottom: var(--spacing-md);
    color: var(--text-secondary);
}

a {
    color: var(--primary-color);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--secondary-color);
    text-decoration: underline;
}

/* ==========================================================================
   4. LAYOUT
   ========================================================================== */

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--spacing-md);
}

.site-wrapper {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.site-header {
    background: var(--bg-primary);
    border-bottom: 1px solid #e2e8f0;
    position: sticky;
    top: 0;
    z-index: 100;
}

.site-main {
    flex: 1;
    padding: var(--spacing-xl) 0;
}

.site-footer {
    background: var(--bg-secondary);
    padding: var(--spacing-lg) 0;
    border-top: 1px solid #e2e8f0;
}

/* ==========================================================================
   5. COMPONENTS
   ========================================================================== */

/* Navigation */
.site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-md) 0;
}

.site-nav-logo {
    font-size: 2.4rem;
    font-weight: 800;
    color: var(--text-primary);
}

.site-nav-menu {
    display: flex;
    list-style: none;
    margin: 0;
    padding: 0;
    gap: var(--spacing-lg);
}

.site-nav-menu a {
    font-weight: 500;
    transition: color var(--transition-fast);
}

/* Post Cards */
.post-card {
    background: var(--bg-primary);
    border-radius: 8px;
    box-shadow: var(--shadow-md);
    overflow: hidden;
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.post-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
}

.post-card-image {
    width: 100%;
    height: 200px;
    object-fit: cover;
}

.post-card-content {
    padding: var(--spacing-lg);
}

.post-card-title {
    margin-bottom: var(--spacing-sm);
    font-size: 2.0rem;
}

.post-card-excerpt {
    color: var(--text-secondary);
    margin-bottom: var(--spacing-md);
}

.post-card-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 1.4rem;
    color: var(--text-secondary);
}

/* Buttons */
.btn {
    display: inline-block;
    padding: var(--spacing-sm) var(--spacing-lg);
    border: none;
    border-radius: 4px;
    font-size: 1.4rem;
    font-weight: 600;
    text-align: center;
    cursor: pointer;
    transition: all var(--transition-fast);
    text-decoration: none;
}

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

.btn-primary:hover {
    background: var(--secondary-color);
    transform: translateY(-1px);
}

.btn-secondary {
    background: transparent;
    color: var(--primary-color);
    border: 2px solid var(--primary-color);
}

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

/* ==========================================================================
   6. UTILITIES
   ========================================================================== */

.text-center { text-align: center; }
.text-left { text-align: left; }
.text-right { text-align: right; }

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--spacing-xs); }
.mt-2 { margin-top: var(--spacing-sm); }
.mt-3 { margin-top: var(--spacing-md); }
.mt-4 { margin-top: var(--spacing-lg); }

.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: var(--spacing-xs); }
.mb-2 { margin-bottom: var(--spacing-sm); }
.mb-3 { margin-bottom: var(--spacing-md); }
.mb-4 { margin-bottom: var(--spacing-lg); }

.hidden { display: none; }
.visible { display: block; }

/* ==========================================================================
   7. MEDIA QUERIES
   ========================================================================== */

@media (max-width: 768px) {
    html { font-size: 56.25%; } /* Reduce base font size */
    
    .container {
        padding: 0 var(--spacing-sm);
    }
    
    .site-nav {
        flex-direction: column;
        gap: var(--spacing-md);
    }
    
    .site-nav-menu {
        gap: var(--spacing-md);
    }
    
    h1 { font-size: 2.8rem; }
    h2 { font-size: 2.4rem; }
    h3 { font-size: 2.0rem; }
}

@media (max-width: 480px) {
    .site-nav-menu {
        flex-direction: column;
        gap: var(--spacing-sm);
    }
    
    .post-card-content {
        padding: var(--spacing-md);
    }
}

Code Injection Method

Accessing Code Injection

  1. Navigate to Ghost AdminSettingsCode Injection
  2. Three injection points available:
    • Site Header: CSS and meta tags
    • Site Footer: JavaScript before closing </body>
    • Post Footer: Content after each post

Site Header CSS Injection

<style>
/* Custom Theme Modifications */

/* Override primary colors */
:root {
    --ghost-accent-color: #667eea;
}

/* Custom header styling */
.site-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.site-header .site-nav-logo,
.site-header .nav a {
    color: white !important;
}

.site-header .nav a:hover {
    color: rgba(255,255,255,0.8) !important;
}

/* Enhanced post cards */
.post-card {
    border: none;
    border-radius: 12px;
    overflow: hidden;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.post-card:hover {
    transform: translateY(-8px);
    box-shadow: 0 12px 24px rgba(0,0,0,0.15);
}

/* Custom typography */
.post-card-title {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-weight: 700;
    line-height: 1.3;
    color: #1a202c;
}

.post-card-excerpt {
    color: #718096;
    line-height: 1.6;
}

/* Reading progress bar */
.reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 0%;
    height: 3px;
    background: linear-gradient(90deg, #667eea, #764ba2);
    z-index: 9999;
    transition: width 0.3s ease;
}

/* Custom button styles */
.gh-btn {
    background: linear-gradient(135deg, #667eea, #764ba2);
    border: none;
    border-radius: 25px;
    padding: 12px 24px;
    color: white;
    font-weight: 600;
    transition: all 0.3s ease;
    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.gh-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    :root {
        --color-base: #ffffff;
        --color-primary: #f7fafc;
        --color-secondary: #e2e8f0;
        --color-border: #4a5568;
        --color-bg: #1a202c;
    }
    
    body {
        background-color: var(--color-bg);
        color: var(--color-base);
    }
    
    .post-card {
        background: #2d3748;
        border: 1px solid #4a5568;
    }
}

/* Animation keyframes */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.post-card {
    animation: fadeInUp 0.6s ease-out;
}

/* Responsive improvements */
@media (max-width: 768px) {
    .site-header {
        padding: 1rem 0;
    }
    
    .post-card {
        margin-bottom: 2rem;
    }
    
    .post-card-content {
        padding: 1.5rem;
    }
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
    // Reading progress bar
    if (document.body.classList.contains('post-template')) {
        const progressBar = document.createElement('div');
        progressBar.className = 'reading-progress';
        document.body.appendChild(progressBar);
        
        window.addEventListener('scroll', function() {
            const article = document.querySelector('.gh-content');
            if (article) {
                const totalHeight = article.offsetHeight;
                const windowHeight = window.innerHeight;
                const scrollTop = window.scrollY;
                const articleTop = article.offsetTop;
                
                const progress = Math.max(0, Math.min(100, 
                    ((scrollTop - articleTop + windowHeight) / totalHeight) * 100
                ));
                
                progressBar.style.width = progress + '%';
            }
        });
    }
    
    // Smooth scroll for anchor links
    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function (e) {
            e.preventDefault();
            const target = document.querySelector(this.getAttribute('href'));
            if (target) {
                target.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }
        });
    });
    
    // Lazy load images
    if ('IntersectionObserver' in window) {
        const imageObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const img = entry.target;
                    img.src = img.dataset.src;
                    img.classList.remove('lazy');
                    imageObserver.unobserve(img);
                }
            });
        });
        
        document.querySelectorAll('img[data-src]').forEach(img => {
            imageObserver.observe(img);
        });
    }
});
</script>

Direct Theme File Editing

Accessing Theme Files

Via FTP/SFTP:

/var/www/ghost/content/themes/your-theme-name/assets/css/

Via Ghost Admin (if enabled): Settings → Design → Theme → Edit

Modifying screen.css

/* Add at the beginning of screen.css for better organization */

/* ==========================================================================
   CUSTOM MODIFICATIONS
   Add all custom styles here to make updates easier
   ========================================================================== */

/* Color scheme override */
:root {
    --ghost-accent-color: #667eea;
    --color-primary: #667eea;
    --color-secondary: #764ba2;
}

/* Typography enhancements */
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    line-height: 1.7;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 700;
    letter-spacing: -0.02em;
}

/* Header customization */
.site-header {
    backdrop-filter: blur(10px);
    background: rgba(255, 255, 255, 0.95);
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

/* Post layout improvements */
.post-full-content {
    max-width: 800px;
    margin: 0 auto;
}

.post-full-content p {
    font-size: 1.125rem;
    line-height: 1.8;
    margin-bottom: 1.5rem;
}

.post-full-content h2 {
    margin-top: 3rem;
    margin-bottom: 1rem;
    font-size: 1.875rem;
}

/* Code block styling */
.post-full-content pre {
    background: #1a202c;
    color: #e2e8f0;
    border-radius: 8px;
    padding: 1.5rem;
    overflow-x: auto;
    font-size: 0.875rem;
    line-height: 1.6;
}

.post-full-content code {
    background: #f7fafc;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    font-size: 0.875rem;
    color: #2d3748;
}

.post-full-content pre code {
    background: transparent;
    padding: 0;
    color: inherit;
}

/* Table styling */
.post-full-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 2rem 0;
    font-size: 0.9375rem;
}

.post-full-content table th,
.post-full-content table td {
    padding: 0.75rem;
    text-align: left;
    border-bottom: 1px solid #e2e8f0;
}

.post-full-content table th {
    background: #f7fafc;
    font-weight: 600;
    color: #2d3748;
}

/* Blockquote styling */
.post-full-content blockquote {
    border-left: 4px solid var(--ghost-accent-color);
    padding-left: 1.5rem;
    margin: 2rem 0;
    font-style: italic;
    color: #4a5568;
    background: #f7fafc;
    padding: 1.5rem;
    border-radius: 0 8px 8px 0;
}

/* Image enhancements */
.post-full-content img {
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    margin: 2rem 0;
}

/* Author bio styling */
.author-card {
    background: linear-gradient(135deg, #f7fafc, #edf2f7);
    border-radius: 12px;
    padding: 2rem;
    margin: 3rem 0;
    border: 1px solid #e2e8f0;
}

/* Subscribe form styling */
.subscribe-form {
    background: linear-gradient(135deg, var(--ghost-accent-color), #764ba2);
    color: white;
    padding: 2rem;
    border-radius: 12px;
    text-align: center;
}

.subscribe-form input[type="email"] {
    padding: 0.75rem 1rem;
    border: none;
    border-radius: 25px;
    margin-right: 0.5rem;
    font-size: 1rem;
}

.subscribe-form button {
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.3);
    padding: 0.75rem 1.5rem;
    border-radius: 25px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
}

.subscribe-form button:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
}

/* ==========================================================================
   END CUSTOM MODIFICATIONS
   ========================================================================== */

Advanced CSS Techniques

CSS Grid Layout for Posts

.posts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
    gap: 2rem;
    margin: 2rem 0;
}

.post-card {
    display: flex;
    flex-direction: column;
}

.post-card-content {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.post-card-excerpt {
    flex: 1;
}

.post-card-meta {
    margin-top: auto;
}

Advanced Animations

/* Scroll-triggered animations */
@keyframes slideInFromLeft {
    0% {
        transform: translateX(-100%);
        opacity: 0;
    }
    100% {
        transform: translateX(0);
        opacity: 1;
    }
}

.animate-on-scroll {
    opacity: 0;
    transform: translateY(20px);
    transition: all 0.6s ease-out;
}

.animate-on-scroll.animated {
    opacity: 1;
    transform: translateY(0);
}

/* Hover effects */
.post-card {
    position: relative;
    overflow: hidden;
}

.post-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
    transition: left 0.5s;
}

.post-card:hover::before {
    left: 100%;
}

CSS Custom Properties for Theming

/* Light theme (default) */
:root {
    --bg-primary: #ffffff;
    --bg-secondary: #f7fafc;
    --text-primary: #2d3748;
    --text-secondary: #718096;
    --border-color: #e2e8f0;
    --accent-color: #667eea;
}

/* Dark theme */
[data-theme="dark"] {
    --bg-primary: #1a202c;
    --bg-secondary: #2d3748;
    --text-primary: #f7fafc;
    --text-secondary: #cbd5e0;
    --border-color: #4a5568;
    --accent-color: #9f7aea;
}

/* Apply variables */
body {
    background-color: var(--bg-primary);
    color: var(--text-primary);
    transition: all 0.3s ease;
}

.post-card {
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}

Performance Optimization

CSS Optimization Techniques

/* Use efficient selectors */
.post-card { } /* Good: class selector */
.post-card .title { } /* Good: descendant selector */
div.post-card { } /* Avoid: element + class */
* { } /* Avoid: universal selector */

/* Minimize repaints and reflows */
.post-card {
    transform: translateZ(0); /* Create compositing layer */
    will-change: transform; /* Hint browser for optimization */
}

/* Use transform for animations */
.post-card:hover {
    transform: translateY(-4px); /* Better than changing top/margin */
}

/* Optimize images */
.post-card-image {
    object-fit: cover;
    width: 100%;
    height: 200px;
    background: #f7fafc; /* Fallback while loading */
}

Critical CSS Extraction

/* Above-the-fold critical CSS */
body, .site-header, .site-nav { 
    /* Include only essential styles for initial render */
}

/* Non-critical CSS - load asynchronously */
@media print {
    /* Print styles */
}

.modal, .tooltip, .dropdown {
    /* Interactive elements not immediately visible */
}

Testing and Debugging

Browser DevTools Usage

  1. Inspect Element: Right-click → Inspect
  2. Styles Panel: View computed styles and cascade
  3. Console: Check for CSS errors
  4. Performance Tab: Analyze rendering performance

CSS Validation

# Use CSS validators
curl -H "Content-Type: text/css" --data-binary @screen.css \
  https://jigsaw.w3.org/css-validator/validator

Cross-Browser Testing

/* Browser prefixes for compatibility */
.element {
    -webkit-transform: scale(1.1);
    -moz-transform: scale(1.1);
    -ms-transform: scale(1.1);
    transform: scale(1.1);
}

/* Feature queries */
@supports (display: grid) {
    .posts-container {
        display: grid;
    }
}

@supports not (display: grid) {
    .posts-container {
        display: flex;
        flex-wrap: wrap;
    }
}

Deployment Best Practices

Version Control

# Initialize Git repository
git init
git add assets/css/
git commit -m "Initial CSS version"

# Create backup before major changes
git branch backup-$(date +%Y%m%d)
git checkout -b feature/new-styling

Minification

/* Development version - readable */
.post-card {
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: all 0.3s ease;
}

/* Production version - minified */
.post-card{background:#fff;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,.1);transition:all .3s ease}

Build Process

// gulpfile.js example
const gulp = require('gulp');
const sass = require('gulp-sass');
const cleanCSS = require('gulp-clean-css');
const autoprefixer = require('gulp-autoprefixer');

gulp.task('css', function() {
    return gulp.src('assets/scss/**/*.scss')
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(cleanCSS())
        .pipe(gulp.dest('assets/css/'));
});

Deployment Checklist

  • [ ] Backup original theme files
  • [ ] Test CSS changes in development environment
  • [ ] Validate CSS syntax
  • [ ] Check cross-browser compatibility
  • [ ] Optimize and minify CSS
  • [ ] Test responsive design on multiple devices
  • [ ] Verify accessibility compliance
  • [ ] Upload to production server
  • [ ] Clear Ghost cache
  • [ ] Test live site functionality

Troubleshooting Common Issues

CSS Not Loading

/* Check file paths in default.hbs */
<link rel="stylesheet" type="text/css" href="{{asset "css/screen.css"}}" />

/* Verify file permissions */
chmod 644 screen.css

Styles Not Applying

/* Increase specificity */
.site-main .post-card { } /* More specific */
.post-card { } /* Less specific */

/* Use !important sparingly */
.post-card {
    background: white !important; /* Last resort */
}

Mobile Responsiveness Issues

/* Use proper viewport meta tag in default.hbs */
<meta name="viewport" content="width=device-width, initial-scale=1.0">

/* Test with proper breakpoints */
@media (max-width: 768px) {
    .post-card {
        margin-bottom: 1rem;
    }
}

/* Use relative units */
.container {
    width: 90%; /* Better than fixed pixels */
    max-width: 1200px;
}

Performance Issues

/* Avoid expensive properties */
.element {
    /* Avoid */
    box-shadow: 0 0 20px rgba(0,0,0,0.5);
    border-radius: 50%;
    
    /* Better */
    transform: translateZ(0); /* GPU acceleration */
    will-change: transform;
}

/* Optimize animations */
@keyframes slideIn {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}

/* Instead of animating width/height */
@keyframes badSlideIn {
    from { width: 0; }
    to { width: 100%; }
}

Advanced Customization Examples

Custom Post Templates by Tag

/* Style posts differently based on tags */
.tag-tutorial .post-card {
    border-left: 4px solid #38a169;
    background: linear-gradient(135deg, #f0fff4, #c6f6d5);
}

.tag-news .post-card {
    border-left: 4px solid #3182ce;
    background: linear-gradient(135deg, #ebf8ff, #bee3f8);
}

.tag-review .post-card {
    border-left: 4px solid #d69e2e;
    background: linear-gradient(135deg, #fffaf0, #faf089);
}

Interactive Elements

/* Custom hover states */
.post-card {
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.post-card:hover {
    transform: translateY(-8px) scale(1.02);
    box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}

/* Loading states */
.loading {
    position: relative;
    overflow: hidden;
}

.loading::after {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, 
        transparent, 
        rgba(255,255,255,0.4), 
        transparent
    );
    animation: loading 1.5s infinite;
}

@keyframes loading {
    0% { left: -100%; }
    100% { left: 100%; }
}

Advanced Layout Techniques

/* CSS Grid for complex layouts */
.post-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-auto-rows: minmax(200px, auto);
    gap: 2rem;
}

/* Feature specific posts */
.post-card.featured {
    grid-column: span 2;
    grid-row: span 2;
}

/* Masonry-like layout with flexbox */
.masonry-container {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    height: 100vh;
    align-content: flex-start;
}

.masonry-item {
    width: 48%;
    margin-bottom: 2rem;
    break-inside: avoid;
}

/* Sticky elements */
.sidebar {
    position: sticky;
    top: 2rem;
    height: fit-content;
}

SEO and Accessibility Considerations

SEO-Friendly CSS

/* Proper heading hierarchy */
h1 { font-size: 2.5rem; } /* One h1 per page */
h2 { font-size: 2rem; }   /* Section headings */
h3 { font-size: 1.75rem; } /* Subsections */

/* Breadcrumb styling */
.breadcrumb {
    font-size: 0.875rem;
    color: #718096;
    margin-bottom: 1rem;
}

.breadcrumb a {
    color: inherit;
    text-decoration: none;
}

.breadcrumb a:hover {
    text-decoration: underline;
}

/* Schema.org structured data styling */
.hentry {
    /* Article structured data */
}

.author {
    /* Author information */
}

.published {
    /* Publication date */
}

Accessibility Best Practices

/* Focus states for keyboard navigation */
a:focus,
button:focus,
input:focus {
    outline: 2px solid #667eea;
    outline-offset: 2px;
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .post-card {
        border: 2px solid #000;
    }
    
    a {
        text-decoration: underline;
    }
}

/* Reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Screen reader only content */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Color contrast compliance */
:root {
    --text-primary: #1a202c; /* 4.5:1 contrast ratio minimum */
    --text-secondary: #4a5568; /* 3:1 for large text */
    --link-color: #2b6cb0; /* Sufficient contrast */
}
@media print {
    /* Hide navigation and non-essential elements */
    .site-header,
    .site-footer,
    .sidebar,
    .social-links,
    .comments {
        display: none;
    }
    
    /* Optimize typography for print */
    body {
        font-size: 12pt;
        line-height: 1.4;
        color: #000;
        background: #fff;
    }
    
    /* Page breaks */
    .post-card {
        page-break-inside: avoid;
        margin-bottom: 1cm;
    }
    
    h1, h2, h3 {
        page-break-after: avoid;
    }
    
    /* Show link URLs */
    a[href]:after {
        content: " (" attr(href) ")";
        font-size: 0.8em;
        color: #666;
    }
    
    /* Remove shadows and gradients */
    * {
        box-shadow: none !important;
        text-shadow: none !important;
        background-image: none !important;
    }
}

Security Considerations

CSS Security Best Practices

/* Avoid user-generated content in CSS */
/* Never do this: */
.user-style {
    background: url('user-provided-url'); /* Potential XSS */
}

/* Content Security Policy headers */
/* Add to your server configuration: */
/* Content-Security-Policy: style-src 'self' 'unsafe-inline'; */

/* Sanitize dynamic values */
.dynamic-color {
    /* Validate color values on server-side before output */
    color: var(--validated-user-color);
}

Maintenance and Updates

Theme Update Strategy

/* Version comments */
/*
 * Theme: Custom Ghost Theme
 * Version: 2.1.0
 * Last Updated: 2025-01-15
 * Author: Your Name
 */

/* Change log */
/*
 * v2.1.0 - Added dark mode support
 * v2.0.0 - Major redesign with CSS Grid
 * v1.5.0 - Improved mobile responsiveness
 */

/* Dependencies */
/*
 * Requires: Ghost 5.0+
 * Fonts: Inter (Google Fonts)
 * Icons: Feather Icons
 */

Backup and Recovery

# Create automated backup script
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/ghost-themes"
THEME_DIR="/var/www/ghost/content/themes/your-theme"

# Create backup
tar -czf "$BACKUP_DIR/theme-backup-$DATE.tar.gz" "$THEME_DIR"

# Keep only last 10 backups
ls -t "$BACKUP_DIR"/theme-backup-*.tar.gz | tail -n +11 | xargs rm -f

echo "Backup created: theme-backup-$DATE.tar.gz"

Performance Monitoring

/* Add CSS for performance monitoring */
.perf-indicator {
    position: fixed;
    top: 10px;
    right: 10px;
    background: rgba(0,0,0,0.8);
    color: white;
    padding: 5px 10px;
    border-radius: 4px;
    font-size: 12px;
    z-index: 9999;
    display: none;
}

/* Show in development mode */
body.development .perf-indicator {
    display: block;
}

Conclusion

This comprehensive guide covers all aspects of CSS editing in Ghost CMS themes, from basic code injection to advanced theme development. Key takeaways:

  1. Start Simple: Use code injection for small modifications
  2. Plan Ahead: Create a development environment for major changes
  3. Follow Standards: Use semantic CSS and maintain consistency
  4. Test Thoroughly: Ensure cross-browser compatibility and responsiveness
  5. Optimize Performance: Minimize CSS and use efficient selectors
  6. Maintain Security: Validate user inputs and follow CSP guidelines
  7. Document Changes: Keep version history and change logs
  8. Backup Regularly: Always backup before making changes

Remember that CSS modifications can significantly impact your site's performance and user experience. Always test changes thoroughly before deploying to production, and consider the long-term maintainability of your customizations.

For additional resources and community support, visit the Ghost Developer Documentation and Ghost GitHub Repository.


This guide is maintained and updated regularly. For the latest version and additional resources, visit our documentation portal.

Read more

Ghost CMS vs WordPress: A Deep Technical Comparison for Developers and Publishers

The choice between Ghost CMS and WordPress extends far beyond surface-level features. For developers, system administrators, and technically-minded publishers, understanding the fundamental architectural differences, performance characteristics, and technical trade-offs between these platforms is crucial for making informed decisions. This comprehensive analysis examines both platforms through a technical lens, exploring everything