You can use media queries and set the font-size attribute on the html element (using px), and then set the font-size of other elements using rem, like so:
@media screen and (max-width: 720px){ /* smartphones breakpoint */
html{font-size: 12px}
}
@media screen and (min-width: 720px) and (max-width: 1024px){ /* tablets */
html{font-size: 14px}
}
@media screen and (min-width: 1024px){ /* laptops */
html{font-size: 16px}
}
h1{
font-size: 2rem
}
Obviously, you can add/modify as many breakpoints as you want. This will allow you to make sure you control what is happening in edge cases (as always, you should test your work using the Chrome device emulator feature, or real devices if possible).
Mixing this technique with the one suggested by Chris Stephens could also be interesting. For example, you could have an an upper & lower breakpoints with absolute font-sizes, and relative ones in between.
Hope this helps :)