← Back to Course Overview

Module 4: HTML & CSS III

The Cascade

The "C" in CSS stands for "Cascading," which is a fundamental concept for understanding how styles are applied to HTML elements. The cascade determines which styles are applied when multiple conflicting rules target the same element.

What is the Cascade?

The cascade is the algorithm that determines which CSS rules apply when multiple rules could style the same element. It's based on three main factors in this order of importance:

  1. Importance - Rules with !important override normal rules
  2. Specificity - More specific selectors override less specific ones
  3. Source Order - Later rules override earlier rules

Specificity Calculation

Specificity is calculated as a four-part value:

  1. Inline styles (style attribute)
  2. Number of ID selectors
  3. Number of class selectors, attribute selectors, and pseudo-classes
  4. Number of element selectors and pseudo-elements
/* Specificity: 0-0-0-1 */
p {
  color: black;
}

/* Specificity: 0-0-1-0 */
.text {
  color: blue;
}

/* Specificity: 0-1-0-0 */
#unique {
  color: red;
}

/* Specificity: 1-0-0-0 */
/* HTML:

Inline style

*/

In the example above, an element with id="unique" class="text" would be red because the ID selector has higher specificity than the class selector.

Common Specificity Mistakes

Avoid these common pitfalls:

  • Overusing !important - it breaks the natural cascade
  • Using overly specific selectors that are hard to override
  • Relying on source order instead of proper specificity

The Box Model

The CSS Box Model is a fundamental concept that describes how elements are rendered on a webpage. Every HTML element is treated as a box with four areas: content, padding, border, and margin.

Box Model Components

  • Content: The inner area where text and images appear
  • Padding: The space between the content and the border
  • Border: The line around the padding
  • Margin: The space outside the border, separating the element from others
CSS Box Model Diagram

Box Sizing

The box-sizing property determines how the width and height of elements are calculated:

/* Default - width applies to content only */
.box-content {
  box-sizing: content-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
  /* Total width: 200px + 40px (padding) + 10px (border) = 250px */
}

/* More intuitive - width includes content, padding and border */
.box-border {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
  /* Total width: 200px (content area shrinks to accommodate padding and border) */
}

Many developers prefer to use box-sizing: border-box globally for more predictable layouts:

*, *::before, *::after {
  box-sizing: border-box;
}

Flexbox Layout

Flexbox (Flexible Box Layout) is a one-dimensional layout system designed for arranging items in rows or columns. It's particularly useful for creating responsive elements within a container:

Setting Up a Flex Container

.flex-container {
  display: flex;
  flex-direction: row; /* or column */
  justify-content: space-between;
  flex-wrap: wrap; /* allow items to wrap */
  gap: 10px;
}

Styling Flex Items

.flex-item {
  flex: 1; /* shorthand for flex-grow, flex-shrink, flex-basis */
  align-self: center;
  order: 2;
}

Key Flexbox Properties

  • display: flex - Creates a flex container
  • flex-direction - Sets the main axis (row, column)
  • justify-content - Aligns items along the main axis
  • flex-wrap - Controls whether items wrap to new lines
  • gap - Sets spacing between flex items
  • align-items - Aligns items along the cross axis
  • align-content - Aligns wrapped lines in a container
  • flex-grow - How much an item can grow
  • flex-shrink - How much an item can shrink
  • flex-basis - Initial main size of the item
  • align-self - Override align-items for specific items
  • order - Controls the order of flex items

Building Responsive Layouts with Flexbox

Flexbox can be used with media queries to create responsive layouts:

.container {
  display: flex;
  flex-direction: column;
}

@media (max-width: 768px) {
  .container {
    padding: 10px;
  }
  .flex-container {
    flex-direction: column;
  }
}

Responsive Design Principles

  • Mobile-first approach: Design for mobile devices first, then enhance for larger screens
  • Fluid layouts: Use relative units like percentages instead of fixed pixels
  • Flexible images: Make images scale with their containers
  • Media queries: Apply different styles based on device characteristics
  • Content prioritization: Ensure critical content is visible regardless of screen size

The Cascade & Specificity

The cascade is the algorithm that determines which CSS rules apply when multiple rules target the same element. Specificity is a key part of this algorithm and helps determine which style declaration takes precedence.

Cascade Order

CSS rules cascade in the following order of importance (highest to lowest):

  1. !important declarations
  2. Inline styles (style attribute)
  3. ID selectors (#id)
  4. Class selectors (.class), attribute selectors ([attr]), and pseudo-classes (:hover)
  5. Element selectors (div, p) and pseudo-elements (::before)

Calculating Specificity

Specificity is calculated as a four-part value: a:b:c:d

  • a: Inline styles (1 if present, 0 if not)
  • b: Number of ID selectors
  • c: Number of class, attribute, and pseudo-class selectors
  • d: Number of element and pseudo-element selectors
/* Specificity: 0,0,0,1 */
p {
  color: black;
}

/* Specificity: 0,0,1,1 */
p.note {
  color: blue;
}

/* Specificity: 0,1,0,1 */
#content p {
  color: red;
}

The !important Exception

The !important rule overrides normal specificity calculations, but should be used sparingly:

.critical {
  color: red !important; /* Will override even higher specificity selectors */
}

Best Practice: Rely on proper specificity rather than !important when possible. Overuse of !important can lead to maintenance difficulties and specificity wars.

Advanced Selectors and Specificity

CSS offers a rich variety of selectors that allow you to target elements with great precision. Understanding these selectors and their specificity is crucial for writing maintainable CSS.

Attribute Selectors

Target elements based on their attributes:

/* Selects all input elements with a type attribute of "text" */
input[type="text"] {
  border: 1px solid blue;
}

/* Selects all links with URLs that start with "https" */
a[href^="https"] {
  color: green;
}

/* Selects all images with file extensions ending in "jpg" */
img[src$=".jpg"] {
  border: 2px solid black;
}

Pseudo-Classes

Select elements based on state or position:

/* Styles applied when hovering over a button */
button:hover {
  background-color: lightgray;
}

/* Styles for the first child of a parent */
li:first-child {
  font-weight: bold;
}

/* Styles for odd-numbered items */
tr:nth-child(odd) {
  background-color: #f3f3f3;
}

Combinators

Use relationship-based selectors for more targeted styling:

/* Descendant selector - all paragraphs inside a container */
.container p {
  line-height: 1.5;
}

/* Child selector - only direct children paragraphs */
.container > p {
  margin-bottom: 1rem;
}

/* Adjacent sibling - paragraph immediately following a heading */
h2 + p {
  font-style: italic;
}

/* General sibling - all paragraphs that follow a heading */
h2 ~ p {
  color: #555;
}

Guided Project

In this guided project, you will take a deep dive into the Cascade, which is the mechanism browsers use to determine which particular CSS style comes into effect of all the different styles that may target the same HTML element. You will also learn about the Box Model, and how elements utilize space when rendered on a page. Finally, you will unlock the secrets of Flexbox, a powerful CSS module that will allow you to position elements along a line, whether horizontal or vertical, with precision and ease.

Solution Preview

This guided project demonstrates:

  • The CSS cascade mechanism and how specificity determines which styles apply
  • Working with the box model to control spacing and layout
  • Implementing Flexbox to create flexible layouts
  • Using selectors to target specific elements
  • Controlling element positioning with Flexbox properties like align-items, justify-content, and flex-grow

Additional Resources