CSS Tutorial 14: The Future of CSS

Course Finale

Welcome to the final CSS module. You have mastered the Box Model, Flexbox, Grid, Specificity, and Animations. Today, we step into the cutting-edge features of modern Web Engineering. These are the advanced tools that separate junior developers from senior UI architects.

Step 1: Custom Webkit Scrollbars

The default gray scrollbar on Windows and Mac browsers often ruins the aesthetic of a beautifully designed website. CSS allows us to override the browser's default scrollbar using special pseudo-elements.

  • ::-webkit-scrollbar: The entire background track of the scrollbar. We use this to set the width.
  • ::-webkit-scrollbar-track: The empty space the scrollbar moves inside.
  • ::-webkit-scrollbar-thumb: The actual draggable handle.

The CSS: Designing a Custom Scrollbar

/* 1. Set the width of the scrollbar */
::-webkit-scrollbar {
  width: 12px;
}

/* 2. Style the background track */
::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 8px;
}

/* 3. Style the draggable thumb handle */
::-webkit-scrollbar-thumb {
  background: #4C8BF5;
  border-radius: 8px;
}

The Output (Scroll inside the box below to see it in action):

Scroll down to see the custom blue scrollbar!

Line 2

Line 3

Line 4

Line 5

Line 6

Line 7

Line 8

Line 9

Line 10

Line 11

Line 12

Line 13

You reached the bottom!

Step 2: Dark Mode (prefers-color-scheme)

Modern operating systems (Windows, macOS, iOS, Android) allow users to set their entire device to "Dark Mode." Instead of building a complex JavaScript toggle button, you can use a specialized CSS Media Query to detect the user's operating system setting and automatically swap your CSS Variables!

The CSS: Automatic Theme Swapping

/* 1. Define default Light Mode variables at the root */
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
}

/* 2. Listen to the Operating System's Dark Mode setting */
@media (prefers-color-scheme: dark) {
  :root {
    /* Overwrite the variables with dark colors */
    --bg-color: #121212;
    --text-color: #f0f0f0;
  }
}

/* 3. Apply the variables to your webpage */
body {
  background-color: var(--bg-color);
  color: var(--text-color);
}
Why this is brilliant: You never have to write "dark mode" CSS classes for every single element. You just change the 3 or 4 core variables inside the media query, and the entire website repaints itself instantly.

Step 3: The :has() Relational Pseudo-class

For 25 years, CSS had a massive limitation: It could only style elements "downward" (Children). You could never style a Parent based on what was inside of it. In late 2023, browsers finally released the :has() selector, changing CSS forever.

The :has() selector acts as a "Parent Selector". It says: "Style this container ONLY if it contains a specific child element."

The HTML & CSS: Styling a Parent based on a Checkbox

<!-- HTML -->
<div class="card">
  <h3>Premium Plan</h3>
  <input type="checkbox" class="plan-selector">
</div>

/* CSS */
/* Normal Card Style */
.card { border: 2px solid gray; }

/* The Magic: If the card HAS a checked checkbox inside it, turn the WHOLE CARD blue! */
.card:has(input:checked) {
  border-color: blue;
  background-color: lightblue;
}

The Output (Click the checkbox to see the Parent Container react!):

Subscription Card

I am the Parent Container. My CSS will dynamically change if you check the box below.

Step 4: Container Queries (@container)

Media Queries (@media) are great, but they look at the entire browser window's width. What if you build a beautiful "User Profile Card" and you want to use it in a wide main article area, AND in a tiny narrow sidebar?

If you use a Media Query, the card in the sidebar will stay wide and broken until the whole browser shrinks. Container Queries solve this. They allow a component to change its layout based on the size of the box it is sitting inside, ignoring the browser window entirely!

The Mechanics:

  1. You must declare a parent element as a container using container-type: inline-size;.
  2. You write an @container rule instead of an @media rule.

The CSS: Responsive Components

/* 1. Define the wrapper as a Container */
.profile-wrapper {
  container-type: inline-size;
  container-name: profile;
}

/* 2. Default Mobile/Narrow Style (Stacked vertically) */
.profile-card {
  display: flex;
  flex-direction: column;
}

/* 3. The Container Query (Changes to a Row ONLY if its wrapper is wider than 500px) */
@container profile (min-width: 500px) {
  .profile-card {
    flex-direction: row;
  }
}

The Output (Drag the bottom-right corner of the dashed box to resize the container):

The dashed box below represents the Parent Wrapper. Drag its right edge to make it wider than 500px. Watch the inner card react independently of your actual browser window!

John Doe

Software Engineer

Final Course Quiz

Click the buttons below to verify your mastery of Modern CSS.

1. What does the `@media (prefers-color-scheme: dark)` rule allow you to do?
2. You have a `<form>`. Inside the form is an `<input type="text">`. You want to give the ENTIRE `<form>` a red border, but ONLY when the user clicks into the `<input>` field. How do you do this?
3. What is the primary difference between a Media Query (`@media`) and a Container Query (`@container`)?

Post a Comment

0 Comments