I\'m having a hard time getting my head around font scaling.
I currently have a website with a body font-size
of 100%. 100% of what though? This seems t
There is a big philosophy for this issue.
The easiest thing to do would be to give a certain font-size to body (I recommend 10), and then all the other element would have their font in em
or rem
.
I'll give you an example to understand those units.
Em
is always relative to its parent:
body{font-size: 10px;}
.menu{font-size: 2em;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5em;} /* That means 1.5*20 pixels = 30 pixels */
Rem
is always relative to body:
body{font-size: 10px;}
.menu{font-size: 2rem;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5rem;} /* that means 1.5*10 pixels = 15 pixels */
And then you could create a script that would modify font-size relative to your container width.
But this isn't what I would recommend. Because in a 900 pixels width container for example you would have a p
element with a 12 pixels font-size let's say. And on your idea that would become an 300 pixels wide container at 4 pixels font-size. There has to be a lower limit.
Other solutions would be with media queries, so that you could set font for different widths.
But the solutions that I would recommend is to use a JavaScript library that helps you with that. And fittext.js that I found so far.
This question is asked in a comment by Alex under the accepted answer.
That fact does not mean vw
cannot be used to some extent to size for that container. Now to see any variation at all one has to be assuming that the container in some way is flexible in size. Whether through a direct percentage width
or through being 100% minus margins. The point becomes "moot" if the container is always set to, let's say, 200px
wide--then just set a font-size
that works for that width.
Example 1
With a flexible width container, however, it must be realized that in some way the container is still being sized off the viewport. As such, it is a matter of adjusting a vw
setting based off that percentage size difference to the viewport, which means taking into account the sizing of parent wrappers. Take this example:
div {
width: 50%;
border: 1px solid black;
margin: 20px;
font-size: 16px;
/* 100 = viewport width, as 1vw = 1/100th of that
So if the container is 50% of viewport (as here)
then factor that into how you want it to size.
Let's say you like 5vw if it were the whole width,
then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
*/
font-size: 2.5vw;
}
Assuming here the div
is a child of the body
, it is 50%
of that 100%
width, which is the viewport size in this basic case. Basically, you want to set a vw
that is going to look good to you. As you can see in my comment in the above CSS content, you can "think" through that mathematically with respect to the full viewport size, but you don't need to do that. The text is going to "flex" with the container because the container is flexing with the viewport resizing. UPDATE: here's an example of two differently sized containers.
Example 2
You can help ensure viewport sizing by forcing the calculation based off that. Consider this example:
html {width: 100%;} /* Force 'html' to be viewport width */
body {width: 150%; } /* Overflow the body */
div {
width: 50%;
border: 1px solid black;
margin: 20px;
font-size: 16px;
/* 100 = viewport width, as 1vw = 1/100th of that
Here, the body is 150% of viewport, but the container is 50%
of viewport, so both parents factor into how you want it to size.
Let's say you like 5vw if it were the whole width,
then for this container, size it at 3.75vw
(5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
*/
font-size: 3.75vw;
}
The sizing is still based off viewport, but is in essence set up based off the container size itself.
If the sizing of the container element ended up changing dynamically its percentage relationship either via @media
breakpoints or via JavaScript, then whatever the base "target" was would need recalculation to maintain the same "relationship" for text sizing.
Take example #1 above. If the div
was switched to 25%
width by either @media
or JavaScript, then at the same time, the font-size
would need to adjust in either the media query or by JavaScript to the new calculation of 5vw * .25 = 1.25
. This would put the text size at the same size it would have been had the "width" of the original 50%
container been reduced by half from viewport sizing, but has now been reduced due to a change in its own percentage calculation.
A Challenge
With the CSS3 calc() function in use, it would become difficult to adjust dynamically, as that function does not work for font-size
purposes at this time. So you could not do a pure CSS 3 adjustment if your width is changing on calc()
. Of course, a minor adjustment of width for margins may not be enough to warrant any change in font-size
, so it may not matter.
For dynamic text, this plugin is quite useful:
http://freqdec.github.io/slabText/
Simply add CSS:
.slabtexted .slabtext
{
display: -moz-inline-box;
display: inline-block;
white-space: nowrap;
}
.slabtextinactive .slabtext
{
display: inline;
white-space: normal;
font-size: 1em !important;
letter-spacing: inherit !important;
word-spacing: inherit !important;
*letter-spacing: normal !important;
*word-spacing: normal !important;
}
.slabtextdone .slabtext
{
display: block;
}
And the script:
$('#mydiv').slabText();
Here is the function:
document.body.setScaledFont = function(f) {
var s = this.offsetWidth, fs = s * f;
this.style.fontSize = fs + '%';
return this
};
Then convert all your documents child element font sizes to em
's or %
.
Then add something like this to your code to set the base font size.
document.body.setScaledFont(0.35);
window.onresize = function() {
document.body.setScaledFont(0.35);
}
http://jsfiddle.net/0tpvccjt/
This web component changes the font size so the inner text width matches the container width. Check the demo.
You can use it like this:
<full-width-text>Lorem Ipsum</full-width-text>
Always have your element with this attribute:
JavaScript: element.style.fontSize = "100%";
or
CSS: style = "font-size: 100%;"
When you go fullscreen, you should already have a scale variable calculated (scale > 1 or scale = 1). Then, on fullscreen:
document.body.style.fontSize = (scale * 100) + "%";
It works nicely with little code.