HTML and CSS course Β· Module 9: Modern CSS
Modern CSS Functions - Part 1
In this lesson4
Modern CSS is a true treasure trove of tools that allow you to create more flexible, readable, and responsive websites. In this chapter, you'll learn four powerful functions: clamp(), aspect-ratio, :is(), and :where(). Each one solves a specific problem that developers struggled with for years - just as ancient Egyptian architects solved construction problems with their pyramids.
The clamp() Function - Flexible Values
The clamp() function lets you define a value that automatically adjusts to available space, but never goes beyond specified boundaries. It takes three arguments: minimum value, preferred value, and maximum value.
It's like building columns in a temple - they have minimum and maximum heights, but adapt to the space between them.
1/* Syntax: clamp(minimum, preferred, maximum) */
2
3/* Fluid typography - font grows with viewport */
4h1 {
5 font-size: clamp(1.5rem, 4vw, 3rem);
6 /* Minimum 1.5rem, preferred 4vw, max 3rem */
7}
8
9/* Flexible container width */
10.container {
11 width: clamp(300px, 80%, 1200px);
12 margin: 0 auto;
13}
14
15/* Responsive padding */
16.section {
17 padding: clamp(1rem, 3vw, 4rem);
18}
19
20/* Fluid spacing between elements */
21.grid {
22 gap: clamp(0.5rem, 2vw, 2rem);
23}The clamp() function is especially useful for fluid typography, where font size smoothly adjusts to screen width without needing media queries.
The aspect-ratio Property - Maintaining Proportions
The aspect-ratio property allows you to maintain element proportions regardless of its size. Previously, forcing proportions required padding-top tricks - now a single line of CSS suffices.
Think of pyramid proportions - their angle of inclination had to be perfect for the structure to be stable. Similarly, aspect-ratio ensures perfect proportions for your elements.
1/* Square - 1:1 proportions */
2.avatar {
3 width: 100px;
4 aspect-ratio: 1 / 1;
5 border-radius: 50%;
6 object-fit: cover;
7}
8
9/* Video - 16:9 proportions */
10.video-container {
11 width: 100%;
12 aspect-ratio: 16 / 9;
13 background: #000;
14}
15
16/* Photo - 4:3 proportions */
17.photo {
18 width: 100%;
19 aspect-ratio: 4 / 3;
20 object-fit: cover;
21}
22
23/* Card with maintained proportions */
24.card-image {
25 width: 100%;
26 aspect-ratio: 3 / 2;
27 object-fit: cover;
28 border-radius: 8px;
29}The :is() Pseudo-class - Simplifying Selectors
The :is() pseudo-class allows you to group multiple selectors into one, which significantly reduces repetition in CSS code. Instead of writing a long list of selectors, you can place them all inside :is().
It's like shorthand hieroglyphs - instead of drawing each symbol separately, we use one symbol to represent a group.
1/* Without :is() - lots of repetition */
2header h1, header h2, header h3,
3nav h1, nav h2, nav h3,
4footer h1, footer h2, footer h3 {
5 color: gold;
6}
7
8/* With :is() - concise and readable */
9:is(header, nav, footer) :is(h1, h2, h3) {
10 color: gold;
11}
12
13/* Styling links in different contexts */
14:is(article, section, aside) a:hover {
15 text-decoration: underline;
16 color: #c9a66b;
17}
18
19/* Nested lists */
20:is(ol, ul) :is(ol, ul) {
21 margin-left: 1.5rem;
22 font-size: 0.9em;
23}An important feature of :is() - it takes the specificity of the highest selector in the list. If :is(h1, .title, #main) contains an ID, the entire selector will have ID specificity.
The :where() Pseudo-class - Selectors Without Specificity
The :where() pseudo-class works identically to :is(), but with one crucial difference - it always has a specificity of 0. This makes it the ideal tool for creating CSS resets and default styles that can be easily overridden.
1/* :where() - specificity 0 */
2:where(header, nav, footer) a {
3 color: inherit;
4 text-decoration: none;
5}
6
7/* Easy to override with a regular class selector */
8.nav-link {
9 color: gold; /* This wins over the rule above */
10}
11
12/* List style reset - easy to override */
13:where(ul, ol) {
14 list-style: none;
15 padding: 0;
16 margin: 0;
17}
18
19/* Comparison :is() vs :where() */
20/* :is() - high specificity (like #id) */
21:is(#main, .content) p {
22 color: #333;
23}
24
25/* :where() - zero specificity */
26:where(#main, .content) p {
27 color: #333; /* Easy to override */
28}Practical rule: use :is() when you want to maintain selector specificity, and :where() when creating base/default styles that should be easily overridable.
Code for this lesson: index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Modern CSS features - part 1</title>
7 <link rel="stylesheet" href="style.css">
8</head>
9<body>
10 <div class="container">
11 <h1>Modern CSS features</h1>
12 <p class="subtitle">clamp(), aspect-ratio, :is(), :where()</p>
13
14 <section>
15 <h2>Fluid Typography with clamp()</h2>
16 <p class="fluid-text">This text scales smoothly thanks to clamp().</p>
17 <p class="fluid-small">Smaller text also uses clamp().</p>
18 </section>
19
20 <section>
21 <h2>Gallery with aspect-ratio</h2>
22 <div class="gallery">
23 <div class="gallery-item ratio-16-9">16:9</div>
24 <div class="gallery-item ratio-1-1">1:1</div>
25 <div class="gallery-item ratio-4-3">4:3</div>
26 </div>
27 </section>
28
29 <section>
30 <h2>Simplified selectors with :is()</h2>
31 <article>
32 <h3>Article heading</h3>
33 <p>A paragraph in an article with a <a href="#">link</a>.</p>
34 </article>
35 <nav>
36 <h3>Navigation</h3>
37 <p>A paragraph in the navigation with a <a href="#">link</a>.</p>
38 </nav>
39 </section>
40
41 <section>
42 <h2>Reset with :where()</h2>
43 <ul class="custom-list">
44 <li>Element 1</li>
45 <li>Element 2</li>
46 <li>Element 3</li>
47 </ul>
48 </section>
49 </div>
50</body>
51</html>Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What does the clamp(min, preferred, max) function do in CSS?
2. What does the :is() pseudo-class do in CSS?
Hands-on tasks in the game
- Click in order
Arrange the syntax for the clamp() function for fluid typography:
- Vertical ordering
Order the aspect-ratio values from narrowest (most vertical) to widest (most horizontal):
- Code editor
Create fluid typography using clamp(1rem, 2vw + 0.5rem, 3rem) for font sizes that scale smoothly.