Viewport Sized Typography with Minimum and Maximum Sizes

Declaring font sizes in viewport units can produce really interesting results, but it does come with challenges. There are no min-font-size or max-font-size properties in CSS, so edge cases where text gets too small or too big are difficult to deal with.

This Sass mixin makes use of media queries to define a minimum and maximum size for the font, in pixels. It also supports an optional parameter to serve as a fallback to browsers that don't support viewport units.

As an example, this is how you'd define a font as 5vw constrained between 35px and 150px (with a fallback of 50px for non-supporting browsers):

@include responsive-font(5vw, 35px, 150px, 50px);

And here's the full mixin:

///
/// Viewport sized typography with minimum and maximum values
///
/// @author Eduardo Boucas (@eduardoboucas)
///
/// @param {Number}   $responsive  - Viewport-based size
/// @param {Number}   $min         - Minimum font size (px)
/// @param {Number}   $max         - Maximum font size (px)
///                                  (optional)
/// @param {Number}   $fallback    - Fallback for viewport-
///                                  based units (optional)
///
/// @example scss - 5vw font size (with 50px fallback), 
///                 minumum of 35px and maximum of 150px
///  @include responsive-font(5vw, 35px, 150px, 50px);
///
@mixin responsive-font($responsive, $min, $max: false, $fallback: false) {
  $responsive-unitless: $responsive / ($responsive - $responsive + 1);
  $dimension: if(unit($responsive) == 'vh', 'height', 'width');
  $min-breakpoint: $min / $responsive-unitless * 100;
  
  @media (max-#{$dimension}: #{$min-breakpoint}) {
    font-size: $min;
  }
  
  @if $max {
    $max-breakpoint: $max / $responsive-unitless * 100;
    
    @media (min-#{$dimension}: #{$max-breakpoint}) {
      font-size: $max;
    }
  }
  
  @if $fallback {
    font-size: $fallback;
  }
  
  font-size: $responsive;
}

Demo

See the Pen Viewport sized typography with minimum and maximum sizes by Eduardo Bouças (@eduardoboucas) on CodePen.

Comments

  1. User Avatar
    Tom Livingston
    Permalink to comment#

    How would you write out the @include when you want a fallback but no max size?

    • User Avatar
      Eduardo Bouças
      Permalink to comment#

      Hey Tom,

      You could pass false in place of the maximum size parameter.

      For example:

      @include responsive-font(5vw, 35px, false, 50px);
      

      I hope that helps!

    • User Avatar
      tomliv
      Permalink to comment#

      Perfect, thanks Eduardo Bouças

    • User Avatar
      Tom Livingston
      Permalink to comment#

      I am trying to use this in a project. In my base mobile-width styles, the vw unit font-size is being overwritten by a px font-size at a max-width:1000px breakpoint i have not, myself, defined. I don’t see the vw unit font-size working until after a 1000px wide browser window. What’s happening?

    • User Avatar
      Tom Livingston
      Permalink to comment#

      I basically understand what’s happening, but how do I get the benefits of this mixin at widths less than 1000px width?

    • User Avatar
      dahliacreative
      Permalink to comment#

      Hi, I’ve adapted your mixin to work using vmin so typography can respond both horizontally and vertically. Means that on wide screen laptops which are really wide but really short, the font shrinks to save space.

      I’ve also done one for units like margin and padding which acts in the same way.

      Hope others find them helpful, and feel free to suggest improvements, I’m sure they could be better!

  2. User Avatar
    Eduardo Bouças
    Permalink to comment#

    The media query is what creates the effect of the minimum font size. The higher you set the minimum size, the higher the width of that media query will be.

    If you want the vw units to always take effect, then you don’t need this mixin at all. Just set the font-size to use those units.

    Does that make sense?

  3. User Avatar
    dahliacreative
    Permalink to comment#

    Hi, I’ve adapted your mixin to work using vmin so typography can respond both horizontally and vertically. Means that on wide screen laptops which are really wide but really short, the font shrinks to save space.

    I’ve also done one for units like margin and padding which acts in the same way.

    Hope others find them helpful, and feel free to suggest improvements, I’m sure they could be better!

  4. User Avatar
    Aaron Barker
    Permalink to comment#

    At work we are exploring the potential use of this logic. As part of this exploration we realized that the “fluid” portion of a given min/fluid/max set of sizes would be different for each combination. I wanted to make a visual representation of how each set of sizes would overlap so we could make educated adjustments to the fluid portions and their overlaps to have the best experience possible, so I made the following CodePen. Hopefully it is of use to others reading this article.

    http://codepen.io/aaronbarker/full/zZroxL/

  5. User Avatar
    Robert
    Permalink to comment#

    There is a font-min/max-size in w3 html draft https://drafts.csswg.org/css-fonts-4/#font-min-max-size-prop

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag