Skip to main content

Course Progress

Loading...

Creating a Consistent Layout with HTML and CSS

Duration: 60 minutes
Module 1: CSS Layout & Responsive Design

Learning Objectives

  • Create responsive layouts
  • Design for multiple devices
  • Use modern CSS techniques
  • Build flexible designs

The Foundation of Effective Web Design

Welcome to today's session on creating consistent layouts with HTML and CSS! A well-structured, consistent layout is the backbone of professional web design. It guides users through your content, reinforces your brand identity, and ensures a cohesive experience across your entire website. This consistency is especially important for WordPress sites, where multiple page templates and content types need to share a unified design language.

Think of your website layout as the floor plan of a building. Just as architects create blueprints to ensure logical room arrangements, proper traffic flow, and structural integrity, web designers use HTML and CSS to create digital "blueprints" that organize content, guide user navigation, and maintain visual consistency. And just as a well-designed building feels intuitive to navigate, a well-designed website feels natural and effortless to use.

In this lecture, we'll explore the principles and techniques for creating consistent layouts that work across multiple pages and content types. We'll focus on modern HTML5 semantic elements and CSS layout techniques that provide flexibility while maintaining design coherence—essential skills for WordPress theme development.

Semantic HTML: The Structural Foundation

Why Semantic HTML Matters

Semantic HTML uses elements that clearly describe their meaning to both browsers and developers. Using the right elements for the right purpose creates a solid foundation for consistent layouts.

Benefits of Semantic HTML

  • Accessibility: Screen readers and assistive technologies better understand your content
  • SEO: Search engines better understand your content's structure and importance
  • Maintainability: Code is more readable and easier to maintain
  • Consistency: Encourages logical, consistent document structure
  • Style targeting: Provides meaningful elements to target with CSS

Key Semantic HTML5 Elements

HTML Document Structure html head body header nav main footer section article aside h2 p figure header p footer Legend semantic = Semantic HTML5 elements standard = Standard HTML elements Semantic elements provide meaning and improve accessibility/SEO

Page Structure Elements

  • <header> - Introductory content or navigational aids for its parent section
  • <nav> - Section with navigation links
  • <main> - Main content of the document (only one per page)
  • <footer> - Footer for its parent section, typically containing authorship, copyright, or related links

Content Structure Elements

  • <section> - Standalone section that doesn't have a more specific semantic element
  • <article> - Self-contained composition (e.g., blog post, forum post, news article)
  • <aside> - Content tangentially related to the content around it (sidebars, call-out boxes)
  • <figure> and <figcaption> - Self-contained content (images, diagrams, code snippets) with optional caption
  • <details> and <summary> - Interactive disclosure widget

Basic Semantic Layout Template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Website</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header class="site-header">
        <div class="logo">
            <a href="index.html">
                <img src="logo.png" alt="Site Logo">
            </a>
        </div>
        
        <nav class="main-navigation">
            <ul>
                <li><a href="index.html">Home</a></li>
                <li><a href="about.html">About</a></li>
                <li><a href="services.html">Services</a></li>
                <li><a href="blog.html">Blog</a></li>
                <li><a href="contact.html">Contact</a></li>
            </ul>
        </nav>
    </header>
    
    <main class="site-content">
        <section class="hero">
            <h1>Welcome to My Website</h1>
            <p>Your compelling introduction here.</p>
        </section>
        
        <section class="featured-content">
            <h2>Featured Content</h2>
            
            <article class="featured-item">
                <h3>Article Title</h3>
                <p>Article content goes here.</p>
                <a href="article.html" class="read-more">Read more</a>
            </article>
            
            <article class="featured-item">
                <h3>Another Article Title</h3>
                <p>More article content.</p>
                <a href="another-article.html" class="read-more">Read more</a>
            </article>
        </section>
        
        <aside class="sidebar">
            <div class="widget">
                <h3>Categories</h3>
                <ul>
                    <li><a href="#">Category 1</a></li>
                    <li><a href="#">Category 2</a></li>
                    <li><a href="#">Category 3</a></li>
                </ul>
            </div>
        </aside>
    </main>
    
    <footer class="site-footer">
        <div class="footer-widgets">
            <div class="widget">
                <h4>About Us</h4>
                <p>Brief company description.</p>
            </div>
            
            <div class="widget">
                <h4>Quick Links</h4>
                <ul>
                    <li><a href="#">Link 1</a></li>
                    <li><a href="#">Link 2</a></li>
                    <li><a href="#">Link 3</a></li>
                </ul>
            </div>
            
            <div class="widget">
                <h4>Contact</h4>
                <address>
                    123 Main St<br>
                    Anytown, ST 12345<br>
                    info@example.com
                </address>
            </div>
        </div>
        
        <div class="copyright">
            <p>© 2025 My Website. All rights reserved.</p>
        </div>
    </footer>
</body>
</html>

WordPress Template Equivalents

When developing WordPress themes, these semantic elements map to specific template files:

Semantic Element WordPress Template Files
<header> header.php
<nav> nav.php, menu templates
<main> index.php, page.php, single.php
<article> content.php, template-parts/content.php
<aside> sidebar.php
<footer> footer.php

Common Website Layout Patterns

While each website is unique, certain layout patterns have become standard due to their effectiveness and user familiarity.

Standard Layout Types

Single Column Layout
Header Main Content Footer

Best for: Mobile views, focused content, landing pages

Two Column Layout (Sidebar)
Header Main Content Sidebar Footer

Best for: Blog layouts, content with related information

Three Column Layout
Header Sidebar 1 Main Content Sidebar 2 Footer

Best for: Complex websites with multiple navigation options

Holy Grail Layout
Header Left Sidebar Main Content Right Sidebar Footer

Best for: Complex applications, dashboards, content-rich websites

Responsive Design Considerations

Layouts need to adapt to different screen sizes while maintaining consistency:

Desktop Header Main Content Sidebar Footer Tablet Header Main Content Sidebar Footer Mobile Header Main Content Sidebar

When creating responsive layouts, follow these principles:

  • Mobile-First Approach: Design for mobile first, then enhance for larger screens
  • Layout Simplification: Collapse multi-column layouts into single columns on small screens
  • Content Prioritization: Ensure critical content appears first in the source order
  • Consistent Navigation: Maintain navigation patterns across screen sizes (e.g., hamburger menu on mobile)
  • Flexible Images: Make images responsive to fit their containers

Modern CSS Layout Techniques

The Evolution of CSS Layouts

CSS layout techniques have evolved dramatically over the years, giving developers increasingly powerful tools for creating flexible, consistent layouts.

Tables (Pre-CSS Era)

HTML tables were misused for layout purposes before proper CSS layout techniques existed.

Limitations: Rigid structures, accessibility issues, difficult maintenance, mixing of content and layout.

Float-Based Layouts

The first true CSS layout technique, using the float property to position elements.

Limitations: Clearing floats, equal height columns, complex nesting, order dependency.

Positioning

Using position: relative, absolute, and fixed for layout control.

Limitations: Removed from document flow, difficult responsive behavior, overlapping issues.

Flexbox

A one-dimensional layout method designed for laying out items in rows or columns.

Strengths: Alignment control, space distribution, order independence, equal heights.

CSS Grid

A two-dimensional layout system designed for complex grid-based layouts.

Strengths: True grid layouts, alignment in both dimensions, layout-first design, powerful placement syntax.

Flexbox: One-Dimensional Layout

Flexbox is perfect for layouts with a single axis (rows or columns) and for components within a larger layout.

Key Flexbox Concepts

Flex Container Flex Item 1 Flex Item 2 Flex Item 3 Main Axis (flex-direction: row) Cross Axis
Container Properties
  • display: flex - Defines a flex container
  • flex-direction - Sets the main axis (row, row-reverse, column, column-reverse)
  • flex-wrap - Controls whether items wrap to new lines (nowrap, wrap, wrap-reverse)
  • justify-content - Aligns items along the main axis (flex-start, flex-end, center, space-between, space-around, space-evenly)
  • align-items - Aligns items along the cross axis (flex-start, flex-end, center, baseline, stretch)
  • align-content - Aligns multiple lines along the cross axis (when wrapping)
Item Properties
  • flex-grow - How much an item can grow relative to other items
  • flex-shrink - How much an item can shrink relative to other items
  • flex-basis - Default size of an item before remaining space is distributed
  • flex - Shorthand for flex-grow, flex-shrink, and flex-basis
  • align-self - Overrides the container's align-items for a specific item
  • order - Controls the order in which items appear

Common Flexbox Use Cases

Navigation Menu
/* HTML */
<nav class="main-nav">
    <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

/* CSS */
.main-nav ul {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
}

.main-nav li {
    margin-right: 1rem;
}

/* Responsive: stack on mobile */
@media (max-width: 768px) {
    .main-nav ul {
        flex-direction: column;
    }
    
    .main-nav li {
        margin-right: 0;
        margin-bottom: 0.5rem;
    }
}
Card Layout
/* HTML */
<div class="card-container">
    <article class="card">
        <img src="image1.jpg" alt="Card image">
        <div class="card-content">
            <h3>Card Title 1</h3>
            <p>Card description...</p>
            <a href="#" class="btn">Read More</a>
        </div>
    </article>
    
    <article class="card">
        <img src="image2.jpg" alt="Card image">
        <div class="card-content">
            <h3>Card Title 2</h3>
            <p>Card description...</p>
            <a href="#" class="btn">Read More</a>
        </div>
    </article>
    
    <article class="card">
        <img src="image3.jpg" alt="Card image">
        <div class="card-content">
            <h3>Card Title 3</h3>
            <p>Card description...</p>
            <a href="#" class="btn">Read More</a>
        </div>
    </article>
</div>

/* CSS */
.card-container {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: space-between;
}

.card {
    flex: 0 1 calc(33.333% - 20px);
    display: flex;
    flex-direction: column;
    border: 1px solid #ddd;
    border-radius: 4px;
    overflow: hidden;
}

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

.card-content {
    padding: 15px;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.card-content .btn {
    margin-top: auto;
    align-self: flex-start;
}

/* Responsive */
@media (max-width: 992px) {
    .card {
        flex: 0 1 calc(50% - 15px);
    }
}

@media (max-width: 576px) {
    .card {
        flex: 0 1 100%;
    }
}

CSS Grid: Two-Dimensional Layout

CSS Grid allows you to create complex grid-based layouts with precise control over rows and columns.

Key Grid Concepts

Grid Container Header (1,1) to (3,1) Item 2 (4,1) to (6,1) Sidebar (1,2) to (1,3) Item 4 (2,2) to (6,2) Item 5 (2,3) to (5,3) Item 6 1 2 3 4 5 6 1 2 3 4 5 6
Container Properties
  • display: grid - Defines a grid container
  • grid-template-columns - Defines the columns of the grid
  • grid-template-rows - Defines the rows of the grid
  • grid-template-areas - Defines named grid areas
  • grid-gap - Sets the gap between grid items (shorthand for grid-row-gap and grid-column-gap)
  • justify-items - Aligns items horizontally within their cell
  • align-items - Aligns items vertically within their cell
  • justify-content - Aligns the entire grid horizontally
  • align-content - Aligns the entire grid vertically
Item Properties
  • grid-column - Specifies which column(s) the item should span
  • grid-row - Specifies which row(s) the item should span
  • grid-area - Specifies the item's location in a named grid area
  • justify-self - Aligns the item horizontally within its cell
  • align-self - Aligns the item vertically within its cell

Common Grid Layout Patterns

Holy Grail Layout with Grid
/* HTML */
<div class="grid-container">
    <header class="header">Header</header>
    <nav class="nav">Navigation</nav>
    <main class="main">Main Content</main>
    <aside class="sidebar">Sidebar</aside>
    <footer class="footer">Footer</footer>
</div>

/* CSS */
.grid-container {
    display: grid;
    grid-template-columns: 1fr 3fr 1fr;
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas:
        "header header header"
        "nav    nav    nav"
        "sidebar main   aside"
        "footer footer footer";
    min-height: 100vh;
    gap: 1rem;
}

.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.sidebar { grid-area: sidebar; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

/* Responsive */
@media (max-width: 768px) {
    .grid-container {
        grid-template-columns: 1fr;
        grid-template-areas:
            "header"
            "nav"
            "main"
            "sidebar"
            "aside"
            "footer";
    }
}
Photo Gallery with Grid
/* HTML */
<div class="gallery">
    <img src="image1.jpg" alt="Gallery image" class="gallery-item">
    <img src="image2.jpg" alt="Gallery image" class="gallery-item">
    <img src="image3.jpg" alt="Gallery image" class="gallery-item tall">
    <img src="image4.jpg" alt="Gallery image" class="gallery-item wide">
    <img src="image5.jpg" alt="Gallery image" class="gallery-item">
    <img src="image6.jpg" alt="Gallery image" class="gallery-item">
    <img src="image7.jpg" alt="Gallery image" class="gallery-item">
    <img src="image8.jpg" alt="Gallery image" class="gallery-item wide tall">
</div>

/* CSS */
.gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    grid-auto-rows: 250px;
    grid-auto-flow: dense;
    gap: 15px;
}

.gallery-item {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.wide {
    grid-column: span 2;
}

.tall {
    grid-row: span 2;
}

/* Responsive */
@media (max-width: 768px) {
    .wide, .tall {
        grid-column: auto;
        grid-row: auto;
    }
}

Choosing Between Flexbox and Grid

Both Flexbox and Grid are powerful layout tools, but they have different strengths and use cases.

Feature Flexbox CSS Grid
Dimensions One-dimensional (row OR column) Two-dimensional (rows AND columns)
Direction Items laid out in either row or column Items placed in defined grid cells
Content-driven Size determined by content Content placed in predefined grid
Alignment Great for alignment within an axis Complex alignment in two dimensions
Nesting Simple nesting for component layouts Powerful explicit placement for page layouts
Best for Navigation, card layouts, small UI components Page layouts, complex grid systems, image galleries

Best Practice: Use Both Together

Modern websites often use both techniques:

  • Use Grid for the overall page layout
  • Use Flexbox for components within the grid areas
  • Use Grid for complex, two-dimensional arrangements
  • Use Flexbox for simpler, one-dimensional arrangements
/* Example of using both together */
.site-container {
    display: grid;
    grid-template-columns: 1fr 3fr;
    grid-template-areas:
        "header header"
        "sidebar main"
        "footer footer";
    gap: 20px;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }

/* Using Flexbox inside a Grid area */
.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nav ul {
    display: flex;
    list-style: none;
    gap: 20px;
}

/* Card grid inside the main content */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
}

/* Each card uses Flexbox for internal layout */
.card {
    display: flex;
    flex-direction: column;
}

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

.card-footer {
    margin-top: auto;
}

Creating Responsive Layouts

Responsive Design Principles

Responsive web design ensures your layout works well on any device, from smartphones to large desktop monitors.

Core Principles

  • Fluid Grids: Using relative units instead of fixed pixels
  • Flexible Images: Images that scale with their containers
  • Media Queries: CSS rules that apply at specific screen sizes
  • Mobile-First: Design for mobile devices first, then enhance for larger screens
  • Content Priority: Organize content based on importance, not just visual appeal

Essential Responsive Techniques

Viewport Meta Tag

The viewport meta tag is essential for proper mobile rendering:

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

This tells mobile browsers to set the viewport width to the device width and initial zoom level to 1.

Relative Units

Use relative units instead of fixed pixels for responsive measurements:

  • % (percentage) - Relative to the parent element
  • em - Relative to the font-size of the element
  • rem - Relative to the font-size of the root element
  • vw/vh - Relative to the viewport width/height (1vw = 1% of viewport width)
  • fr - Fractional unit for Grid layouts
/* Responsive typography */
html {
    font-size: 16px;  /* Base font size */
}

h1 {
    font-size: 2.5rem;  /* 40px at default font size */
}

p {
    font-size: 1rem;   /* 16px at default font size */
    line-height: 1.5;  /* 24px at default font size */
    margin-bottom: 1.5rem;
}

/* Responsive container */
.container {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
}

/* Responsive image */
img {
    max-width: 100%;
    height: auto;
}

Media Queries

Media queries allow you to apply different styles based on the device characteristics:

/* Common breakpoints */
/* Mobile first approach - styles for small screens first */

/* Base styles for all screen sizes */
body {
    font-size: 16px;
    line-height: 1.5;
}

.container {
    width: 90%;
    margin: 0 auto;
}

/* For tablets and larger (768px and up) */
@media (min-width: 768px) {
    body {
        font-size: 17px;
    }
    
    .container {
        width: 85%;
    }
    
    .two-column {
        display: flex;
        gap: 2rem;
    }
    
    .two-column > * {
        flex: 1;
    }
}

/* For desktops (992px and up) */
@media (min-width: 992px) {
    body {
        font-size: 18px;
    }
    
    .container {
        width: 80%;
    }
    
    .three-column {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 2rem;
    }
}

/* For large desktops (1200px and up) */
@media (min-width: 1200px) {
    .container {
        width: 70%;
        max-width: 1140px;
    }
}

Responsive Navigation Patterns

Navigation often requires special handling for mobile devices:

/* HTML */
<nav class="main-nav">
    <div class="logo">Site Logo</div>
    
    <button class="menu-toggle" aria-expanded="false" aria-controls="primary-menu">
        <span class="screen-reader-text">Menu</span>
        <span class="hamburger"></span>
    </button>
    
    <ul id="primary-menu" class="menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

/* CSS */
.main-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
}

.menu {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
}

.menu li {
    margin-left: 1.5rem;
}

.menu-toggle {
    display: none;
}

/* Hamburger icon */
.hamburger {
    display: block;
    width: 25px;
    height: 3px;
    background: #333;
    position: relative;
}

.hamburger::before, 
.hamburger::after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    background: #333;
    left: 0;
}

.hamburger::before {
    top: -8px;
}

.hamburger::after {
    bottom: -8px;
}

/* Responsive menu */
@media (max-width: 768px) {
    .menu {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: #fff;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        flex-direction: column;
        padding: 1rem;
    }
    
    .menu.active {
        display: flex;
    }
    
    .menu li {
        margin: 0 0 1rem 0;
    }
    
    .menu-toggle {
        display: block;
        background: transparent;
        border: none;
        cursor: pointer;
    }
}

You would also need JavaScript to toggle the menu:

// JavaScript for the responsive menu
document.addEventListener('DOMContentLoaded', function() {
    const menuToggle = document.querySelector('.menu-toggle');
    const menu = document.querySelector('#primary-menu');
    
    menuToggle.addEventListener('click', function() {
        const expanded = this.getAttribute('aria-expanded') === 'true' || false;
        this.setAttribute('aria-expanded', !expanded);
        menu.classList.toggle('active');
    });
});

Responsive Images

Images often account for the majority of a page's file size, making them critical for responsive design.

Basic Responsive Images

/* CSS */
img {
    max-width: 100%;
    height: auto;
}

/* For background images */
.hero {
    background-image: url('image.jpg');
    background-size: cover;
    background-position: center;
    height: 50vh;
}

Advanced Responsive Images with srcset

The srcset attribute allows browsers to choose the best image based on the device's capabilities:

<img 
    src="image-800.jpg" 
    srcset="image-400.jpg 400w,
            image-800.jpg 800w,
            image-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw,
           (max-width: 1200px) 50vw,
           33vw"
    alt="Responsive image example"
>

This provides three image options (400px, 800px, and 1200px wide), and tells the browser that the image will take up:

  • 100% of the viewport width on screens up to 600px wide
  • 50% of the viewport width on screens up to 1200px wide
  • 33% of the viewport width on larger screens

Art Direction with picture Element

The picture element allows you to provide different images for different screen sizes, not just different resolutions:

<picture>
    <source media="(max-width: 600px)" srcset="image-mobile.jpg">
    <source media="(max-width: 1200px)" srcset="image-tablet.jpg">
    <img src="image-desktop.jpg" alt="Art-directed responsive image">
</picture>

This allows you to show completely different images (e.g., a cropped version for mobile) rather than just scaled versions of the same image.

CSS Organization for Maintainable Layouts

The Importance of Well-Organized CSS

As websites grow, CSS can quickly become unwieldy. Well-organized CSS is crucial for maintaining consistent layouts across large websites.

Benefits of Organized CSS

  • Maintainability: Easier to update and bug fix
  • Scalability: Easier to expand as the website grows
  • Collaboration: Easier for multiple developers to work together
  • Performance: Reduces CSS bloat and redundancy
  • Consistency: Promotes a unified look and feel across pages

CSS Organizational Methodologies

Several methodologies have been developed to help organize CSS for large projects.

BEM (Block, Element, Modifier)

BEM is a naming convention that creates a clear, strict relationship between CSS and HTML.

/* BEM Naming Convention */

/* Block: Standalone entity that is meaningful on its own */
.card { }

/* Element: A part of a block that has no standalone meaning */
.card__image { }
.card__title { }
.card__content { }
.card__footer { }

/* Modifier: A flag on a block or element to change appearance or behavior */
.card--featured { }
.card__title--large { }

/* Example usage */
<article class="card card--featured">
    <img class="card-_image" src="image.jpg" alt="Card image">
    <h2 class="card-_title card__title--large">Card Title</h2>
    <div class="card-_content">
        <p>Card content...</p>
    </div>
    <div class="card-_footer">
        <button class="card-_button">Read More</button>
    </div>
</article>

BEM's strength is its clear structure and namespacing, which prevents style conflicts.

SMACSS (Scalable and Modular Architecture for CSS)

SMACSS categorizes CSS rules into distinct types:

  • Base: Default styles for HTML elements (no classes or IDs)
  • Layout: Divides the page into sections
  • Module: Reusable, modular components
  • State: Describes how modules or layouts look in a particular state
  • Theme: Defines colors and images that give the site its look and feel
/* SMACSS Example */

/* Base */
body {
    font-family: 'Open Sans', sans-serif;
    line-height: 1.5;
    color: #333;
}

h1, h2, h3 {
    margin-top: 0;
}

/* Layout */
.l-header,
.l-main,
.l-footer {
    padding: 1rem;
}

.l-container {
    max-width: 1200px;
    margin: 0 auto;
}

.l-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 20px;
}

/* Module */
.btn {
    display: inline-block;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    background-color: #007bff;
    color: white;
    text-decoration: none;
}

.card {
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 1rem;
}

/* State */
.is-active {
    font-weight: bold;
    color: #007bff;
}

.is-hidden {
    display: none;
}

/* Theme */
.t-dark {
    background-color: #222;
    color: #fff;
}

.t-light {
    background-color: #fff;
    color: #222;
}

ITCSS (Inverted Triangle CSS)

ITCSS organizes CSS by specificity, moving from low specificity to high specificity:

Settings Tools Generic Elements Objects Components Utilities Low Specificity High Specificity
  • Settings: Variables and configuration
  • Tools: Mixins and functions (no CSS output)
  • Generic: Reset and normalization styles
  • Elements: Bare HTML elements (h1, a, etc.)
  • Objects: Class-based selectors for structure
  • Components: Specific UI components
  • Utilities: Helper classes with high specificity

ITCSS helps prevent specificity conflicts by organizing code from least to most specific.

Atomic CSS / Utility-First CSS

Atomic CSS uses small, single-purpose classes that each do one thing. Tailwind CSS is a popular implementation of this approach.

/* Atomic/Utility CSS Example */

/* Instead of component-based classes like this: */
.card {
    display: flex;
    flex-direction: column;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 1rem;
    margin-bottom: 1rem;
    background-color: white;
}

/* You use utility classes like this: */
<div class="flex flex-col border border-gray-300 rounded p-4 mb-4 bg-white">
    <!-- Card content -->
</div>

This approach emphasizes reusability and reduces CSS file size but can lead to verbose HTML.

File Organization Strategies

Beyond naming conventions, how you organize your CSS files is crucial for maintainability.

Single CSS File

For small projects, a single CSS file may be sufficient:

styles.css

Pros: Simple to manage, single HTTP request
Cons: Becomes unwieldy as the project grows

Multiple CSS Files by Category

Dividing CSS into logical files:

base.css      /* Reset, typography, general elements */
layout.css    /* Grid systems, page structure */
components.css /* UI components like buttons, cards */
utilities.css  /* Helper classes */

Pros: Easier to find specific styles
Cons: Multiple HTTP requests (mitigated by bundling)

Component-Based Organization

Organizing CSS by component, often used with preprocessors:

scss/
├── main.scss           /* Imports all partials */
├── base/
│   ├── _reset.scss     /* CSS reset or normalize */
│   ├── _typography.scss /* Font styles */
│   └── _variables.scss  /* Variables for colors, etc. */
├── layout/
│   ├── _grid.scss      /* Grid system */
│   ├── _header.scss    /* Header styles */
│   └── _footer.scss    /* Footer styles */
├── components/
│   ├── _buttons.scss   /* Button styles */
│   ├── _cards.scss     /* Card component styles */
│   └── _forms.scss     /* Form element styles */
└── utilities/
    ├── _helpers.scss   /* Helper classes */
    └── _mixins.scss    /* SASS mixins */

Pros: Highly organized, works well with large projects
Cons: Requires a build process, more complex setup

CSS Organization in WordPress Themes

WordPress themes often adopt a hybrid approach to CSS organization:

mytheme/
├── style.css           /* Main theme stylesheet */
├── assets/
│   └── css/
│       ├── editor-style.css  /* Gutenberg editor styles */
│       ├── woocommerce.css   /* WooCommerce styles (if needed) */
│       └── admin.css         /* Admin dashboard styles (if needed) */
└── sass/               /* Source SCSS files */
    ├── style.scss      /* Main SCSS file that imports others */
    ├── _variables.scss
    ├── _mixins.scss
    ├── _base.scss
    ├── _layout.scss
    ├── _navigation.scss
    ├── _typography.scss
    ├── _forms.scss
    ├── _widgets.scss
    ├── _content.scss
    └── _media.scss

This organization allows for modular development while maintaining WordPress standards like the main style.css file.

CSS Best Practices for Consistency

Follow these practices to maintain consistent, maintainable CSS:

  • Use a CSS Reset or Normalize: Start with a clean slate across browsers
  • Define CSS Variables for Theme Elements:
    :root {
        --primary-color: #007bff;
        --secondary-color: #6c757d;
        --success-color: #28a745;
        --font-main: 'Open Sans', sans-serif;
        --spacing-unit: 1rem;
    }
    
    .button {
        background-color: var(--primary-color);
        font-family: var(--font-main);
        padding: var(--spacing-unit);
    }
  • Comment Your CSS: Especially for complex selectors or hacks
  • Avoid Too Much Nesting: Limit selector depth to maintain performance
  • Use Shorthand Properties:
    /* Instead of this */
    .element {
        margin-top: 10px;
        margin-right: 15px;
        margin-bottom: 10px;
        margin-left: 15px;
    }
    
    /* Use this */
    .element {
        margin: 10px 15px;
    }
  • Group Related Properties:
    .element {
        /* Positioning */
        position: absolute;
        top: 0;
        left: 0;
        z-index: 10;
        
        /* Display & Box Model */
        display: flex;
        width: 100%;
        padding: 1rem;
        
        /* Typography */
        font-family: sans-serif;
        font-size: 16px;
        line-height: 1.5;
        
        /* Visual */
        background-color: #fff;
        border: 1px solid #ddd;
        border-radius: 4px;
        
        /* Misc */
        transition: all 0.3s ease;
    }
  • Follow a Style Guide: Establish team standards for indentation, naming, etc.

Building a Complete Layout: Practical Example

WordPress Theme Header and Footer

Let's walk through creating a consistent header and footer layout for a WordPress theme.

header.php

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
    <a class="skip-link screen-reader-text" href="#content">
        <?php esc_html_e('Skip to content', 'mytheme'); ?>
    </a>
    
    <header class="site-header">
        <div class="site-header-_container container">
            <div class="site-branding">
                <?php if (has_custom_logo()) : ?>
                    <div class="site-logo">
                        <?php the_custom_logo(); ?>
                    </div>
                <?php else : ?>
                    <h1 class="site-title">
                        <a href="<?php echo esc_url(home_url('/')); ?>">
                            <?php bloginfo('name'); ?>
                        </a>
                    </h1>
                    
                    <?php $description = get_bloginfo('description', 'display'); ?>
                    <?php if ($description) : ?>
                        <p class="site-description"><?php echo $description; ?></p>
                    <?php endif; ?>
                <?php endif; ?>
            </div>
            
            <nav class="main-navigation" aria-label="<?php esc_attr_e('Main Navigation', 'mytheme'); ?>">
                <button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">
                    <span class="screen-reader-text"><?php esc_html_e('Menu', 'mytheme'); ?></span>
                    <span class="menu-icon"></span>
                </button>
                
                <?php
                wp_nav_menu(array(
                    'theme_location' => 'primary',
                    'menu_id'        => 'primary-menu',
                    'menu_class'     => 'menu-items',
                    'container'      => false,
                ));
                ?>
            </nav>
        </div>
    </header>
    
    <div id="content" class="site-content">

Header and Footer CSS

/* Variables */
:root {
    --color-primary: #007bff;
    --color-secondary: #6c757d;
    --color-text: #333;
    --color-light: #f8f9fa;
    --color-dark: #343a40;
    --font-primary: 'Open Sans', sans-serif;
    --container-width: 1200px;
    --container-padding: 1rem;
    --header-height: 80px;
}

/* Container */
.container {
    width: 100%;
    max-width: var(--container-width);
    margin: 0 auto;
    padding: 0 var(--container-padding);
}

/* Header */
.site-header {
    background-color: white;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    position: relative;
    z-index: 100;
}

.site-header__container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: var(--header-height);
}

.site-branding {
    display: flex;
    align-items: center;
}

.site-logo img {
    max-height: 50px;
    width: auto;
}

.site-title {
    margin: 0;
    font-size: 1.5rem;
}

.site-title a {
    color: var(--color-dark);
    text-decoration: none;
}

.site-description {
    margin: 0;
    font-size: 0.875rem;
    color: var(--color-secondary);
}

/* Main Navigation */
.main-navigation {
    display: flex;
    align-items: center;
}

.menu-toggle {
    display: none;
}

.menu-items {
    display: flex;
    list-style: none;
    margin: 0;
    padding: 0;
}

.menu-items li {
    margin-left: 1.5rem;
}

.menu-items a {
    color: var(--color-dark);
    text-decoration: none;
    font-weight: 500;
    padding: 0.5rem 0;
    transition: color 0.3s ease;
}

.menu-items a:hover {
    color: var(--color-primary);
}

/* Current menu item */
.menu-items .current-menu-item > a {
    color: var(--color-primary);
    border-bottom: 2px solid var(--color-primary);
}

/* Footer */
.site-footer {
    background-color: var(--color-dark);
    color: white;
    padding: 3rem 0 1.5rem;
}

.footer-widgets {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 2rem;
    margin-bottom: 2rem;
}

.footer-widget-area h2 {
    color: white;
    font-size: 1.25rem;
    margin-bottom: 1rem;
}

.footer-widget-area ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-widget-area ul li {
    margin-bottom: 0.5rem;
}

.footer-widget-area a {
    color: #adb5bd;
    text-decoration: none;
    transition: color 0.3s ease;
}

.footer-widget-area a:hover {
    color: white;
}

.site-info {
    text-align: center;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    font-size: 0.875rem;
    color: #adb5bd;
}

/* Responsive */
@media (max-width: 768px) {
    .site-header__container {
        flex-wrap: wrap;
    }
    
    .menu-toggle {
        display: block;
        background: transparent;
        border: none;
        width: 30px;
        height: 30px;
        position: relative;
        cursor: pointer;
    }
    
    .menu-icon,
    .menu-icon::before,
    .menu-icon::after {
        position: absolute;
        width: 30px;
        height: 3px;
        background-color: var(--color-dark);
        border-radius: 1px;
        transition: all 0.3s ease;
    }
    
    .menu-icon {
        top: 50%;
        left: 0;
        transform: translateY(-50%);
    }
    
    .menu-icon::before,
    .menu-icon::after {
        content: '';
        left: 0;
    }
    
    .menu-icon::before {
        top: -8px;
    }
    
    .menu-icon::after {
        bottom: -8px;
    }
    
    /* Menu toggle animation */
    .menu-toggle[aria-expanded="true"] .menu-icon {
        background-color: transparent;
    }
    
    .menu-toggle[aria-expanded="true"] .menu-icon::before {
        top: 0;
        transform: rotate(45deg);
    }
    
    .menu-toggle[aria-expanded="true"] .menu-icon::after {
        bottom: 0;
        transform: rotate(-45deg);
    }
    
    /* Mobile menu */
    .menu-items {
        display: none;
        position: absolute;
        top: var(--header-height);
        left: 0;
        right: 0;
        background-color: white;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        flex-direction: column;
        padding: 1rem 0;
    }
    
    .menu-items.active {
        display: flex;
    }
    
    .menu-items li {
        margin: 0;
        width: 100%;
    }
    
    .menu-items a {
        display: block;
        padding: 0.75rem 1.5rem;
    }
    
    /* Footer on mobile */
    .footer-widgets {
        grid-template-columns: 1fr;
    }
}

JavaScript for Mobile Menu

// File: js/navigation.js
(function() {
    const menuToggle = document.querySelector('.menu-toggle');
    const menu = document.querySelector('.menu-items');
    
    if (!menuToggle || !menu) return;
    
    menuToggle.addEventListener('click', function() {
        const isExpanded = this.getAttribute('aria-expanded') === 'true';
        this.setAttribute('aria-expanded', !isExpanded);
        menu.classList.toggle('active');
    });
    
    // Close menu when clicking outside
    document.addEventListener('click', function(event) {
        const isClickInsideMenu = menu.contains(event.target);
        const isClickOnToggle = menuToggle.contains(event.target);
        
        if (!isClickInsideMenu && !isClickOnToggle && menu.classList.contains('active')) {
            menuToggle.setAttribute('aria-expanded', 'false');
            menu.classList.remove('active');
        }
    });
    
    // Add dropdown functionality for submenus
    const hasChildren = document.querySelectorAll('.menu-item-has-children');
    
    hasChildren.forEach(item => {
        const link = item.querySelector('a');
        const submenu = item.querySelector('.sub-menu');
        
        if (!link || !submenu) return;
        
        // Create dropdown toggle button
        const toggleBtn = document.createElement('button');
        toggleBtn.classList.add('submenu-toggle');
        toggleBtn.setAttribute('aria-expanded', 'false');
        toggleBtn.innerHTML = 'Toggle Submenu';
        
        link.after(toggleBtn);
        
        toggleBtn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            const isExpanded = this.getAttribute('aria-expanded') === 'true';
            this.setAttribute('aria-expanded', !isExpanded);
            submenu.classList.toggle('active');
        });
    });
})();

Enqueuing Styles and Scripts in functions.php

/**
 * Enqueue styles and scripts
 */
function mytheme_scripts() {
    // Enqueue Google Fonts
    wp_enqueue_style(
        'mytheme-fonts',
        'https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;700&display=swap',
        array(),
        null
    );
    
    // Enqueue main stylesheet
    wp_enqueue_style(
        'mytheme-style',
        get_stylesheet_uri(),
        array(),
        wp_get_theme()->get('Version')
    );
    
    // Enqueue navigation JavaScript
    wp_enqueue_script(
        'mytheme-navigation',
        get_template_directory_uri() . '/js/navigation.js',
        array(),
        wp_get_theme()->get('Version'),
        true
    );
    
    // Add keyboard navigation support for screen readers
    if (is_singular() && comments_open() && get_option('thread_comments')) {
        wp_enqueue_script('comment-reply');
    }
}
add_action('wp_enqueue_scripts', 'mytheme_scripts');

/**
 * Register widget areas
 */
function mytheme_widgets_init() {
    register_sidebar(array(
        'name'          => esc_html__('Footer 1', 'mytheme'),
        'id'            => 'footer-1',
        'description'   => esc_html__('Add widgets here to appear in the first footer column.', 'mytheme'),
        'before_widget' => '<section class="widget %2$s" id="%1$s">',
        'after_widget'  => '</section>',
        'before_title'  => '<h2 class="widget-title">',
        'after_title'   => '</h2>',
    ));
    
    register_sidebar(array(
        'name'          => esc_html__('Footer 2', 'mytheme'),
        'id'            => 'footer-2',
        'description'   => esc_html__('Add widgets here to appear in the second footer column.', 'mytheme'),
        'before_widget' => '<section class="widget %2$s" id="%1$s">',
        'after_widget'  => '</section>',
        'before_title'  => '<h2 class="widget-title">',
        'after_title'   => '</h2>',
    ));
    
    register_sidebar(array(
        'name'          => esc_html__('Footer 3', 'mytheme'),
        'id'            => 'footer-3',
        'description'   => esc_html__('Add widgets here to appear in the third footer column.', 'mytheme'),
        'before_widget' => '<section class="widget %2$s" id="%1$s">',
        'after_widget'  => '</section>',
        'before_title'  => '<h2 class="widget-title">',
        'after_title'   => '</h2>',
    ));
}
add_action('widgets_init', 'mytheme_widgets_init');

What's Next?

Now that you understand how to create consistent layouts with HTML and CSS, you're ready to apply these concepts to build sophisticated, responsive WordPress themes. In upcoming sessions, we'll explore:

  • Adding interactivity with JavaScript
  • Working with WordPress template parts
  • Creating custom page templates
  • Building advanced layouts with Flexbox and Grid
  • Optimizing your layouts for performance
  • Advanced responsive design techniques

Homework Assignment

Create a consistent, responsive layout for a WordPress theme home page that includes:

  1. A semantic HTML structure with proper use of header, nav, main, section, article, aside, and footer elements
  2. A responsive header with logo, site title, and navigation menu
  3. A featured content section with a grid of at least three cards
  4. A sidebar with widget areas
  5. A responsive footer with multiple columns that stack on mobile
  6. CSS that follows one of the organizational methodologies discussed (BEM, SMACSS, ITCSS)
  7. Media queries for at least three breakpoints (mobile, tablet, desktop)

Submit your HTML, CSS, and any JavaScript files to the course learning management system.

Additional Resources