Lecture 4

March 12, 2025

CSS selectors, units, block, box model, flexbox

I’ll build out a comprehensive lecture on these CSS topics for your girlfriend’s tech course. Let me expand each concept with clear, in-depth explanations while keeping it accessible for someone new to tech but intellectually curious.

CSS Selectors: Targeting HTML Elements

CSS selectors are the bridge between your HTML document and your styling rules. They allow you to precisely target specific elements or groups of elements for styling.

Basic Selectors

Element Selector

The most straightforward selector targets all instances of a specific HTML element:

p {
  color: blue;
  /* This targets ALL paragraph elements */
}

Class Selector

Classes are reusable styles that can be applied to any element. They’re prefixed with a dot:

.important-text {
  font-weight: bold;
  /* This targets any element with class="important-text" */
}

ID Selector

IDs are unique identifiers that should only appear once per page. They’re prefixed with a hash symbol:

#site-header {
  background-color: navy;
  /* This targets the single element with id="site-header" */
}

Combinatorial Selectors

Descendant Selector

Targets elements that are nested inside another element (at any level):

article p {
  line-height: 1.6;
  /* Targets paragraphs inside article elements */
}

Child Selector

Targets direct children only (not deeper descendants):

nav > ul {
  list-style-type: none;
  /* Targets ul elements that are direct children of nav */
}

Adjacent Sibling Selector

Targets elements that come immediately after another element with the same parent:

h2 + p {
  font-size: 1.2em;
  /* Targets paragraphs that come right after h2 headings */
}

Attribute Selectors

Target elements based on their attributes or attribute values:

input[type="text"] {
  border: 1px solid gray;
  /* Targets input elements with type="text" */
}

a[href^="https"] {
  color: green;
  /* Targets links that begin with "https" */
}

Pseudo-classes and Pseudo-elements

Pseudo-classes

Target elements based on states or positions:

a:hover {
  text-decoration: underline;
  /* Applies when the user hovers over links */
}

li:first-child {
  font-weight: bold;
  /* Targets the first li element in its parent */
}

input:focus {
  border-color: blue;
  /* Applies when an input has focus */
}

Pseudo-elements

Target specific parts of elements:

p::first-line {
  font-variant: small-caps;
  /* Targets the first line of paragraphs */
}

h1::before {
  content: "→ ";
  /* Inserts content before h1 elements */
}

Selector Specificity

CSS resolves conflicts between overlapping selectors using specificity, calculated as:

  • IDs: 100 points each
  • Classes, attributes, pseudo-classes: 10 points each
  • Elements, pseudo-elements: 1 point each
/* Specificity: 1 (element) */
p { color: red; }

/* Specificity: 10 (class) */
.text { color: blue; }

/* Specificity: 101 (ID + element) */
#content p { color: green; }

In this example, the text would be green if all three rules applied to the same element.

Reference Documentation:

CSS Units: Measuring Size and Space

CSS offers various units for specifying dimensions, providing flexibility for different contexts.

Absolute Units

Fixed physical measurements that remain consistent regardless of screen size:

  • px (pixels): The most common absolute unit, representing screen pixels
  • pt (points): 1/72 of an inch, traditionally used in print
  • in (inches), cm (centimeters), mm (millimeters): Physical measurements

Example:

h1 {
  font-size: 24px;
  margin-bottom: 12px;
}

Relative Units

Scale according to other factors, making them ideal for responsive design:

Font-relative Units

  • em: Relative to the element’s font size (1em = current font size)
  • rem: Relative to the root element’s font size (usually the html element)
  • ch: Width of the “0” character in the current font
  • ex: Height of the lowercase “x” in the current font

Example:

body {
  font-size: 16px; /* Base font size */
}

h1 {
  font-size: 2em; /* 2 × 16px = 32px */
}

p {
  font-size: 1rem; /* 1 × root font size */
  line-height: 1.5; /* 1.5 × the element's font size */
  margin-bottom: 1.5em; /* 1.5 × the element's font size */
}

Viewport-relative Units

Scale according to the browser viewport dimensions:

  • vw (viewport width): 1% of viewport width
  • vh (viewport height): 1% of viewport height
  • vmin: 1% of the smaller dimension (width or height)
  • vmax: 1% of the larger dimension (width or height)

Example:

.hero {
  height: 80vh; /* 80% of viewport height */
  padding: 5vw; /* Padding scales with viewport width */
}

h1 {
  font-size: 5vmin; /* Scales based on smaller viewport dimension */
}

Percentage (%)

Relative to the parent element’s corresponding dimension:

.container {
  width: 80%; /* 80% of parent width */
}

.column {
  width: 50%; /* 50% of parent width */
  margin-top: 5%; /* 5% of parent width (not height!) */
}

Choosing the Right Units

  • Use relative units (rem, em, %) for most spacing, sizing, and typography to support responsive design
  • Use viewport units (vw, vh) for elements that should scale with the screen size
  • Use pixels (px) for:
    • Borders
    • Small, precise details
    • When you need exact measurements that shouldn’t scale

Best Practices

Set a base font size on the html element, then use relative units everywhere else:

html {
  font-size: 16px; /* Base font size */
}

body {
  font-size: 1rem; /* Same as base */
  line-height: 1.5;
}

h1 {
  font-size: 2.5rem; /* 2.5 × base font size */
  margin-bottom: 1rem;
}

This approach makes your design more accessible since it scales properly when users change their browser font size settings.

Reference Documentation:

Block vs. Inline Elements: Understanding Display Properties

Every HTML element has a default display behavior that affects how it flows in the document and interacts with surrounding elements.

Block-Level Elements

Block elements:

  • Start on a new line
  • Take up the full width available
  • Create a “block” in the document flow
  • Can have their width and height explicitly set
  • Automatically add line breaks before and after

Common block elements include:

  • <div>
  • <p> (paragraphs)
  • <h1> through <h6> (headings)
  • <ul> and <ol> (lists)
  • <section>, <article>, <nav> (semantic blocks)
div {
  display: block; /* Default for div */
  width: 80%;
  height: 200px;
  margin-bottom: 20px;
}

Inline Elements

Inline elements:

  • Flow within text, like words in a sentence
  • Only take up as much width as necessary
  • Do not force new lines
  • Cannot have width and height explicitly set
  • Ignore top and bottom margins

Common inline elements:

  • <span>
  • <a> (links)
  • <strong> and <em> (text emphasis)
  • <img> (technically inline-block by default)
  • <button> (technically inline-block by default)
span {
  display: inline; /* Default for span */
  padding: 5px; /* Horizontal padding works */
  /* width and height would be ignored */
  /* top and bottom margins would be ignored */
}

Inline-Block Elements

Inline-block combines features of both:

  • Flows within text (no line breaks)
  • Can have explicit width and height
  • Respects all margin and padding
  • Doesn’t force line breaks
.button {
  display: inline-block;
  width: 100px;
  height: 40px;
  margin: 10px; /* All margins work */
  padding: 10px;
  text-align: center;
}

Changing Display Behavior

You can override the default display behavior of any element:

/* Make a paragraph behave like an inline element */
p.inline {
  display: inline;
}

/* Make a span behave like a block element */
span.block {
  display: block;
  width: 100px;
  height: 100px;
}

/* Make list items display side by side */
li.menu-item {
  display: inline-block;
  margin-right: 20px;
}

Other Common Display Values

  • none: Removes the element completely from the document flow
  • flex: Creates a flex container (discussed later)
  • grid: Creates a grid container
  • table, table-row, table-cell: Creates CSS table layouts

Reference Documentation:

The Box Model: Understanding Element Dimensions

The CSS box model is fundamental to understanding how elements are sized and spaced in a webpage.

Box Model Components

Every element on a page is represented as a rectangular box with four main components:

  1. Content: The actual content of the box, where text and images appear
  2. Padding: Clear space between the content and the border
  3. Border: A line that surrounds the padding (if any) and content
  4. Margin: Clear space outside the border, separating the element from others

![Box Model Diagram]

How Dimensions Are Calculated

By default (in the standard box model):

  • width and height properties only control the content area
  • The actual space an element takes up is:
    • Total width = width + padding-left + padding-right + border-left + border-right
    • Total height = height + padding-top + padding-bottom + border-top + border-bottom
.box {
  width: 300px;
  height: 200px;
  padding: 20px;
  border: 10px solid black;
  margin: 30px;
}

In this example:

  • Content width: 300px
  • Content height: 200px
  • Total element width: 300px + 20px + 20px + 10px + 10px = 360px
  • Total element height: 200px + 20px + 20px + 10px + 10px = 260px
  • Total space occupied: 360px × 260px plus 30px margin on all sides

Box-Sizing Property

The box-sizing property changes how the browser calculates dimensions:

.box {
  box-sizing: content-box; /* Default - width/height apply to content only */
  width: 300px;
  padding: 20px;
  border: 10px solid black;
  /* Total width: 300 + 40 + 20 = 360px */
}

.better-box {
  box-sizing: border-box; /* Width/height include padding and border */
  width: 300px;
  padding: 20px;
  border: 10px solid black;
  /* Total width: exactly 300px */
}

Most developers prefer border-box because it makes layout calculations simpler. A common practice is to apply it globally:

* {
  box-sizing: border-box;
}

Controlling Individual Sides

You can control each side of padding, border, and margin independently:

.box {
  /* Clock-wise: top, right, bottom, left */
  margin: 10px 20px 15px 25px;
  
  /* Alternative individual properties */
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 15px;
  padding-left: 25px;
  
  /* Border can control style, width, and color */
  border-top: 1px solid black;
  border-right: 2px dashed red;
  border-bottom: 3px dotted blue;
  border-left: 4px double green;
}

Collapsing Margins

An important quirk: adjacent vertical margins “collapse” into a single margin:

.paragraph1 {
  margin-bottom: 20px;
}

.paragraph2 {
  margin-top: 30px;
}

The space between these paragraphs would be 30px (the larger of the two), not 50px.

Reference Documentation:

Flexbox: Modern Layout System

Flexbox (Flexible Box Layout) is a powerful one-dimensional layout system that makes it much easier to design flexible, responsive layouts without using floats or positioning.

Core Concepts

Flexbox works with a parent-child relationship:

  • The flex container is the parent element
  • The flex items are the direct children
.container {
  display: flex; /* Makes this element a flex container */
}

Flex Container Properties

flex-direction

Controls the primary axis direction:

.container {
  display: flex;
  flex-direction: row; /* Default - items flow horizontally */
  /* Other values: column, row-reverse, column-reverse */
}

flex-wrap

Controls whether items can wrap to new lines:

.container {
  display: flex;
  flex-wrap: nowrap; /* Default - items stay on a single line */
  /* Other values: wrap, wrap-reverse */
}

justify-content

Controls alignment along the main axis:

.container {
  display: flex;
  justify-content: flex-start; /* Default - items at the start */
  /* Other values: flex-end, center, space-between, space-around, space-evenly */
}

align-items

Controls alignment along the cross axis:

.container {
  display: flex;
  align-items: stretch; /* Default - items stretch to fill container */
  /* Other values: flex-start, flex-end, center, baseline */
}

align-content

Controls spacing between lines when flex-wrap is enabled:

.container {
  display: flex;
  flex-wrap: wrap;
  align-content: stretch; /* Default */
  /* Other values: flex-start, flex-end, center, space-between, space-around */
}

Flex Item Properties

flex-grow

Controls how much an item can grow relative to others:

.item {
  flex-grow: 0; /* Default - item doesn't grow */
}

.growing-item {
  flex-grow: 1; /* Item will grow to fill available space */
}

.growing-item-double {
  flex-grow: 2; /* This item grows twice as much as items with flex-grow: 1 */
}

flex-shrink

Controls how much an item can shrink relative to others:

.item {
  flex-shrink: 1; /* Default - item can shrink if needed */
}

.non-shrinking-item {
  flex-shrink: 0; /* Item won't shrink below its flex-basis */
}

flex-basis

Sets the initial main size of an item:

.item {
  flex-basis: auto; /* Default - uses the item's width/height */
}

.sized-item {
  flex-basis: 200px; /* Initial size is 200px along the main axis */
}

Shorthand: flex

Combines the three properties in one declaration:

.item {
  /* flex: flex-grow flex-shrink flex-basis */
  flex: 0 1 auto; /* Default */
}

.flexible-item {
  flex: 1; /* Same as flex: 1 1 0% - grows and shrinks equally */
}

.fixed-item {
  flex: 0 0 200px; /* Fixed width, won't grow or shrink */
}

align-self

Overrides the container’s align-items for a specific item:

.special-item {
  align-self: center; /* This item centers itself vertically */
}

order

Changes the visual order of items without changing the HTML:

.first-item {
  order: -1; /* Appears before items with higher order values */
}

.last-item {
  order: 1; /* Appears after items with lower order values */
}

Common Flexbox Patterns

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.nav-links {
  display: flex;
  gap: 20px; /* Modern way to add spacing between items */
}

Centering Content

.centered-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh; /* For vertical centering in viewport */
}

Card Layout

.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 0 1 300px; /* Don't grow, can shrink, basis 300px */
  display: flex;
  flex-direction: column;
}

.card-body {
  flex-grow: 1; /* Takes available space */
}

.card-footer {
  margin-top: auto; /* Pushes footer to bottom */
}

Reference Documentation:

Additional Topics: Enhancing Your CSS Foundation

Cascading and Inheritance

CSS stands for “Cascading Style Sheets” because styles cascade - meaning multiple style rules can apply to the same element, with conflicts resolved according to:

  1. Importance: !important declarations override normal declarations
  2. Specificity: More specific selectors override less specific ones
  3. Source order: Later styles override earlier ones
p { color: blue; } /* Less specific */
.article p { color: green; } /* More specific, overrides the above */
#intro p { color: red; } /* Even more specific, overrides both above */

Responsive Design Fundamentals

Responsive design ensures layouts work well on any device size:

Media Queries

/* Base styles for all devices */
.container {
  padding: 20px;
}

/* Styles for screens wider than 768px */
@media (min-width: 768px) {
  .container {
    padding: 40px;
  }
}

Common Breakpoints

  • Mobile: less than 600px
  • Tablet: 600px to 900px
  • Desktop: more than 900px
/* Mobile-first approach */
.container {
  flex-direction: column; /* Stack on small screens */
}

@media (min-width: 768px) {
  .container {
    flex-direction: row; /* Side by side on larger screens */
  }
}

Best Practices

Organize Your CSS

Structure your CSS for maintainability:

/* 1. Reset/Normalize */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* 2. Typography */
body {
  font-family: 'Segoe UI', sans-serif;
  line-height: 1.5;
}

/* 3. Layout components */
.container { /* ... */ }
.grid { /* ... */ }

/* 4. Components */
.button { /* ... */ }
.card { /* ... */ }

/* 5. Utilities */
.text-center { text-align: center; }
.mt-1 { margin-top: 1rem; }

Use CSS Variables for Maintainability

:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --text-color: #333;
  --spacing-unit: 8px;
}

.button {
  background-color: var(--primary-color);
  color: white;
  padding: calc(var(--spacing-unit) * 2);
}

Browser Developer Tools

Make sure to mention that all modern browsers include developer tools (usually accessible with F12) that allow for:

  • Inspecting elements
  • Seeing applied CSS rules
  • Testing changes in real-time
  • Debugging layout issues

Reference Documentation:

< Look at other lectures