Clamp it down
This replaces:
.memb-txt { font-size: clamp(1.15em, 2vw, 1.85em); }
All of this:
@media (max-width: 340px) {
.memb-txt {
font-size: 1.1em;
}
}
@media (max-width: 399px){
.memb-txt {font-size: 1.1em;}
}
@media (max-width: 450px){
.memb-txt {font-size: 1.25em;}
}
@media (max-width: 480px){
.memb-txt {font-size: 1.4em;}
}
@media (max-width: 680px){
.memb-txt {font-size: 1.5em;}
}
@media (max-width: 768px) {
.memb-txt {
font-size: 1.3em;
}
}
@media (max-width: 1011px){
.memb-txt {font-size: 1.4em;}
}
@media (max-width: 1050px){
.memb-txt {font-size: 1.55em;}
}
@media (max-width: 1242px) {
.memb-txt {
font-size: 1.55em;
}
}
@media (max-width: 1300px){
.memb-txt {font-size: 1.55em;}
}
and has other advantages as well
.memb-txt { font-size: clamp(1.15em, 2vw, 1.85em); }
The middle value needs to be a viewport-relative unit (like vw) for smooth scaling. The format is:clamp(minimum, preferred-value, maximum)
you should either use all the same unit type, or use vw for the middle value:
/* Option 1: All px */
font-size: clamp(14px, 1.55vw, 18px);
/* Option 2: All rem (relative to root - html {font-size: 12px})) */
font-size: clamp(1.166rem, 1.55vw, 1.5rem);
/* Option 3: All em (relative to parent, but might compound) */
font-size: clamp(1.1em, 1.55vw, 1.55em);
The middle value (1.55vw in these examples) is what creates the smooth scaling between your min and max values. .
To set a font size that differs for one element from the base:
You can “cheat” it by setting the base size first and then applying the clamp.
.memb-txt {
/* Set base size first */
font-size: 14px;
/* Override with clamp */
font-size: clamp(1.25em, 1.33vw, 1.5em);
/* base font-size: 14px (we set this above)
So this would give us:
Minimum (1.25em) = 14px × 1.25 = 17.5px
Maximum (1.5em) = 14px × 1.5 = 21px
Preferred (1.33vw) examples:
- At 1000px viewport: 13.3px (1000px × 0.0133)
- At 1200px viewport: 15.96px (1200px × 0.0133)
- At 1400px viewport: 18.62px (but will cap at 21px due to clamp)
*/
If we used rem values then:
/* When using rem values: */
font-size: 14px; /* This will be ignored when using rem in clamp */
font-size: 1.15rem; /* This sets it relative to root (12px × 1.15 = 13.8px) */
font-size: clamp(1.25rem, 1.33vw, 1.5rem);
/* All calculations now use html root (12px) as base:
/* base font size: (html {font-size: 12px;}):
So this would give us:
Minimum (1.25em)=12px × 1.25=15px
Maximum (1.5em)=12px × 1.5=18px
Preferred (1.33vw) examples:
- At 1000px viewport: 13.3px (1000px × 0.0133)
- At 1200px viewport: 15.96px (1200px × 0.0133)
- At 1400px viewport: 18.62px (but will cap at 18px due to clamp)
*/
text-transform: capitalize;
line-height: 1.15;
letter-spacing: -0.3px;
margin-top: 15px;
z-index: 14;
This works because:
First line sets 14px as fallback for older browsers Second line with clamp will override in modern browsers The em values will now be relative to the 14px base size instead of the html root size This is a valid approach and commonly used for progressive enhancement !
Why you should use rem units. rem’s set their value relative to the base font size (html{font-size: 12px}) – this better because if you use em’s it will compound the values.
Hover States
When using em units (not rem), the hover/active states will calculate their font sizes relative to the “base” size set in the non-hover state of that element. Here’s how it works:
/* Base state */
[id^="option-"].option .memb-txt {
font-size: 14px; /* Sets initial base size */
font-size: clamp(1.15em, 2vw, 1.85em); /* Uses 14px as base for em calculations */
}
/* Hover/active states */
[id^="option-"].option:hover .memb-txt,
[id^="option-"].option.pressed-button .memb-txt {
font-size: 1.75em; /* This will be calculated as: 14px × 1.75 = 24.5px */
color: var(--color-secondary);
}
EM and EM
has a compounding effect.When you use clamp() with em units after setting an initial em size on .memb-txt, it compounds/multiplies the values. Here’s how it works:
/* If html is 12px */
.memb-txt {
font-size: 1.4em; /* This makes it 16.8px (12px × 1.4) */
}
/* Then this clamp would be calculated based on 16.8px, not 12px */
[id^="option-"].option:hover .memb-txt {
font-size: clamp(1.1em, 1.55vw, 1.55em);
/* 1.1em = 18.48px (16.8px × 1.1) */
/* 1.55em = 26.04px (16.8px × 1.55) */
}
This is why it’s crucial to be careful with em units in hover states – they compound from the base size. If you want to avoid this relationship, you could:
- Use rem to always calculate from root
- Use absolute units like px
- Use a new clamp() calculation for the hover state
REM
if you want to set a different base size for .memb-txt specifically,you can use rem units instead of em. This way, the size will be relative to the root (html) font size rather than inheriting from its parent. Here’s how we can modify it:
/* If html { font-size: 12px; } and we want .memb-txt to start from, say, 14px as base */
.memb-txt {
text-transform: capitalize;
line-height: 1.15;
font-weight: 700;
/* 14px ÷ 12px = 1.166666667rem */
font-size: clamp(1.166666667rem, 1.55vw, 1.55rem);
letter-spacing: -0.3px;
…16px */
/* 16px ÷ 12px = 1.333333333rem */
font-size: clamp(1.333333333rem, 1.8vw, 1.75rem);
color: #CAA973;
}
This way: The sizes are calculated relative to the root 12px We can set any base size we want by converting to rem (desired px ÷ 12) It’s more predictable since it’ s not inheriting from parent elements The clamp still works the same way, just with rem units instead of em
Designers Prospective
From a designer’s perspective, here’s the argument for keeping individual breakpoints instead of using clamp():Precise Control: Breakpoints allow designers to make very specific adjustments at exact viewport widths. For example, in your code:
@media (max-width: 399px) {
.memb-txt {font-size: 1.1em;}
}
@media (max-width: 450px) {
.memb-txt {font-size: 1.25em;}
}
@media (max-width: 680px) {
.memb-txt {font-size: 1.5em;}
Visual Certainty: Designers can test each breakpoint and know exactly what size the text will be at specific screen sizes. With clamp(), the scaling is fluid which can lead to “in-between” sizes they didn’t specifically design for.Design System Alignment: Breakpoints often align with broader design system decisions – perhaps these specific font sizes match other elements at these exact viewport widths.
Device-Specific Optimization: These specific breakpoints might correspond to common device sizes where the design needs to look perfect (iPhone SE at 375px, iPad at 768px, etc.).
Legacy Support: Some older browsers don’t support clamp(), so breakpoints provide better backwards compatibility.
Easier QA: It’s simpler to test and verify designs at specific breakpoints than to check fluid scaling between sizes.
The tradeoff is between smooth scaling (clamp()) versus pixel-perfect control at specific widths (breakpoints).
BUT – the majority of all layouts will AUTOMATICALLY look very good
if there is a particular breakpoint that needs adjusting – then we only do an adjustment for that one.
Browser Support
Here’s the browser support breakdown for clamp():Major browsers that DO NOT support clamp():
Internet Explorer (all versions)
Opera Mini (all versions)
UC Browser for Android versions below 12.12
KaiOS Browser (all versions)
All modern browsers support clamp() since:
Chrome 79+ (Dec 2019)
Firefox 75+ (April 2020)
Safari 13.1+ (March 2020)
Edge 79+ (Jan 2020)
Opera 66+ (Dec 2019)
Samsung Internet 12.0+ (Dec 2019)
Current global usage statistics:
clamp() is supported in browsers used by approximately 94% of users worldwide
The main concern would be IE11 users (less than 0.5% of global users)
If IE11 support is needed, you could use this fallback pattern:
.memb-txt {
/* Fallback for IE11 */
font-size: 14px;
/* Modern browsers */
font-size: clamp(1.15em, 2vw, 1.85em);
}
IE11 will use the first declaration while modern browsers will use the clamp() value.