It is entirely possible and as you can probably tell there is a number of ways to achieve this. The technique I use is very simple:
Set the font-size on the body and html elements in px, as well as any media query to step the font size up or down, in px.
Use rem units to set the font-size where you need. rem stands for root em, where root is the topmost element in the DOM, usually html or body.
Example:
html, body {
font-size: 18px;
}
@media screen and (max-width: 320px) {
html, body {
font-size: 15px;
}
}
/*
The rem values use 18px or 15px as the base unit
depending on matching query.
In this case there is no need to use 1rem unless you need to reset
a previously changed value.
*/
.heading { font-size: 1.2rem; }
.small { font-size: 0.8rem; }
Using rem makes it very easy (for me at least) to reason about relative sizes.
em on the other hand is very useful if want a value to be affected by the font-size of the closest parent element.
For example if you wanted to have a padding that scales proportionally to the text size of a .heading, then you'd use em:
html, body {
font-size: 18px;
}
@media screen and (max-width: 320px) {
html, body {
font-size: 15px;
}
}
.heading { font-size: 1.2rem; }
.small { font-size: 0.8rem; }
/*
Now you define a padding that is always 80% of the element's
font-size.
And since .heading is set at 1.2rem, the padding will be
80% of 1.2rem.
*/
.heading { padding: 0.8em; }