Superscripts and subscripts are important parts in educational and scientific content material — from quotation references to chemical formulation and mathematical expressions. But browsers deal with these parts with a static method that may create vital issues: parts change into both too small on cell gadgets or disproportionately massive on desktop shows.
After years of wrestling with superscript and subscript scaling in CSS, I’m proposing a contemporary resolution utilizing fluid calculations. On this article, I’ll present you why the static method falls brief and the way we are able to present higher typography throughout all viewports whereas sustaining accessibility. Better of all, this resolution requires nothing however clear, pure CSS.
The issue with static scaling
The scaling difficulty is especially evident when evaluating skilled typography with browser defaults. Take this instance (tailored from Wikipedia), the place the primary “2” is professionally designed and included within the glyph set, whereas the second makes use of <sub>
(high) and <sup>
(backside) parts:
Browsers have traditionally used font-size: smaller
for <sup>
and <sub>
parts, which interprets to roughly 0.83x scaling. Whereas this made sense within the early days of CSS for easy paperwork, it could create issues in trendy responsive designs the place font sizes can range dramatically. That is very true when utilizing fluid typography, the place textual content sizes can scale easily between extremes.
Fluid scaling: A greater resolution
I’ve developed an answer that scales extra naturally throughout totally different sizes by combining fastened and proportional models. This method ensures legibility at small sizes whereas sustaining correct proportions at bigger sizes, eliminating the necessity for context-specific changes.
Right here’s the way it works:
sup, sub {
font-size: calc(0.5em + 4px);
vertical-align: baseline;
place: relative;
high: calc(-0.5 * 0.83 * 2 * (1em - 4px));
/* Simplified high: calc(-0.83em + 3.32px) */
}
sub {
high: calc(0.25 * 0.83 * 2 * (1em - 4px));
/* Simplified high: calc(0.42em - 1.66px) */
}
- Pure scaling: The degressive system ensures that superscripts and subscripts stay proportional in any respect sizes
- Baseline alignment: By utilizing
vertical-align: baseline
and relative positioning, we stop the weather from affecting line peak and it offers us higher management over the offset to match your particular wants. You’re in all probability additionally questioning the place the heck these values come from — I’ll clarify within the following.
Breaking down the mathematics
Let’s have a look at how this works, piece by piece:
px
)
Calculating the font measurement (At small sizes, the fastened 4px
element has extra affect. At massive sizes, the 0.5em
proportion turns into dominant. The result’s extra pure scaling throughout all sizes.
sup, sub {
font-size: calc(0.5em + 4px);
/* ... */
}
sub {
/* ... */
}
em
)
Calculating the father or mother font measurement (Inside the <sup>
and <sub>
parts, we are able to calculate the father or mother’s font-size
:
sup, sub {
font-size: calc(0.5em + 4px);
high: calc(2 * (1em - 4px));
}
sub {
high: calc(2 * (1em + 4px));
}
The fluid font measurement is outlined as calc(0.5em + 4px)
. To compensate for the 0.5em
, we first want to unravel 0.5em * x = 1em
which provides us x = 2
. The 1em
right here represents the font measurement of the <sup>
and <sub>
parts themselves. We subtract the 4px
fastened element from our present em
worth earlier than multiplying.
The vertical offset
For the vertical offset, we begin with default CSS positioning values and alter them to work with our fluid scaling:
sup, sub {
font-size: calc(0.5em + 4px);
high: calc(-0.5 * 0.83 * 2 * (1em - 4px));
}
sub {
high: calc(0.25 * 0.83 * 2 * (1em - 4px));
}
The system is rigorously calibrated to match customary browser positioning:
0.5em
(tremendous) and0.25em
(sub) are the default vertical offset values (e.g. utilized in frameworks like Tailwind CSS and Bootstrap).- We multiply by
0.83
to account for the browser’sfont-size: smaller
scaling issue, which is used per default for superscript and subscript.
This method ensures that our superscripts and subscripts preserve acquainted vertical positions whereas benefiting from improved fluid scaling. The consequence matches what customers count on from conventional browser rendering however scales extra naturally throughout totally different font sizes.
Useful ideas
The precise scaling issue font-size: (0.5em + 4px)
relies on my evaluation of superscript Unicode characters in widespread fonts. Be happy to regulate these values to match your particular design wants. Listed below are a number of methods the way you would possibly need to customise this method:
For bigger scaling:
sup, sub {
font-size: calc(0.6em + 3px);
/* alter offset calculations accordingly */
}
For smaller scaling:
sup, sub {
font-size: calc(0.4em + 5px);
/* alter offset calculations accordingly */
}
For backward compatibility, you would possibly need to wrap all of it in a @helps
block:
@helps (font-size: calc(1em + 1px)) {
sup, sub {
...
}
}
Remaining demo
I constructed this small interactive demo to indicate totally different fluid scaling choices, evaluate them to the browser’s static scaling, and fine-tune the vertical positioning to see what works greatest on your use case:
Give it a attempt in your subsequent undertaking and glad to listen to your ideas!