UNPKG

@moohng/postcss-px2vw

Version:

A CSS post-processor that converts px to vw and fallback rem.

54 lines (48 loc) 1.83 kB
module.exports = (options = {}) => { const opts = { viewportWidth: 750, unitPrecision: 5, rootValue: 75, minPixelValue: 1, ...options, }; const pxRegex = /"[^"]+"|'[^']+'|url\([^\)]+\)|(\d*\.?\d+)px/ig; return { postcssPlugin: 'postcss-px2vw', Declaration (decl) { if (decl.value.indexOf('px') === -1) return; const value = decl.value; if (opts.viewportWidth) { const viewportWidth = typeof opts.viewportWidth === 'function' ? opts.viewportWidth(opts, decl, decl.source.input.file) : opts.viewportWidth const pxReplaceForVw = createPxReplace(viewportWidth / 100, opts.minPixelValue, opts.unitPrecision, 'vw'); decl.value = value.replace(pxRegex, pxReplaceForVw); } if (opts.rootValue) { const rootValue = typeof opts.rootValue === 'function' ? opts.rootValue(opts, decl, decl.source.input.file) : opts.rootValue const pxReplaceForRem = createPxReplace(rootValue, opts.minPixelValue, opts.unitPrecision, 'rem'); if (opts.viewportWidth) { var newValue = value.replace(pxRegex, pxReplaceForRem); if (newValue !== value) { decl.cloneBefore({ value: newValue }); } } else { decl.value = value.replace(pxRegex, pxReplaceForRem); } } }, }; }; function createPxReplace(perRatio, minPixelValue, unitPrecision, unit) { return function (m, $1) { if (!$1) return m; const pixels = parseFloat($1); if (pixels <= minPixelValue) return m; return toFixed((pixels / perRatio), unitPrecision) + unit; }; } function toFixed(number, precision) { const multiplier = 10 ** (precision + 1); const wholeNumber = Math.floor(number * multiplier); return Math.round(wholeNumber / 10) * 10 / multiplier; } module.exports.postcss = true;