I'm wondering if there is a CSS-only solution to make contents scale
to fit their container
Short answer:
No.
Longer answer:
You can scale a font-size:
- relative to the viewport (using
vw
, vh
, vmax
and vmin
)
- relative to the font size of the current element (using
em
or %
)
- relative to the font size of the root element (using
rem
)
You can also scale a font-size relative to its parent element, if the parent element in question is also sized relative to the viewport.
eg. if the stylesheet reads:
p {
width: 20vw;
font-size: 2vw;
}
then the width
of the p
will always be 20% of the viewport width and the font-size
of the p
will always be 2% of the viewport width... so the font-size
of the p
will always be 10% of the width
of the p
.
You can also (self-evidently) scale the font-size relative to a fixed width parent:
eg. if the stylesheet reads:
p {
width: 200px;
font-size: 20px;
}
then the font-size
of the p
will always be 10% of the width
of the p
.
But there is no unit which enables the font-size
of a fixed-width element to be inversely proportional to the amount of text present in the element.
That's not to say you can't build a javascript-based solution of course...
So, here is a quick script which decreases the font-size
of a div
as the textual content of that div
increases:
var containers = document.getElementsByClassName('container');
for (var i = 0; i < containers.length; i++) {
var text = containers[i].textContent;
var calculatedFontSize;
switch (true) {
case (text.length < 10) : calculatedFontSize = 50; break;
case (text.length < 20) : calculatedFontSize = 40; break;
case (text.length < 30) : calculatedFontSize = 30; break;
case (text.length < 40) : calculatedFontSize = 24; break;
case (text.length < 50) : calculatedFontSize = 22; break;
case (text.length < 60) : calculatedFontSize = 21; break;
case (text.length < 70) : calculatedFontSize = 20; break;
case (text.length < 80) : calculatedFontSize = 19; break;
case (text.length < 90) : calculatedFontSize = 18; break;
case (text.length < 100) : calculatedFontSize = 17; break;
case (text.length < 110) : calculatedFontSize = 16; break;
case (text.length < 120) : calculatedFontSize = 15; break;
case (text.length < 130) : calculatedFontSize = 14; break;
default : calculatedFontSize = 12; break;
}
containers[i].style.fontSize = calculatedFontSize + 'px';
}
.container {
position: relative;
display: inline-block;
width: 2in;
height: 1in;
margin: 0 6px 6px 0;
background-color: rgb(191,191,191);
vertical-align: top;
}
<div class="container">
Some Text.
</div>
<div class="container">
A little more text.
</div>
<div class="container">
Considerably more text, now something like the size of a sentence.
</div>
<div class="container">
Another container with significantly more content, and so the font should scale down to fit.
</div>
<div class="container">
A fifth container with a very much larger amount of content, which inevitably ends up creating a much longer sentence.
</div>