Creating a Consistent Layout with HTML and CSS
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
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
Best for: Mobile views, focused content, landing pages
Two Column Layout (Sidebar)
Best for: Blog layouts, content with related information
Three Column Layout
Best for: Complex websites with multiple navigation options
Holy Grail Layout
Best for: Complex applications, dashboards, content-rich websites
Responsive Design Considerations
Layouts need to adapt to different screen sizes while maintaining consistency:
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
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
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: 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:
- A semantic HTML structure with proper use of header, nav, main, section, article, aside, and footer elements
- A responsive header with logo, site title, and navigation menu
- A featured content section with a grid of at least three cards
- A sidebar with widget areas
- A responsive footer with multiple columns that stack on mobile
- CSS that follows one of the organizational methodologies discussed (BEM, SMACSS, ITCSS)
- Media queries for at least three breakpoints (mobile, tablet, desktop)
Submit your HTML, CSS, and any JavaScript files to the course learning management system.