Chapter 4: Layout - Flexbox & Grid

Master modern CSS layout techniques to build responsive, flexible web designs. Learn how elements are positioned and how to create complex layouts with ease.

What you'll learn:
  • The display property and how elements flow
  • CSS positioning: static, relative, absolute, fixed, sticky
  • Flexbox for one-dimensional layouts
  • CSS Grid for two-dimensional layouts
  • Responsive design with media queries
  • CSS transitions and transforms for animations
  • CSS custom properties (variables)

4.1 The Display Property

The display property is fundamental to CSS layout. It controls how an element generates boxes and how it interacts with other elements.

Display Values

/* Block elements - stack vertically, take full width */
div, p, h1, section, article, form {
  display: block;
}

/* Inline elements - flow with text, only take needed width */
span, a, strong, em, img {
  display: inline;
}

/* Inline-block - inline flow but accepts width/height */
.badge {
  display: inline-block;
  width: 100px;
  height: 50px;
}

/* None - hides element completely */
.hidden {
  display: none;
}

/* Flex and Grid - modern layout systems */
.flex-container { display: flex; }
.grid-container { display: grid; }

Block vs Inline Summary

Property Block Inline
Width Full available Content only
Height Can be set Cannot be set
Margin (top/bottom) Yes No
New line Yes No
Examples div, p, h1 span, a, strong

4.2 Position Property

The position property controls how elements are placed in the document flow.

Position Values

/* Static (default) - normal document flow */
.static {
  position: static;
  /* top, right, bottom, left have NO effect */
}

/* Relative - offset from normal position */
.relative {
  position: relative;
  top: 20px;  /* moves DOWN 20px from where it was */
  left: 10px; /* moves RIGHT 10px from where it was */
  /* Original space is preserved */
}

/* Absolute - removed from flow, positioned relative to ancestor */
.absolute {
  position: absolute;
  top: 0;
  right: 0;
  /* Positioned relative to nearest positioned ancestor */
  /* If none, relative to <html> */
}

/* Fixed - removed from flow, positioned relative to viewport */
.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  /* Stays in place when scrolling */
}

/* Sticky - hybrid of relative and fixed */
.sticky-nav {
  position: sticky;
  top: 0;
  /* Normal flow until scroll reaches 'top: 0', then fixed */
}

Z-Index: Controlling Stack Order

/* Higher z-index = on top (only works on positioned elements) */
.modal {
  position: fixed;
  z-index: 1000; /* On top of most things */
}

.dropdown {
  position: absolute;
  z-index: 100;
}

.behind {
  position: relative;
  z-index: -1; /* Behind normal elements */
}
Common Pattern: To position a child element absolutely within a parent, give the parent position: relative (creates a positioning context).

4.3 Float Property (Legacy but Useful)

Float was originally designed for text wrapping around images, but was used for layouts before Flexbox/Grid. Still useful for specific cases.

Float Property

/* Float an image to the left, text wraps around */
.float-left {
  float: left;
  margin-right: 20px;
  margin-bottom: 10px;
}

.float-right {
  float: right;
  margin-left: 20px;
}

/* Clear floats - stop wrapping */
.clear {
  clear: both; /* left, right, or both */
}

/* Clearfix - contain floated children (old technique) */
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}
Modern Alternative: For page layouts, use Flexbox or CSS Grid instead of floats. Floats are still useful for wrapping text around images, but shouldn't be used for overall page structure.

4.4 Flexbox Layout

Flexbox is a one-dimensional layout system for arranging items in rows or columns. It's perfect for navigation, cards, and component layouts.

Flex Container Properties

.flex-container {
  display: flex; /* or inline-flex */

  /* Direction of items */
  flex-direction: row;        /* left to right (default) */
  flex-direction: row-reverse; /* right to left */
  flex-direction: column;     /* top to bottom */
  flex-direction: column-reverse;

  /* Wrapping behavior */
  flex-wrap: nowrap;  /* single line (default) */
  flex-wrap: wrap;    /* wrap to multiple lines */

  /* Main axis alignment (horizontal in row) */
  justify-content: flex-start;   /* items at start */
  justify-content: flex-end;     /* items at end */
  justify-content: center;       /* items centered */
  justify-content: space-between; /* first/last at edges */
  justify-content: space-around;  /* equal space around */
  justify-content: space-evenly;  /* perfectly equal */

  /* Cross axis alignment (vertical in row) */
  align-items: stretch;    /* fill height (default) */
  align-items: flex-start; /* top */
  align-items: flex-end;   /* bottom */
  align-items: center;     /* middle */
  align-items: baseline;   /* text baselines align */

  /* Gap between items */
  gap: 20px;           /* all gaps */
  row-gap: 10px;       /* between rows */
  column-gap: 20px;    /* between columns */
}

Flex Item Properties

.flex-item {
  /* Grow to fill available space */
  flex-grow: 1; /* 0 = don't grow (default) */

  /* Shrink when space is tight */
  flex-shrink: 1; /* 0 = don't shrink */

  /* Initial size before growing/shrinking */
  flex-basis: 200px; /* or auto, 25%, etc. */

  /* Shorthand: grow shrink basis */
  flex: 1;         /* flex: 1 1 0 */
  flex: 0 0 auto;  /* don't grow, don't shrink */
  flex: 1 1 200px; /* grow/shrink from 200px */

  /* Individual alignment (override align-items) */
  align-self: flex-end;

  /* Order (default 0, lower = earlier) */
  order: -1; /* move to front */
}

Common Flexbox Patterns

/* Centering (horizontal and vertical) */
.center-everything {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Navigation bar */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
}

/* Card layout that wraps */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.card {
  flex: 1 1 300px; /* min 300px, grows/shrinks */
}

/* Sticky footer layout */
.page-layout {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.main-content {
  flex: 1; /* grow to push footer down */
}
When to use Flexbox: When you need to arrange items in a single row or column. Think navigation bars, button groups, card rows, centering content, or any one-dimensional layout.

4.5 CSS Grid Layout

CSS Grid is a two-dimensional layout system. It's ideal for page layouts, galleries, and complex designs.

Grid Container Properties

.grid-container {
  display: grid;

  /* Define columns */
  grid-template-columns: 200px 200px 200px; /* 3 fixed columns */
  grid-template-columns: 1fr 1fr 1fr;       /* 3 equal columns */
  grid-template-columns: repeat(3, 1fr);   /* same as above */
  grid-template-columns: 1fr 2fr 1fr;       /* middle is 2x wider */
  grid-template-columns: 200px 1fr;         /* sidebar + flexible */

  /* Auto-fit/auto-fill for responsive grids */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

  /* Define rows */
  grid-template-rows: 100px auto 50px; /* header, main, footer */
  grid-auto-rows: minmax(100px, auto); /* min 100px, expand as needed */

  /* Gaps */
  gap: 20px;
  row-gap: 10px;
  column-gap: 20px;

  /* Alignment */
  justify-items: center;  /* horizontal align of items */
  align-items: center;    /* vertical align of items */
  justify-content: center; /* horizontal align of grid */
  align-content: center;  /* vertical align of grid */
}

Grid Item Properties

.grid-item {
  /* Span multiple columns/rows */
  grid-column: span 2;      /* spans 2 columns */
  grid-row: span 3;         /* spans 3 rows */

  /* Specific placement (line numbers) */
  grid-column: 1 / 3;       /* start at line 1, end at line 3 */
  grid-row: 2 / 4;          /* start at line 2, end at line 4 */

  /* Shorthand: row-start / column-start / row-end / column-end */
  grid-area: 1 / 1 / 3 / 3; /* 2x2 from top-left */

  /* Individual alignment */
  justify-self: end;        /* horizontal */
  align-self: center;       /* vertical */
}

Named Grid Areas

.page-layout {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "sidebar content content"
    "footer  footer  footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }
When to use Grid: When you need both rows AND columns (two-dimensional). Think page layouts, image galleries, dashboards, or any layout where items need to align both horizontally and vertically.

4.6 Responsive Design

Responsive design makes your website work on all screen sizes. Media queries are the key tool.

Media Queries

/* Mobile First Approach (recommended) */
/* Base styles for mobile */
.container {
  padding: 10px;
}

/* Tablet and up */
@media (min-width: 768px) {
  .container {
    padding: 20px;
  }
}

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

/* Common breakpoints */
/* Mobile: 0 - 767px */
/* Tablet: 768px - 1023px */
/* Desktop: 1024px+ */

Responsive Layout Example

/* Mobile: single column */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

/* Tablet: 2 columns */
@media (min-width: 768px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Desktop: 3 columns */
@media (min-width: 1024px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Or use auto-fit for automatic responsiveness */
.auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

Responsive Best Practices

  • Viewport meta tag: Required for responsive design <meta name="viewport" content="width=device-width, initial-scale=1">
  • Use relative units: %, em, rem, vw, vh instead of px
  • Flexible images: max-width: 100%; height: auto;
  • Mobile-first: Start with mobile styles, add complexity for larger screens
  • Test on real devices: Browser dev tools help, but real device testing is important
Pro Tip: Use min-width for mobile-first (progressively add styles). Use max-width for desktop-first (progressively remove styles). Mobile-first is generally recommended.

4.7 CSS Transitions and Transforms

Add smooth animations and visual effects to your elements.

CSS Transitions

.button {
  background: #3b82f6;
  color: white;
  padding: 10px 20px;

  /* Transition syntax: property duration timing-function delay */
  transition: all 0.3s ease;
  /* Or be specific: */
  transition: background-color 0.3s, transform 0.2s;
}

.button:hover {
  background: #2563eb;
  transform: translateY(-2px);
}

/* Timing functions */
transition-timing-function: ease;      /* default */
transition-timing-function: linear;    /* constant speed */
transition-timing-function: ease-in;   /* slow start */
transition-timing-function: ease-out;  /* slow end */
transition-timing-function: ease-in-out;

CSS Transforms

.element {
  /* Move element */
  transform: translateX(50px);  /* move right */
  transform: translateY(-20px); /* move up */
  transform: translate(50px, -20px); /* both */

  /* Scale (resize) */
  transform: scale(1.5);   /* 150% size */
  transform: scale(0.5);   /* 50% size */
  transform: scaleX(2);    /* stretch horizontally */

  /* Rotate */
  transform: rotate(45deg);  /* clockwise */
  transform: rotate(-90deg); /* counter-clockwise */

  /* Skew (slant) */
  transform: skew(10deg);

  /* Combine multiple transforms */
  transform: translateY(-5px) scale(1.1) rotate(5deg);

  /* Transform origin (default: center) */
  transform-origin: top left;
}
Performance Tip: Use transform and opacity for animations - they're GPU-accelerated and perform better than animating width, height, or margin.

4.8 CSS Variables (Custom Properties)

CSS Variables allow you to store values for reuse throughout your stylesheet.

CSS Variables

/* Define variables (usually in :root for global scope) */
:root {
  --primary-color: #3b82f6;
  --secondary-color: #8b5cf6;
  --text-color: #333333;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --border-radius: 8px;
  --font-main: 'Segoe UI', sans-serif;
}

/* Use variables with var() */
.button {
  background: var(--primary-color);
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--border-radius);
  font-family: var(--font-main);
}

/* Fallback value if variable is undefined */
color: var(--text-color, black);

/* Override variables in specific contexts */
.dark-theme {
  --text-color: #ffffff;
  --bg-color: #1a1a1a;
}
Benefits of CSS Variables:
  • Single source of truth for colors, spacing, etc.
  • Easy to maintain and update across your entire site
  • Perfect for theming (light/dark mode)
  • Can be changed dynamically with JavaScript

Exercise: Create a Navigation Bar

EXERCISE

Flexbox Navigation

Use Flexbox to create a horizontal navigation bar with:

  • Items evenly spaced
  • Vertically centered
  • A gap of 20px between items