
Unitflip is a tiny JavaScript utility that transforms CSS units precisely and reliably. It allows you to convert between px, rem, em, percentage, viewport units, and physical units with a single JS call.
This library solves common unit conversion challenges in web development. The conversion system handles relative units like rem and em with contextual awareness of root and base font sizes. For viewport-based calculations, it automatically detects screen dimensions to ensure accurate vh/vw conversions.
The unit conversion covers the full range of CSS length units – from pixels and percentages to physical measurements like inches and millimeters. Each conversion uses standardized ratios and formulas based on the CSS specification.
For projects requiring exact control over unit precision, Unitflip supports optional decimal place rounding. This prevents floating point errors while maintaining mathematical accuracy in the conversions.
How to use it:
1. Install & download with NPM.
# NPM $ npm install unitflip
2. Import the library using your preferred module system:
// ES6 Import
import unitFlip from 'unitflip';
// CommonJS
const unitFlip = require('unitflip');
// Browser via CDN
<script src="https://unpkg.com/unitflip@latest/dist/index.umd.js"></script>
// OR
<script type="module">
import unitFlip from 'https://unpkg.com/unitflip@latest/dist/index.esm.mjs'
</script>3. The core of Unitflip is the unitFlip function. It converts a value from a source CSS unit to a target CSS unit. The function returns the converted value in the target unit. The unitFlip function accepts the following parameters:
- sourceUnit: A string specifying the original CSS unit of the value. Accepted values include: “px”, “rem”, “em”, “%”, “vw”, “vh”, “vmin”, “vmax”, “ch”, “cm”, “in”, “mm”, “pt”, “pc”, “q”, “rlh”.
- targetUnit: A string specifying the CSS unit you want to convert to. Accepts the same values as sourceUnit.
- precision (optional): Indicates the number of decimal places for the converted value. If you provide a number, the result will be rounded to that many decimal places. The default is false, which returns the full precision.
- options (optional): An object containing additional parameters for the conversion.
unitFlip(value, sourceUnit, targetUnit, precision = false, options)
4. All available options to customize the conversion process:
- rootFontSize (number, default: 16): Sets the root font size in pixels, used for rem conversions. If your website has a different base font size, you should specify it here for accurate rem calculations.
- baseFontSize (number, default: 16): Sets the base font size in pixels, used for em conversions. This is relevant when converting to or from em units, as they are relative to the font size of the parent element.
- chFontSize (number, default: calculated): Sets the font size of the character “0” in pixels, used for ch conversions. Unitflip attempts to determine this automatically, but you can override it if necessary.
- viewPortWidth (number, default: current viewport width): Sets the width of the viewport in pixels. This is used for conversions involving viewport-percentage units (vw, vmin, vmax).
- viewPortHeight (number, default: current viewport height): Sets the height of the viewport in pixels, used for vh, vmin, and vmax conversions.
- minViewPortSize (number, default: the smaller of viewPortWidth and viewPortHeight): Sets the minimum viewport dimension, used for vmin conversions.
- maxViewPortSize (number, default: the larger of viewPortWidth and viewPortHeight): Sets the maximum viewport dimension, used for vmax conversions.
// => 2.5
console.log(unitFlip(24, 'px', 'vw', 2, { viewPortWidth:960 }));How It Works
Unitflip performs CSS unit conversions by using predefined conversion factors and, where necessary, contextual information like viewport dimensions and font sizes.
To determine viewport-related units, Unitflip uses the getViewPortDimension function:
const isWindowValid =
typeof window !== "undefined" &&
typeof window.innerWidth === "number" &&
typeof window.innerHeight === "number";
if (!isWindowValid) return 0;
return dimension === "width" ? window.innerWidth : window.innerHeight;
};This function checks if the window object is available (indicating a browser environment) and returns the inner width or height of the viewport in pixels. If the window object is not valid, it defaults to 0.
For conversions involving the ch unit, which is based on the width of the “0” character, Unitflip uses the getChWidth function:
const getChWidth = () => {
const isDocumentValid =
typeof document !== "undefined" &&
typeof document.createElement === "function" &&
typeof window !== "undefined";
if (!isDocumentValid) return 0;
const letterElement = document.createElement("span");
letterElement.style.visibility = "hidden";
letterElement.style.position = "absolute";
letterElement.style.whiteSpace = "nowrap";
letterElement.textContent = "0";
document.body.appendChild(letterElement);
const chWidth = letterElement.getBoundingClientRect().width;
document.body.removeChild(letterElement);
return chWidth;
};This function creates a temporary span element, sets its content to “0”, and measures its width using getBoundingClientRect(). This provides the current width of the “0” character in pixels. The temporary element is then removed from the DOM.
The core conversion logic resides within the conversion object. This object contains nested objects, where the keys represent CSS units. Each unit object contains functions for converting from that unit to other units. For example, the px object contains a function to convert pixels to rem:
px: {
rem: (value, props) => value / props.rootFontSize,
// ... other conversions from px
},This function divides the pixel value by the rootFontSize (obtained from the options or the default value) to calculate the equivalent rem value. Similar functions exist for all supported unit conversions.
The main unitFlip function then orchestrates the conversion:
const getChWidth = () => {
const isDocumentValid =
typeof document !== "undefined" &&
typeof document.createElement === "function" &&
typeof window !== "undefined";
if (!isDocumentValid) return 0;
const letterElement = document.createElement("span");
letterElement.style.visibility = "hidden";
letterElement.style.position = "absolute";
letterElement.style.whiteSpace = "nowrap";
letterElement.textContent = "0";
document.body.appendChild(letterElement);
const chWidth = letterElement.getBoundingClientRect().width;
document.body.removeChild(letterElement);
return chWidth;
};It first gathers the necessary properties, including default and user-provided options. It then checks if the requested sourceUnit and targetUnit are valid and supported. If so, it retrieves the appropriate conversion function from the conversion object and executes it.
Finally, if a precision value is provided, it rounds the result to the specified number of decimal places.
Changelog:
v1.4.0 (01/06/205)
- add the conversion for rlh unit.







