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 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 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 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 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.