{"id":13515601,"url":"https://github.com/rikschennink/fitty","last_synced_at":"2025-04-29T18:27:34.413Z","repository":{"id":41190223,"uuid":"98174544","full_name":"rikschennink/fitty","owner":"rikschennink","description":"✨ Makes text fit perfectly","archived":false,"fork":false,"pushed_at":"2023-12-16T14:13:53.000Z","size":798,"stargazers_count":3730,"open_issues_count":24,"forks_count":211,"subscribers_count":44,"default_branch":"gh-pages","last_synced_at":"2024-10-29T14:59:08.418Z","etag":null,"topics":["flexible","fluid","font-size","javascript","pixel","resize","responsive","scale","text"],"latest_commit_sha":null,"homepage":"https://rikschennink.github.io/fitty/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rikschennink.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"custom":["https://www.buymeacoffee.com/rikschennink"]}},"created_at":"2017-07-24T09:39:26.000Z","updated_at":"2024-10-26T11:53:49.000Z","dependencies_parsed_at":"2023-02-06T11:46:45.644Z","dependency_job_id":"11d212fb-ef58-482b-aa2e-dd6208dd93cc","html_url":"https://github.com/rikschennink/fitty","commit_stats":{"total_commits":110,"total_committers":11,"mean_commits":10.0,"dds":"0.10909090909090913","last_synced_commit":"e251efeff48d0f986378398bfa6d979cf4f497cd"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rikschennink%2Ffitty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rikschennink%2Ffitty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rikschennink%2Ffitty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rikschennink%2Ffitty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rikschennink","download_url":"https://codeload.github.com/rikschennink/fitty/tar.gz/refs/heads/gh-pages","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251558556,"owners_count":21608841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flexible","fluid","font-size","javascript","pixel","resize","responsive","scale","text"],"created_at":"2024-08-01T05:01:13.330Z","updated_at":"2025-04-29T18:27:34.383Z","avatar_url":"https://github.com/rikschennink.png","language":"JavaScript","readme":"# Fitty, Snugly text resizing\n\nScales up (or down) text so it fits perfectly to its parent container.\n\nIdeal for flexible and responsive websites.\n\n**[Visit PQINA.nl for other useful Web Components](https://pqina.nl/)**\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/rikschennink/fitty/blob/gh-pages/LICENSE)\n[![npm version](https://badge.fury.io/js/fitty.svg)](https://badge.fury.io/js/fitty)\n![npm](https://img.shields.io/npm/dt/fitty)\n\n---\n\n[\u003cimg src=\"https://github.com/rikschennink/fitty/blob/gh-pages/header.svg\" alt=\"\"/\u003e](https://www.buymeacoffee.com/rikschennink/)\n\n[Buy me a Coffee](https://www.buymeacoffee.com/rikschennink/) / [Dev updates on Twitter](https://twitter.com/rikschennink/)\n\n---\n\n## Features\n\n-   No dependencies\n-   Easy setup\n-   Optimal performance by grouping DOM read and write operations\n-   Works with WebFonts (see example below)\n-   Min and max font sizes\n-   Support for MultiLine\n-   Auto update when viewport changes\n-   Monitors element subtree and updates accordingly\n\n## Installation\n\nInstall from npm:\n\n```\nnpm install fitty --save\n```\n\nOr download `dist/fitty.min.js` and include the script on your page like shown below.\n\n## Usage\n\nRun fitty like shown below and pass an element reference or a querySelector. For best performance include the script just before the closing `\u003c/body\u003e` element.\n\n```html\n\u003cdiv id=\"my-element\"\u003eHello World\u003c/div\u003e\n\n\u003cscript src=\"fitty.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    fitty('#my-element');\n\u003c/script\u003e\n```\n\nThe following options are available to pass to the `fitty` method.\n\n| Option             | Default                | Description                                                                                                                                                                                                                                                                                       |\n| ------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `minSize`          | `16`                   | The minimum font size in pixels                                                                                                                                                                                                                                                                   |\n| `maxSize`          | `512`                  | The maximum font size in pixels                                                                                                                                                                                                                                                                   |\n| `multiLine`        | `true`                 | Wrap lines when using minimum font size.                                                                                                                                                                                                                                                          |\n| `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. |\n\nDefault MutationObserverInit configuration:\n\n```javascript\n{\n  subtree: true,\n  childList: true,\n  characterData: true\n}\n```\n\nYou can pass custom arguments like this:\n\n```javascript\nfitty('#my-element', {\n    minSize: 12,\n    maxSize: 300,\n});\n```\n\nThe `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.\n\n| Method          | Description                                                                        |\n| --------------- | ---------------------------------------------------------------------------------- |\n| `fit(options)`  | Force a redraw of the current fitty element                                        |\n| `freeze()`      | No longer update this fitty on changes                                             |\n| `unfreeze()`    | Resume updates to this fitty                                                       |\n| `unsubscribe()` | Remove the fitty element from the redraw loop and restore it to its original state |\n\n| Properties | Description                      |\n| ---------- | -------------------------------- |\n| `element`  | Reference to the related element |\n\n```javascript\nvar fitties = fitty('.fit');\n\n// get element reference of first fitty\nvar myFittyElement = fitties[0].element;\n\n// force refit\nfitties[0].fit();\n\n// force synchronous refit\nfitties[0].fit({ sync: true });\n\n// stop updating this fitty and restore to original state\nfitties[0].unsubscribe();\n```\n\nFitty dispatches an event named `\"fit\"` when a fitty is fitted.\n\n| Event   | Description                                                     |\n| ------- | --------------------------------------------------------------- |\n| `\"fit\"` | Fired when the element has been fitted to the parent container. |\n\nThe `detail` property of the event contains an object which exposes the font size `oldValue` the `newValue` and the `scaleFactor`.\n\n```js\nmyFittyElement.addEventListener('fit', function (e) {\n    // log the detail property to the console\n    console.log(e.detail);\n});\n```\n\nThe `fitty` function itself also exposes some static options and methods:\n\n| Option                     | Default | Description                                                                                               |\n| -------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |\n| `fitty.observeWindow`      | `true`  | Listen to the \"resize\" and \"orientationchange\" event on the window object and update fitties accordingly. |\n| `fitty.observeWindowDelay` | `100`   | Redraw debounce delay in milliseconds for when above events are triggered.                                |\n\n| Method                  | Description                                                                                                                                                                |\n| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `fitty.fitAll(options)` | Refits all fitty instances to match their parent containers. Essentially a request to redraw all fitties. The `options` object is passed to fitty instance `fit()` method. |\n\n## Performance\n\nFor 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.\n\nSuppose all elements that you apply fitty to are assigned the `fit` class name, add the following CSS selector to your stylesheet:\n\n```css\n.fit {\n    display: inline-block;\n    white-space: nowrap;\n}\n```\n\nShould you only want to do this when JavaScript is available, add the following to the `\u003chead\u003e` of your web page.\n\n```html\n\u003cscript\u003e\n    document.documentElement.classList.add('js');\n\u003c/script\u003e\n```\n\nAnd change the CSS selector to:\n\n```css\n.js .fit {\n    display: inline-block;\n    white-space: nowrap;\n}\n```\n\n## Do Not Upscale Text\n\nFitty calculates the difference in width between the text container and its parent container. If you use CSS to set the width of the text container to be equal to the parent container it won't scale the text.\n\nThis could be achieved by forcing the text container to be a block level element with `display: block !important` or setting its width to 100% with `width: 100%`.\n\n## Custom Fonts\n\nFitty 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).\n\nIf you need to use fitty on browsers that don't have [CSS Font Loading](http://caniuse.com/#feat=font-loading) support (Edge and Internet Explorer) you can use the fantastic [FontFaceObserver by Bram Stein](https://github.com/bramstein/fontfaceobserver) to detect when your custom fonts have loaded.\n\nSee an example custom font implementation below. This assumes fitty has already been called on all elements with class name `fit`.\n\n```html\n\u003cstyle\u003e\n    /* Only set the custom font if it's loaded and ready */\n    .fonts-loaded .fit {\n        font-family: 'Oswald', serif;\n    }\n\u003c/style\u003e\n\u003cscript\u003e\n    (function () {\n        // no promise support (\u003c=IE11)\n        if (!('Promise' in window)) {\n            return;\n        }\n\n        // called when all fonts loaded\n        function redrawFitty() {\n            document.documentElement.classList.add('fonts-loaded');\n            fitty.fitAll();\n        }\n\n        // CSS Font Loading API\n        function native() {\n            // load our custom Oswald font\n            var fontOswald = new FontFace('Oswald', 'url(assets/oswald.woff2)', {\n                style: 'normal',\n                weight: '400',\n            });\n            document.fonts.add(fontOswald);\n            fontOswald.load();\n\n            // if all fonts loaded redraw fitty\n            document.fonts.ready.then(redrawFitty);\n        }\n\n        // FontFaceObserver\n        function fallback() {\n            var style = document.createElement('style');\n            style.textContent =\n                '@font-face { font-family: Oswald; src: url(assets/oswald.woff2) format(\"woff2\");}';\n            document.head.appendChild(style);\n\n            var s = document.createElement('script');\n            s.src =\n                'https://cdnjs.cloudflare.com/ajax/libs/fontfaceobserver/2.0.13/fontfaceobserver.standalone.js';\n            s.onload = function () {\n                new FontFaceObserver('Oswald').load().then(redrawFitty);\n            };\n            document.body.appendChild(s);\n        }\n\n        // Does the current browser support the CSS Font Loading API?\n        if ('fonts' in document) {\n            native();\n        } else {\n            fallback();\n        }\n    })();\n\u003c/script\u003e\n```\n\n## Notes\n\n-   Will not work if the fitty element is not part of the DOM.\n\n-   If the parent element of the fitty element has horizontal padding the width calculation will be incorrect. You can fix this by wrapping the fitty element in another element.\n\n```html\n\u003c!-- Problems --\u003e\n\u003cdiv style=\"padding-left:100px\"\u003e\n    \u003ch1 class=\"fit\"\u003eI'm a wonderful heading\u003c/h1\u003e\n\u003c/div\u003e\n```\n\n```html\n\u003c!-- No more problems --\u003e\n\u003cdiv style=\"padding-left:100px\"\u003e\n    \u003cdiv\u003e\u003ch1 class=\"fit\"\u003eI'm a wonderful heading\u003c/h1\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n## Tested\n\n-   Modern browsers\n-   IE 10+\n\nNote that IE will require CustomEvent polyfill:\nhttps://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill\n\nIE10 will require a polyfill for `Object.assign`:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n## Versioning\n\nVersioning follows [Semver](http://semver.org).\n\n## License\n\nMIT\n","funding_links":["https://www.buymeacoffee.com/rikschennink","https://www.buymeacoffee.com/rikschennink/"],"categories":["JavaScript","javascript","Utilities","Framework agnostic packages"],"sub_categories":["React Components","Typography"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frikschennink%2Ffitty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frikschennink%2Ffitty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frikschennink%2Ffitty/lists"}