GithubHelp home page GithubHelp logo

cartertsai / fitty Goto Github PK

View Code? Open in Web Editor NEW

This project forked from rikschennink/fitty

0.0 2.0 0.0 623 KB

Makes text fit perfectly.

Home Page: https://rikschennink.github.io/fitty/

License: MIT License

JavaScript 100.00%

fitty's Introduction

Fitty Logo

Fitty, Snugly text resizing

Scales up (or down) text so it fits perfectly to its parent container.

Ideal for flexible and responsive websites.

Features

  • No dependencies
  • Easy setup
  • Optimal performance by grouping DOM read and write operations
  • Works with WebFonts (see example below)
  • Min and max font sizes
  • Support for MultiLine
  • Auto update when viewport changes
  • Monitors element subtree and updates accordingly

Time to learn ES6?

Fitty is written in ES6.

If you want to learn how to write modern ES6 JavaScript as well, I highly recommend ES6 for Everyone by Wes Bos.

Installation

Install from npm:

npm install fitty --save

Or download dist/fitty.min.js and include the script on your page like shown below.

Usage

Run fitty like shown below and pass an element reference or a querySelector. For best performance include the script just before the closing </body> element.

<div id="my-element">Hello World</div>

<script src="fitty.min.js"></script>
<script>
fitty('#my-element');
</script>

The following options are available to pass to the fitty method.

Option Default Description
minSize 16 The minimum font size in pixels
maxSize 512 The maximum font size in pixels
multiLine true Wrap lines when using minimum font size.
observeMutations MutationObserverInit Rescale when element contents is altered. Is set to false when MutationObserver is not supported. Pass a custom MutationObserverInit config to optimize monitoring based on your project. By default contains the MutationObserverInit configuration below or false based on browser support.

Default MutationObserverInit configuration:

{
  subtree: true,
  childList: true,
  characterData: true
}

You can pass custom arguments like this:

fitty('#my-element', {
  minSize: 12,
  maxSize: 300
});

The fitty function returns a single or multiple Fitty instances depending on how it's called. If you pass a query selector it will return an array of Fitty instances, if you pass a single element reference you'll receive back a single Fitty instance.

Method Description
fit() Force a redraw of the current fitty element
unsubscribe() Remove the fitty element from the redraw loop and restore it to its original state
Properties Description
element Reference to the related element
var fitties = fitty('.fit');

// get element reference of first fitty
var myFittyElement = fitties[0].element;

// force refit
fitties[0].fit();

// unsubscribe from fitty, restore to original state
fitties[0].unsubscribe();

Fitty dispatches an event named "fit" when a fitty is fitted.

Event Description
"fit" Fired when the element has been fitted to the parent container.

The detail property of the event contains an object which exposes the font size oldValue the newValue and the scaleFactor.

The fitty function itself also exposes some static options and methods:

Option Default Description
fitty.observeWindow true Listen to the "resize" and "orientationchange" event on the window object and update fitties accordingly.
fitty.observeWindowDelay 100 Redraw debounce delay in milliseconds for when above events are triggered.
Method Description
fitty.fitAll() Refits all fitty instances to match their parent containers. Essentially a request to redraw all fitties.

Performance

For optimal performance add a CSS selector to your stylesheet that sets the elements that will be resized to have white-space:nowrap and display:inline-block. If not, Fitty will detect this and will have to restyle the elements automatically, resulting in a slight performance penalty.

Suppose all elements that you apply fitty to are assigned the fit class name, add the following CSS selector to your stylesheet:

.fit {
  display: inline-block;
  white-space: nowrap;
}

Should you only want to do this when JavaScript is available, add the following to the <head> of your web page.

<script>document.documentElement.classList.add('js');</script>

And change the CSS selector to:

.js .fit {
  display: inline-block;
  white-space: nowrap;
}

Custom Fonts

Fitty does not concern itself with custom fonts. But it will be important to redraw Fitty text after a custom font has loaded (as previous measurements are probably incorrect at that point).

If you need to use fitty on browsers that don't have CSS Font Loading support (Edge and Internet Explorer) you can use the fantastic FontFaceObserver by Bram Stein to detect when your custom fonts have loaded.

See an example custom font implementation below. This assumes fitty has already been called on all elements with class name fit.

<style>
/* Only set the custom font if it's loaded and ready */
.fonts-loaded .fit {
  font-family: 'Oswald', serif;
}
</style>
<script>
(function() {

  // no promise support (<=IE11)
  if (!('Promise' in window)) {
    return;
  }

  // called when all fonts loaded
  function redrawFitty() {
    document.documentElement.classList.add('fonts-loaded');
    fitty.fitAll();
  }

  // CSS Font Loading API 
  function native() {

    // load our custom Oswald font
    var fontOswald = new FontFace('Oswald', 'url(assets/oswald.woff2)', {
      style:'normal',
      weight:'400'
    });
    document.fonts.add(fontOswald);
    fontOswald.load();

    // if all fonts loaded redraw fitty
    document.fonts.ready.then(redrawFitty);
  }

  // FontFaceObserver
  function fallback() {

    var style = document.createElement('style');
    style.textContent = '@font-face { font-family: Oswald; src: url(assets/oswald.woff2) format("woff2");}'
    document.head.appendChild(style);

    var s = document.createElement('script');
    s.src = 'https://cdnjs.cloudflare.com/ajax/libs/fontfaceobserver/2.0.13/fontfaceobserver.standalone.js';
    s.onload = function() {
      new FontFaceObserver('Oswald').load().then(redrawFitty);    
    };
    document.body.appendChild(s);
  }

  // Does the current browser support the CSS Font Loading API?
  if ('fonts' in document) {
    native();
  }
  else {
    fallback();
  }

}());
</script>

Notes

Will not work if the element is not part of the DOM.

Tested

  • Modern browsers
  • IE 10+

Versioning

Versioning follows Semver.

License

MIT

fitty's People

Contributors

rikschennink avatar iyel avatar manuelandro avatar

Watchers

James Cloos avatar Carter Tsai avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.