dev9
dev9

Reputation: 2382

Responsive font size using CSS/jQuery

I want to create a responsive text inside a div.

I tried jquery-textfill and FlowType, but they are not working for me at all.

FlowType does not use all the available space, only a part of it (demo), while textfill does not respect the height (demo).

Am I using them incorrecly or what I want is too hard to achieve?

My HTML:

<body>
    <div class="external">
        <div class="internal">Example</div>
    </div>    
</body>

My CSS:

.internal{width:100%;height:100%}
.external{width:400px;height:50px;}

PS. Viewports are not supported enough for now.

Upvotes: 0

Views: 7047

Answers (3)

Josh Bradley
Josh Bradley

Reputation: 1974

For anyone who stumbles upon this old post, I have found a solution I consider perfect.

You take this beautiful plugin written by Dave Rupert, configure the settings to your liking, and I added a wrapper for it that allows you to define the elements you want to resize. It also stores the original font size so when you scale back up, the text is limited by it's original size, otherwise it scales without limit.

Here's a snippet and a jsfiddle. JSFiddle

NOTE: the snippet only runs on resize in JSFiddle so be sure to resize your screen. In production it runs on load.

var headings = [$('h1'), $('h2'), $('h3')]

  $.each(headings, function(index, heading) {

    var fontsize = heading.css('font-size');
    $(window).on('load resize', function() {
      if (heading.parent()[0] &&
        heading.parent()[0].scrollWidth > $('.container').innerWidth()) {
        heading.fitText(1, {
          minFontSize: '10px',
          maxFontSize: fontsize
        });
      }
    });
  });


  /*global jQuery */
  /*!
   * FitText.js 1.2
   *
   * Copyright 2011, Dave Rupert http://daverupert.com
   * Released under the WTFPL license
   * http://sam.zoy.org/wtfpl/
   *
   * Date: Thu May 05 14:23:00 2011 -0600
   */

  $.fn.fitText = function(kompressor, options) {
    // Setup options
    var compressor = kompressor || 1,
      settings = $.extend({
        'minFontSize': Number.NEGATIVE_INFINITY,
        'maxFontSize': Number.POSITIVE_INFINITY
      }, options);
    return this.each(function() {
      // Store the object
      var $this = $(this);
      // Resizer() resizes items based on the object width divided by the compressor * 10
      var resizer = function() {
        $this.css('font-size', Math.max(Math.min($this.width() / (compressor * 10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
      };
      // Call once to set.
      resizer();
      // Call on resize. Opera debounces their resize by default.
      $(window).on('resize.fittext orientationchange.fittext', resizer);
    });
  };
.container {
  width: 80vw;
  background: yellow;
}

h1 {
  font-size: 5rem;
}

h2 {
  font-size: 4rem;
}

h3 {
  font-size: 3rem;
}

h4 {
  font-size: 1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h1>GIGANTICFONT</h1>
</div>
<div class="container">
  <h2>LargishFont</h2>
</div>
<div class="container">
  <h3>Mediumfont</h3>
</div>
<div class="container">
  <h4>smallfont</h4>
</div>

Upvotes: 0

flowstoneknight
flowstoneknight

Reputation: 1236

EDIT: Updated with resize event listener. Updated fiddle.

As I understand it, you want the text to be as large as possible while still fitting inside the containing <div>, correct? My solution is to put a <span> around the text, which conforms to the text's normal size. Then calculate the ratios between the container's dimensions and the <span>'s dimensions. Whichever is the smaller ratio (either width or height), use that ratio to enlarge the text.

HTML:

<div class="container">
    <span class="text-fitter">
        text here
    </span>
</div>

JS (jQuery):

textfit();
$(window).on('resize', textfit);

function textfit() {
    $('.text-fitter').css('font-size', 'medium');
    var w1 = $('.container').width()-10;
    var w2 = $('.text-fitter').width();
    var wRatio = Math.round(w1 / w2 * 10) / 10;

    var h1 = $('.container').height()-10;
    var h2 = $('.text-fitter').height();
    var hRatio = Math.round(h1 / h2 * 10) / 10;

    var constraint = Math.min(wRatio, hRatio);

    $('.text-fitter').css('font-size', constraint + 'em');
}

Here's a fiddle. Adjust the .container dimensions in the CSS to see it in action.

Upvotes: 5

Hamix
Hamix

Reputation: 1335

CSS

.internal{width:100%;height:100%}
.external{width:auto;height:auto;background-color:yellow}

JQuery

$(".external").fitText(0.5);

DEMO 1

Update 1:

CSS

.internal{width:auto;height:auto;position:absolute;}
.external{width:400px;height:50px;background-color:yellow;position:relative;}

JQuery

$(".external").fitText();

DEMO 2

Update 2:

JQuery

var ex=$(".external");
var h=ex.height();
var w=ex.width();
ex.fitText(Math.min(h,w)/Math.max(h,w) );

DEMO 3

Update 4:

Bigtext is a jQuery text plugin that automatically enlarge the font size of your text to fill its parent container, without overflowing the container Div. jQuery Bigtext Plugin

Upvotes: 1

Related Questions