
7 changed files with 187 additions and 1 deletions
-
2LICENSE
-
7README.md
-
17example/index.js
-
23example/main-viewport.css
-
23example/main.css
-
85index.js
-
31package.json
@ -0,0 +1,7 @@ |
|||
# postcss-px-to-viewport [](http://badge.fury.io/js/postcss-px-to-viewport) |
|||
|
|||
A plugin for [PostCSS](https://github.com/ai/postcss) that generates viewport units (vw, vh, vmin, vmax) from pixel units. |
|||
|
|||
## Usage |
|||
|
|||
TODO... |
@ -0,0 +1,17 @@ |
|||
'use strict'; |
|||
|
|||
var fs = require('fs'); |
|||
var postcss = require('postcss'); |
|||
var pxToViewport = require('..'); |
|||
var css = fs.readFileSync('main.css', 'utf8'); |
|||
var options = { |
|||
replace: false |
|||
}; |
|||
var processedCss = postcss(pxToViewport(options)).process(css).css; |
|||
|
|||
fs.writeFile('main-viewport.css', processedCss, function (err) { |
|||
if (err) { |
|||
throw err; |
|||
} |
|||
console.log('File with viewport units written.'); |
|||
}); |
@ -0,0 +1,23 @@ |
|||
.class { |
|||
margin: -3.125vw .5vh; |
|||
padding: 5vmin 2.96875vw; |
|||
border: 0.9375vw solid black; |
|||
font-size: 4.375vw; |
|||
line-height: 6.25vw; |
|||
} |
|||
.class2 { |
|||
font-size: 6.25vw; |
|||
line-height: 9.375vw; |
|||
} |
|||
@media (min-width: 750px) { |
|||
.class3 { |
|||
font-size: 5vw; |
|||
line-height: 6.875vw; |
|||
} |
|||
} |
|||
|
|||
/* |
|||
.class { |
|||
font-size: 16px; |
|||
} |
|||
*/ |
@ -0,0 +1,23 @@ |
|||
.class { |
|||
margin: -10px .5vh; |
|||
padding: 5vmin 9.5px; |
|||
border: 3px solid black; |
|||
font-size: 14px; |
|||
line-height: 20px; |
|||
} |
|||
.class2 { |
|||
font-size: 20px; |
|||
line-height: 30px; |
|||
} |
|||
@media (min-width: 750px) { |
|||
.class3 { |
|||
font-size: 16px; |
|||
line-height: 22px; |
|||
} |
|||
} |
|||
|
|||
/* |
|||
.class { |
|||
font-size: 16px; |
|||
} |
|||
*/ |
@ -0,0 +1,85 @@ |
|||
'use strict'; |
|||
|
|||
var postcss = require('postcss'); |
|||
var objectAssign = require('object-assign'); |
|||
|
|||
// excluding regex trick: http://www.rexegg.com/regex-best-trick.html
|
|||
// Not anything inside double quotes
|
|||
// Not anything inside single quotes
|
|||
// Not anything inside url()
|
|||
// Any digit followed by px
|
|||
// !singlequotes|!doublequotes|!url()|pixelunit
|
|||
var pxRegex = /"[^"]+"|'[^']+'|url\([^\)]+\)|(\d*\.?\d+)px/ig; |
|||
|
|||
var defaults = { |
|||
viewportWidth: 320, |
|||
viewportHeight: 568, |
|||
unitPrecision: 5, |
|||
viewportUnit: 'vw', |
|||
selectorBlackList: [], |
|||
//propWhiteList: ['font', 'font-size', 'line-height', 'letter-spacing'],
|
|||
replace: true, |
|||
mediaQuery: false |
|||
}; |
|||
|
|||
module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|||
|
|||
var opts = objectAssign({}, defaults, options); |
|||
var pxReplace = createPxReplace(opts.viewportWidth, opts.unitPrecision, opts.viewportUnit); |
|||
|
|||
return function (css) { |
|||
|
|||
css.walkDecls(function (decl, i) { |
|||
// This should be the fastest test and will remove most declarations
|
|||
if (decl.value.indexOf('px') === -1) return; |
|||
|
|||
// if (opts.propWhiteList.length && opts.propWhiteList.indexOf(decl.prop) === -1) return;
|
|||
|
|||
if (blacklistedSelector(opts.selectorBlackList, decl.parent.selector)) return; |
|||
|
|||
//var value = decl.value.replace(pxRegex, pxReplace);
|
|||
//
|
|||
////// if viewport unit already exists, do not replace
|
|||
////if (declarationExists(decl.parent, decl.prop, value)) return;
|
|||
//
|
|||
//decl.value = value;
|
|||
decl.value = decl.value.replace(pxRegex, pxReplace); |
|||
}); |
|||
|
|||
if (opts.mediaQuery) { |
|||
css.walkAtRules('media', function (rule) { |
|||
if (rule.params.indexOf('px') === -1) return; |
|||
rule.params = rule.params.replace(pxRegex, pxReplace); |
|||
}); |
|||
} |
|||
|
|||
}; |
|||
}); |
|||
|
|||
function createPxReplace(viewportSize, unitPrecision, viewportUnit) { |
|||
return function (m, $1) { |
|||
if (!$1) return m; |
|||
var pixels = parseFloat($1); |
|||
return toFixed((pixels / viewportSize * 100), unitPrecision) + viewportUnit; |
|||
}; |
|||
} |
|||
|
|||
function toFixed(number, precision) { |
|||
var multiplier = Math.pow(10, precision + 1), |
|||
wholeNumber = Math.floor(number * multiplier); |
|||
return Math.round(wholeNumber / 10) * 10 / multiplier; |
|||
} |
|||
|
|||
//function declarationExists(decls, prop, value) {
|
|||
// return decls.some(function (decl) {
|
|||
// return (decl.prop === prop && decl.value === value);
|
|||
// });
|
|||
//}
|
|||
|
|||
function blacklistedSelector(blacklist, selector) { |
|||
if (typeof selector !== 'string') return; |
|||
return blacklist.some(function (regex) { |
|||
if (typeof regex === 'string') return selector.indexOf(regex) !== -1; |
|||
return selector.match(regex); |
|||
}); |
|||
} |
@ -0,0 +1,31 @@ |
|||
{ |
|||
"name": "postcss-px-to-viewport", |
|||
"description": "A CSS post-processor that converts px to viewport units (vw, vh, vmin, vmax).", |
|||
"version": "0.0.1", |
|||
"author": "Dmitry Karpunin <koderfunk@gmail.com>", |
|||
"license": "MIT", |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "git@github.com:KODerFunk/postcss-px-to-viewport.git" |
|||
}, |
|||
"bugs": "https://github.com/KODerFunk/postcss-px-to-viewport/issues", |
|||
"homepage": "https://github.com/KODerFunk/postcss-px-to-viewport", |
|||
"main": "index.js", |
|||
"keywords": [ |
|||
"css", |
|||
"units", |
|||
"pixel", |
|||
"px", |
|||
"viewport", |
|||
"vw", |
|||
"vh", |
|||
"vmin", |
|||
"vmax", |
|||
"postcss", |
|||
"postcss-plugin" |
|||
], |
|||
"dependencies": { |
|||
"object-assign": "^4.0.1", |
|||
"postcss": "^5.0.2" |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue