mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:11:08 -05:00
- Created a new base HTML template for the ThrillWiki project. - Implemented responsive navigation with mobile support. - Added dark mode functionality using Alpine.js and CSS variables. - Included Open Graph and Twitter meta tags for better SEO. - Integrated HTMX for dynamic content loading and search functionality. - Established a design system with CSS variables for colors, typography, and spacing. - Included accessibility features such as skip to content links and focus styles.
15 KiB
15 KiB
Responsive Layout System
Overview
This document defines the responsive layout system for ThrillWiki's frontend redesign, implementing modern CSS techniques including CSS Grid, Flexbox, and custom properties for a mobile-first, accessible design approach.
Breakpoint Strategy
Mobile-First Approach
/* Base styles (mobile) - 320px+ */
.container {
width: 100%;
padding: var(--spacing-layout-sm);
}
/* Small tablets - 640px+ */
@media (min-width: 640px) {
.container {
padding: var(--spacing-layout-md);
}
}
/* Large tablets - 768px+ */
@media (min-width: 768px) {
.container {
max-width: 768px;
margin: 0 auto;
}
}
/* Desktop - 1024px+ */
@media (min-width: 1024px) {
.container {
max-width: 1024px;
padding: var(--spacing-layout-lg);
}
}
/* Large desktop - 1280px+ */
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
/* Extra large - 1536px+ */
@media (min-width: 1536px) {
.container {
max-width: 1536px;
}
}
Breakpoint Variables
:root {
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px;
}
Grid Systems
CSS Grid Layout Patterns
Main Application Grid
.app-grid {
display: grid;
min-height: 100vh;
grid-template-areas:
"header"
"nav"
"main"
"footer";
grid-template-rows: auto auto 1fr auto;
}
@media (min-width: 768px) {
.app-grid {
grid-template-areas:
"header header"
"nav main"
"nav main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
}
}
@media (min-width: 1024px) {
.app-grid {
grid-template-columns: 280px 1fr;
}
}
.app-header { grid-area: header; }
.app-nav { grid-area: nav; }
.app-main { grid-area: main; }
.app-footer { grid-area: footer; }
Content Grid Patterns
/* Two-column content layout */
.content-grid-2 {
display: grid;
gap: var(--spacing-layout-md);
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.content-grid-2 {
grid-template-columns: 2fr 1fr;
}
}
/* Three-column layout */
.content-grid-3 {
display: grid;
gap: var(--spacing-layout-md);
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.content-grid-3 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.content-grid-3 {
grid-template-columns: repeat(3, 1fr);
}
}
/* Auto-fit grid for cards */
.auto-grid {
display: grid;
gap: var(--spacing-layout-md);
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
/* Dense grid for smaller items */
.dense-grid {
display: grid;
gap: var(--spacing-layout-sm);
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-flow: dense;
}
Flexbox Patterns
Navigation Layouts
/* Horizontal navigation */
.nav-horizontal {
display: flex;
align-items: center;
gap: var(--spacing-component-md);
flex-wrap: wrap;
}
/* Vertical navigation */
.nav-vertical {
display: flex;
flex-direction: column;
gap: var(--spacing-component-sm);
}
/* Responsive navigation */
.nav-responsive {
display: flex;
flex-direction: column;
gap: var(--spacing-component-sm);
}
@media (min-width: 768px) {
.nav-responsive {
flex-direction: row;
align-items: center;
gap: var(--spacing-component-md);
}
}
Content Layouts
/* Flexible content container */
.flex-container {
display: flex;
flex-direction: column;
gap: var(--spacing-layout-md);
}
@media (min-width: 768px) {
.flex-container {
flex-direction: row;
align-items: flex-start;
}
}
/* Center content */
.flex-center {
display: flex;
align-items: center;
justify-content: center;
min-height: 50vh;
}
/* Space between items */
.flex-between {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: var(--spacing-component-md);
}
/* Flexible sidebar layout */
.flex-sidebar {
display: flex;
flex-direction: column;
gap: var(--spacing-layout-md);
}
@media (min-width: 768px) {
.flex-sidebar {
flex-direction: row;
}
.flex-sidebar-main {
flex: 1;
}
.flex-sidebar-aside {
flex: 0 0 300px;
}
}
Container Queries (Future Enhancement)
Container Query Setup
/* Container query context */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Responsive card based on container size */
@container card (min-width: 300px) {
.card {
display: flex;
flex-direction: row;
}
.card-image {
flex: 0 0 40%;
}
.card-content {
flex: 1;
padding: var(--spacing-component-lg);
}
}
@container card (min-width: 500px) {
.card-content {
padding: var(--spacing-component-xl);
}
.card-title {
font-size: var(--text-xl);
}
}
Responsive Typography
Fluid Typography Scale
:root {
/* Fluid typography using clamp() */
--text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
--text-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
--text-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
--text-lg: clamp(1.125rem, 1rem + 0.625vw, 1.25rem);
--text-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem);
--text-2xl: clamp(1.5rem, 1.3rem + 1vw, 1.875rem);
--text-3xl: clamp(1.875rem, 1.6rem + 1.375vw, 2.25rem);
--text-4xl: clamp(2.25rem, 1.9rem + 1.75vw, 3rem);
--text-5xl: clamp(3rem, 2.5rem + 2.5vw, 4rem);
}
/* Responsive line heights */
.text-responsive {
line-height: 1.6;
}
@media (min-width: 768px) {
.text-responsive {
line-height: 1.5;
}
}
Reading Width Optimization
.text-content {
max-width: 65ch; /* Optimal reading width */
margin: 0 auto;
}
.text-content-wide {
max-width: 80ch;
margin: 0 auto;
}
Responsive Images
Responsive Image Patterns
/* Responsive image base */
.img-responsive {
max-width: 100%;
height: auto;
display: block;
}
/* Aspect ratio containers */
.aspect-square {
aspect-ratio: 1 / 1;
overflow: hidden;
}
.aspect-video {
aspect-ratio: 16 / 9;
overflow: hidden;
}
.aspect-photo {
aspect-ratio: 4 / 3;
overflow: hidden;
}
/* Object fit for images within aspect ratio containers */
.aspect-square img,
.aspect-video img,
.aspect-photo img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
Picture Element Patterns
<!-- Responsive images with art direction -->
<picture>
<source media="(min-width: 1024px)" srcset="hero-desktop.jpg">
<source media="(min-width: 768px)" srcset="hero-tablet.jpg">
<img src="hero-mobile.jpg" alt="Hero image" class="img-responsive">
</picture>
<!-- Responsive images with density -->
<img src="image.jpg"
srcset="image.jpg 1x, image@2x.jpg 2x, image@3x.jpg 3x"
alt="Responsive image"
class="img-responsive">
Layout Components
Page Layout Templates
Standard Page Layout
.page-layout {
display: grid;
gap: var(--spacing-layout-lg);
grid-template-areas:
"breadcrumb"
"header"
"content"
"sidebar";
grid-template-rows: auto auto 1fr auto;
}
@media (min-width: 1024px) {
.page-layout {
grid-template-areas:
"breadcrumb breadcrumb"
"header sidebar"
"content sidebar";
grid-template-columns: 1fr 300px;
grid-template-rows: auto auto 1fr;
}
}
.page-breadcrumb { grid-area: breadcrumb; }
.page-header { grid-area: header; }
.page-content { grid-area: content; }
.page-sidebar { grid-area: sidebar; }
Dashboard Layout
.dashboard-layout {
display: grid;
gap: var(--spacing-layout-md);
grid-template-areas:
"stats"
"charts"
"tables";
}
@media (min-width: 768px) {
.dashboard-layout {
grid-template-areas:
"stats stats"
"charts tables";
grid-template-columns: 2fr 1fr;
}
}
@media (min-width: 1024px) {
.dashboard-layout {
grid-template-areas:
"stats stats stats"
"charts charts tables";
grid-template-columns: 1fr 1fr 300px;
}
}
Card Layouts
Responsive Card Grid
.card-grid {
display: grid;
gap: var(--spacing-layout-md);
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (min-width: 1280px) {
.card-grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* Masonry-style layout */
.card-masonry {
columns: 1;
column-gap: var(--spacing-layout-md);
}
@media (min-width: 640px) {
.card-masonry {
columns: 2;
}
}
@media (min-width: 1024px) {
.card-masonry {
columns: 3;
}
}
@media (min-width: 1280px) {
.card-masonry {
columns: 4;
}
}
.card-masonry .card {
break-inside: avoid;
margin-bottom: var(--spacing-layout-md);
}
Form Layouts
Responsive Form Patterns
.form-layout {
display: grid;
gap: var(--spacing-component-lg);
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.form-layout {
grid-template-columns: repeat(2, 1fr);
}
.form-field-full {
grid-column: 1 / -1;
}
}
/* Inline form elements */
.form-inline {
display: flex;
flex-direction: column;
gap: var(--spacing-component-md);
}
@media (min-width: 640px) {
.form-inline {
flex-direction: row;
align-items: flex-end;
}
}
/* Form with sidebar */
.form-with-sidebar {
display: grid;
gap: var(--spacing-layout-lg);
grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
.form-with-sidebar {
grid-template-columns: 2fr 1fr;
}
}
Navigation Layouts
Responsive Navigation Patterns
/* Mobile-first navigation */
.nav-mobile {
position: fixed;
top: 0;
left: -100%;
width: 280px;
height: 100vh;
background: var(--bg-elevated);
transition: left var(--transition-base);
z-index: 1000;
}
.nav-mobile.is-open {
left: 0;
}
@media (min-width: 768px) {
.nav-mobile {
position: static;
left: 0;
width: auto;
height: auto;
background: transparent;
}
}
/* Breadcrumb navigation */
.breadcrumb {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--spacing-component-xs);
font-size: var(--text-sm);
}
.breadcrumb-item:not(:last-child)::after {
content: '/';
margin-left: var(--spacing-component-xs);
color: var(--text-secondary);
}
/* Tab navigation */
.tab-nav {
display: flex;
border-bottom: 1px solid var(--border-primary);
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tab-nav::-webkit-scrollbar {
display: none;
}
.tab-nav-item {
flex-shrink: 0;
padding: var(--spacing-component-md) var(--spacing-component-lg);
border-bottom: 2px solid transparent;
transition: all var(--transition-base);
}
.tab-nav-item.is-active {
border-bottom-color: var(--interactive-primary);
color: var(--interactive-primary);
}
Utility Classes
Responsive Display Utilities
/* Hide/show at different breakpoints */
.hidden { display: none !important; }
.block { display: block !important; }
.inline-block { display: inline-block !important; }
.flex { display: flex !important; }
.inline-flex { display: inline-flex !important; }
.grid { display: grid !important; }
@media (min-width: 640px) {
.sm\:hidden { display: none !important; }
.sm\:block { display: block !important; }
.sm\:flex { display: flex !important; }
.sm\:grid { display: grid !important; }
}
@media (min-width: 768px) {
.md\:hidden { display: none !important; }
.md\:block { display: block !important; }
.md\:flex { display: flex !important; }
.md\:grid { display: grid !important; }
}
@media (min-width: 1024px) {
.lg\:hidden { display: none !important; }
.lg\:block { display: block !important; }
.lg\:flex { display: flex !important; }
.lg\:grid { display: grid !important; }
}
Responsive Spacing Utilities
/* Responsive padding */
.p-responsive {
padding: var(--spacing-layout-sm);
}
@media (min-width: 768px) {
.p-responsive {
padding: var(--spacing-layout-md);
}
}
@media (min-width: 1024px) {
.p-responsive {
padding: var(--spacing-layout-lg);
}
}
/* Responsive margins */
.m-responsive {
margin: var(--spacing-layout-sm);
}
@media (min-width: 768px) {
.m-responsive {
margin: var(--spacing-layout-md);
}
}
@media (min-width: 1024px) {
.m-responsive {
margin: var(--spacing-layout-lg);
}
}
Performance Considerations
CSS Optimization
/* Use transform for animations instead of changing layout properties */
.slide-in {
transform: translateX(-100%);
transition: transform var(--transition-base);
}
.slide-in.is-visible {
transform: translateX(0);
}
/* Use will-change for elements that will be animated */
.will-animate {
will-change: transform, opacity;
}
/* Remove will-change after animation */
.animation-complete {
will-change: auto;
}
Loading Strategies
/* Skeleton loading for responsive content */
.skeleton-responsive {
background: linear-gradient(90deg,
var(--color-neutral-200) 25%,
var(--color-neutral-100) 50%,
var(--color-neutral-200) 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
border-radius: var(--radius-md);
}
.skeleton-text {
height: 1em;
margin-bottom: 0.5em;
}
.skeleton-text:last-child {
width: 60%;
margin-bottom: 0;
}
@keyframes skeleton-loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
Accessibility Considerations
Focus Management
/* Ensure focus indicators are visible at all screen sizes */
.focus-visible {
outline: 2px solid var(--border-focus);
outline-offset: 2px;
}
/* Skip links for keyboard navigation */
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: var(--bg-elevated);
color: var(--text-primary);
padding: 8px;
text-decoration: none;
border-radius: var(--radius-md);
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Reduced Motion Support
/* Respect user's motion preferences */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Testing Strategy
Responsive Testing Checklist
- Breakpoint Testing: Test all major breakpoints (320px, 640px, 768px, 1024px, 1280px, 1536px)
- Content Overflow: Ensure content doesn't break at any screen size
- Touch Targets: Minimum 44px touch targets on mobile devices
- Readability: Text remains readable at all screen sizes
- Navigation: Navigation remains accessible across all devices
- Performance: Layout shifts and reflows are minimized
- Accessibility: Focus management works across all screen sizes
Browser Support
- Modern Browsers: Full CSS Grid and Flexbox support
- Fallbacks: Flexbox fallbacks for older browsers
- Progressive Enhancement: Basic layout works without CSS Grid
- Container Queries: Progressive enhancement for supported browsers
This responsive layout system provides a solid foundation for creating flexible, accessible, and performant layouts across all device sizes while maintaining consistency with the established design system.