Giter Site home page Giter Site logo

postcss-pxtorem's Introduction

postcss-pxtorem NPM version

A plugin for PostCSS that generates rem units from pixel units.

Install

$ npm install postcss postcss-pxtorem --save-dev

Usage

Pixels are the easiest unit to use (opinion). The only issue with them is that they don't let browsers change the default font size of 16. This script converts every px value to a rem from the properties you choose to allow the browser to set the font size.

Input/Output

With the default settings, only font related properties are targeted.

// input
h1 {
    margin: 0 0 20px;
    font-size: 32px;
    line-height: 1.2;
    letter-spacing: 1px;
}

// output
h1 {
    margin: 0 0 20px;
    font-size: 2rem;
    line-height: 1.2;
    letter-spacing: 0.0625rem;
}

Example

var fs = require('fs');
var postcss = require('postcss');
var pxtorem = require('postcss-pxtorem');
var css = fs.readFileSync('main.css', 'utf8');
var options = {
    replace: false
};
var processedCss = postcss(pxtorem(options)).process(css).css;

fs.writeFile('main-rem.css', processedCss, function (err) {
  if (err) {
    throw err;
  }
  console.log('Rem file written.');
});

options

Type: Object | Null
Default:

{
    rootValue: 16,
    unitPrecision: 5,
    propList: ['font', 'font-size', 'line-height', 'letter-spacing', 'word-spacing'],
    selectorBlackList: [],
    replace: true,
    mediaQuery: false,
    minPixelValue: 0,
    exclude: /node_modules/i
}
  • rootValue (Number | Function) Represents the root element font size or returns the root element font size based on the input parameter
  • unitPrecision (Number) The decimal numbers to allow the REM units to grow to.
  • propList (Array) The properties that can change from px to rem.
    • Values need to be exact matches.
    • Use wildcard * to enable all properties. Example: ['*']
    • Use * at the start or end of a word. (['*position*'] will match background-position-y)
    • Use ! to not match a property. Example: ['*', '!letter-spacing']
    • Combine the "not" prefix with the other prefixes. Example: ['*', '!font*']
  • selectorBlackList (Array) The selectors to ignore and leave as px.
    • If value is string, it checks to see if selector contains the string.
      • ['body'] will match .body-class
    • If value is regexp, it checks to see if the selector matches the regexp.
      • [/^body$/] will match body but not .body
  • replace (Boolean) Replaces rules containing rems instead of adding fallbacks.
  • mediaQuery (Boolean) Allow px to be converted in media queries.
  • minPixelValue (Number) Set the minimum pixel value to replace.
  • exclude (String, Regexp, Function) The file path to ignore and leave as px.
    • If value is string, it checks to see if file path contains the string.
      • 'exclude' will match \project\postcss-pxtorem\exclude\path
    • If value is regexp, it checks to see if file path matches the regexp.
      • /exclude/i will match \project\postcss-pxtorem\exclude\path
    • If value is function, you can use exclude function to return a true and the file will be ignored.
      • the callback will pass the file path as a parameter, it should returns a Boolean result.
      • function (file) { return file.indexOf('exclude') !== -1; }
  • unit (String) Set the default unit to convert, default is px.

Use with gulp-postcss and autoprefixer

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var pxtorem = require('postcss-pxtorem');

gulp.task('css', function () {

    var processors = [
        autoprefixer({
            browsers: 'last 1 version'
        }),
        pxtorem({
            replace: false
        })
    ];

    return gulp.src(['build/css/**/*.css'])
        .pipe(postcss(processors))
        .pipe(gulp.dest('build/css'));
});

A message about ignoring properties

Currently, the easiest way to have a single property ignored is to use a capital in the pixel unit declaration.

// `px` is converted to `rem`
.convert {
    font-size: 16px; // converted to 1rem
}

// `Px` or `PX` is ignored by `postcss-pxtorem` but still accepted by browsers
.ignore {
    border: 1Px solid; // ignored
    border-width: 2PX; // ignored
}

postcss-pxtorem's People

Contributors

cowills avatar cuth avatar endday avatar kud avatar michaeldietiker avatar rileyjshaw avatar spacedawwwg avatar yutingzhao1991 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

postcss-pxtorem's Issues

Is include mode possible

I know pxtorem's ways to ignore px we don't wanna translate into rem: using PX and configure it with exclude and selectorBlackList option.
But in my case(also in some other guy's case), i just want a small part of my project being translated into rem, using these ways will be extremely time consuming and when i run npm run serve(i am using vue),the time spent is apparently prolonged, is it possible that we can enable an include or selectorWhiteList mode?
I haven't read about the source code, maybe i can pull a request.

selector_black_list - regex match, not a strict one.

strings from selector_black_list are checked against selector itself using match for regex which produces not strict comparison. So in attemp to leave font-size declared on body unchanged, selector like .post_body will also be matched.
I suppose it is worth mentioning in readme, that this values are, in fact, producing non-strict indexOf-like comparison, or changing to strict comparison in source?

Solution for responsive background images

.some-picture {
    display: block;
    width: 20px;
    height: 20px;
    background: url('path/to/img.jpg') no-repeat center;
}

It will be compiled to:

.some-picture {
    display: block;
    width: 2rem;
    height: 2rem;
    background: url('path/to/img.jpg') no-repeat center;
}

and here is a problem with bg image

I propose to add an option like this:

pxtorem({
    root_value: 10,
    responsive_bg: true
})

and it will be compile to:

.some-picture {
    display: block;
    width: 2rem;
    height: 2rem;
    background: url('path/to/img.jpg') no-repeat center;
    background-size: (get img width in px / root_value)rem
}

If background-size css prop is undefined, pxtorem plugin will add this css prop

Consider blacklisting the HTML element?

Hey,

We've encountered an issue with this task when we set our html element to have a base font-size (of 18px for example) - for the rest of the styles to inherit from.

The task runs on the html's CSS and converts its value to a rem unit based against the rootValue in the config (18), changing it to 1rem.

This then causes it to be 16px (browser default) and the other elements on the page that have been converted to rem units are sized relatively according to a 16px base size instead of the 18px that we want.

Is there a way to exclude the html root element - could that be a best practise going forward?

Or is there any advice you can give us if we are using this wrong? Currently we're ignoring the html element's CSS by putting px value in capitals as you suggest: html { font-size: 18PX;}.

Anything I can do to help let me know,
thanks.

PX/Px being converted to rem when inside calc()

I need a pixel value to remain a pixel value inside of a calc function. I have made sure that the value is -17.4359PX before the postcss-pxtorem processes. After processing, this is converted to -1.08974rem.

Is there a specific reason by the plugin ignores PX/Px inside of a calc()?

Is there a workaround?

Pixel values in custom property names are converting too

In our codebase we have some custom properties like --rem-16px: 1rem

If I run postcss-pxtorem with these then these variables are renamed like --rem-1rem: 1rem but I didn't expect that the property name would be replaced. Not sure if it's a big issue because I plan to remove those and replace with this plugin but still maybe there is a way to prevent that or is that the desired behavior?

2:14	⚠  variable '--rem-1rem' is undefined and used without a fallback [postcss-custom-properties]
45:14	⚠  variable '--rem-1rem' is undefined and used without a fallback [postcss-custom-properties]
48:14	⚠  variable '--rem-2rem' is undefined and used without a fallback [postcss-custom-properties]

1px width elements as .0625rem disappear in some browers

QUESTION

1px widths (borders etc) specced in rem can disappear completely in some browsers (Chrome) when users zoom out. This isn't a bug with pxtorem obviously, but some possible strategies for dealing with it might be:

  • add prop_black_list for prop_black_list: ['border', 'border-width'] type use
  • add a min-size to convert (going to mess with things like letter-spacing, so bad idea)

I realise that there is already a selector_black_list but that's not quite what I want.


Honestly, if this is a just me issue, then I might be best writing a postcss module to run afterwards and convert back any .0625rem (1px) values to px.

Plugin doesn't work with @font-face

This great plugin doesn't work with the @font-face declaration.

My config is an empty array in prop_white_list.
selector_black_list doesn't filter the font-face.

Here is the error:

TypeError: Cannot call method 'match' of undefined
    at node_modules/postcss-pxtorem/index.js:72:25
    at Array.some (native)
    at blacklistedSelector (node_modules/postcss-pxtorem/index.js:71:22)

Greetings

Support for css module `@value`?

Hi, thanks for this aweseome plugin!
I'm currently using css modules and found that @value rules are not being transformed, for example

@value foo: 16px;
.bar {
  font-size: foo;
  line-height: 32px;
}

is transformed to

.bar {
  font-size: 16px;
  line-height: 2em;
}

where the @value variable is missed out. It would be great if @value is supported.

option to skip border: 1px

hello,

border with 1px tend to disappear using rem for responsive. I would like an option to avoid converting border values if the value is 1px. Something like border-safe ?

I made a quick change locally for one project, it seems to work but i'm sure it can be better... line 33:

if(decl.prop === 'border' || decl.prop === 'border-top' || decl.prop === 'border-bottom' || decl.prop === 'border-left' || decl.prop === 'border-right')
{
    if(value.indexOf('1px') >= 0 && value.indexOf('11px') == -1)
    {
        return;
    }
}

Avoid needing to declare each side of the box model

Great plugin, very useful.

However with properties like margin, padding etc it would be great to use just margin and it cover off margin-top, margin-bottom etc without declaring them all. It gets quite verbose when you add padding in there too.

ignore file

i want to ignore some file

example

/* pxtorem-ignore */
// then the file will be ignore
...

.div1 {
   width: 100px; // ignored
}
.div2 {
  height: 100px; // ignored
}

...

what can i do?

Media queries

I develop version for smartphones for some project and use this plugin.
All styles compiles from pixels to rems, only base css rules are left in px, like this:

html { // for desktop
    font-size: 14px;
}
@media (max-width: 500px) { // for phones
    html {
        font-size: 11px;
    }
}

Generally it is good, fast and simple solution to make mobile version.
But for some ui blocks I use media queries overrides for small screen. And I want to keep this values in pixels. It will be good to have ability to ignore css rules in media queries (not there – @media (max-width: 500px) )

Space missing after font-size: when not replacing

When the option replace: false is used - there is a space missing after the colon.

font-size: 18px;
font-size:1.8rem;

Suggestion: replace line 32 of index.js with

    var pxReplace = createPxReplace(opts.rootValue, opts.unitPrecision, opts.minPixelValue, opts.replace);

replace function on line 89 with this:

function createPxReplace(rootValue, unitPrecision, minPixelValue, pxReplace) {
    return function(m, $1) {
        if (!$1) return m;
        var pixels = parseFloat($1);
        if (pixels < minPixelValue) return m;
        var fixedVal = toFixed((pixels / rootValue), unitPrecision);
        if (pxReplace) {
            return (fixedVal === 0) ? '0' : fixedVal + 'rem';
        } else {
            return (fixedVal === 0) ? '0' : ' ' + fixedVal + 'rem';
        }
    };
}

Better solution to ignore properties

I appreciate the mention of a workaround in the docs but I wonder if something like this would be a better pattern, similar to the behavior used by eslint (i.e. with a comment):

Input:

h1 {
  font-size: 48px;
}
h2 {
  /* pxtorem-disable-next-line */
  font-size: 24px;
}

Output:

h1 {
  font-size: 3rem;
}
h2 {
  font-size: 24px;
}

I haven't looked at the source yet to see what kind of lift this would be, but would you accept a PR with this kind of solution?

Cheers, and thanks for the great library
Jeremy

Add ability to use font size from root element

Right now, you have to explicitly declare root font size value as argument for plugin. It would be good if plugin could read input CSS and read html/root element font size value and use that as starting point. If there is no value, use current (and browser) default, 16px.

Is the plugin abandoned?

Hi, I see some pending pull requests which would be nice to merge ( including postcss 8 that I require ). If you would like to share the burden I am happy to help, test the stuff, merge what's needed and add some easy improvements.

All files are excluded when exclude function contains ||

When exclude option is a function and it has operator ||, all files will be ignored.

For example, the following config will ignore all files:

require('postcss-pxtorem')({
    exclude: function exclude(file) {
      return /node_modules/i.test(file) || false;
    }
})

While the following code works properly:

require('postcss-pxtorem')({
    exclude: function exclude(file) {
      return /node_modules/i.test(file);
    }
})

declare certain width as maximum base width

That's not a big, just a question...
Is it possible to declare a maximum screensize, everything is calculated for?
Like if screen is bigger than 1200px, use 1200 as value for calculation everything into rem

does't work with webpack3

{ loader: 'postcss-loader', options: { plugins: loader => [ precss, autoprefixer, pxtorem({ rootValue: 100, propWhiteList: [], }) ] } }

It does't work. There is no error.

it doesn't work when i use v-bind of Vuejs to get the px number

just like below in Vue.js, it doesn't work. The 'left' and 'top' can't change to rem.

<ul
    v-show="visible"
   :style="{left: contextMenuLeft + 'px', top: contextMenuTop + 'px'}"
   class="contextmenu"
 >
   <li v-for="(item, key) of menuList" @click="handleTagsOption(key)" :key="key">{{item}}</li>
 </ul>

Error installing with Gulp

I'm trying to instal this package with gulp but I keep getting the following error:

npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "postcss-pxtorem" "--save-dev"
npm ERR! node v7.1.0
npm ERR! npm v3.10.9
npm ERR! file /Users/Tiago/Desktop/hyperion/package.json
npm ERR! code EJSONPARSE

npm ERR! Failed to parse json
npm ERR! Trailing comma in object at 15:3
npm ERR! }
npm ERR! ^
npm ERR! File: /Users/Tiago/Desktop/hyperion/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
npm ERR!
npm ERR! This is not a bug in npm.
npm ERR! Tell the package author to fix their package.json file. JSON.parse

npm ERR! Please include the following file with any support request:
npm ERR! /Users/Tiago/Desktop/hyperion/npm-debug.log

Any ideas of what I'm might be doing wrong?
Thanks.

Add ability to black list selectors

Would be nice to add the ability to black list selectors. A use case would be :before and :after in IE9, IE10 do not like using rem's in line-height

Being able to black list psuedo elements would allow a work around.

PX doesn't work with cssnano and postcss-calc

This is the error I get when using PX to ignore a property:

Message:
    Lexical error on line 1: Unrecognized text.

  Erroneous area:
1: 1PX + 0.3em
^..^
Details:
    hash: [object Object]
    postcssNode: padding:calc(1PX + 0.3em)
    fileName: /sass/styles.css
    domainEmitter: [object Object]
    domain: [object Object]
    domainThrown: false

Stack:
JisonLexerError: Lexical error on line 1: Unrecognized text.

  Erroneous area:
1: 1PX + 0.3em
^..^
    at /sass/styles.css:427:7
    at Object.parseError (/node_modules/postcss-calc/dist/parser.js:1164:15)
    at Object.lexer_parseError [as parseError] (/node_modules/postcss-calc/dist/parser.js:2297:44)
    at Object.lexer_next [as next] (/node_modules/postcss-calc/dist/parser.js:3292:22)
    at Object.lexer_fastLex [as fastLex] (/node_modules/postcss-calc/dist/parser.js:3367:18)
    at fastLex (/node_modules/postcss-calc/dist/parser.js:1567:27)
    at Parser.parse (/node_modules/postcss-calc/dist/parser.js:1641:30)
    at /node_modules/postcss-calc/dist/lib/transform.js:30:30
    at walk (/node_modules/postcss-value-parser/lib/walk.js:19:7)
    at ValueParser.walk (/node_modules/postcss-value-parser/lib/index.js:18:3)
    at transformValue (/node_modules/postcss-calc/dist/lib/transform.js:24:50)
    at _default (/node_modules/postcss-calc/dist/lib/transform.js:59:100)
    at /node_modules/postcss-calc/dist/index.js:25:51
    at /node_modules/postcss/lib/container.js:135:18
    at Rule.each (/node_modules/postcss/lib/container.js:101:16)
    at Rule.walk (/node_modules/postcss/lib/container.js:131:17)
    at /node_modules/postcss/lib/container.js:148:24```

pxtorem was not worked in .scss file which has @import .scss file

When I used pxtorem, It was worked in pure scss files, but it was not worked when the scss file import other scss files.How to fix it?
There is the webpack.config.js:

loaders: [
{
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader!postcss')
 }],
postcss: [
        autoprefixer({browsers: ['last 5 versions']}),
        pxtorem({rootValue: 100, propWhiteList: []})
]

replace option is not working as expected

I have set up postcss-cli v3.2.0 using the postcss.config.js as instructed here

package.json

My npm script is:

"postbuild:css": "postcss dist/assets/stylesheets/*.css -d dist/assets/stylesheets/ --parser sugarss

postcss.config.js

This is in my root directory

module.exports = (ctx) => ({
  parser: ctx.file.extname === '.sss' ? ctx.options.parser : false,
  map: ctx.options.map,
  plugins: {
    'postcss-pxtorem': {
      rootValue: 16,
      unitPrecision: 5,
      selectorBlackList: [],
      replace: false,
      mediaQuery: false,
      minPixelValue: 0,
      propWhiteList: [
        'font',
        'font-size',
        'line-height',
        'letter-spacing',
        'padding',
        'padding-top',
        'padding-right',
        'padding-bottom',
        'padding-left',
        'margin',
        'margin-top',
        'margin-right',
        'margin-bottom',
        'margin-left',
        'width',
        'height',
        'border-radius',
        'letter-spacing'
      ]
    },
    autoprefixer: {
      browsers: [
        '> 2%',
        'last 2 versions',
        'ie >= 7'
      ]
    }
  }
})

When running the above script against my CSS I would expect to see:

.highlight{
  font-size: 24px;
  font-size: 1.5rem
}

But with the option replaced set to false I currently see:

.highlight{
  font-size:1.5rem
}

Of Note

a) The above config is definitely being picked up because changing the contents of the propWhiteList option works as expected and is reflected in the outputted css file.

b) setting up a node script as described here with the option replaced set to false works as expected.

c) I am not sure this is connected but I could not get the postcss.config.js to be picked up or get it to work by any of the methods described in the migration guide. The only way it has worked is as described above via this issue comment from @michael-ciniawsky potentially this is causing an issue here with the replaced option not being respected?

need limit html font-size maximum is A value

The user should be given a fixed root element size, or maximum, so that on a very large screen device the editor can edit webpage in a non-full-screen format, which can also be used to display web pages

Support for custom properties

Is it possible to transform values of custom properties as well? For example to switch them on like so:

{
    propList: [
        'font',
        'font-size',
        'line-height',
        'letter-spacing',
        '--'
    ]
}

Use PostCSS 4.1 API

PostCSS Plugin Guidelines are mandatory right now. Because all of rules are about ecosystem health.

propWhiteList is not working for me

Hello,

My issue is that pxtorem converts only font-related properties to rem, as stated in the docs. I am using the propWhiteList to add for example margin and padding, but I get px values.

I am using a postcss.json file for my config:

{
  "use": ["postcss-import",
        "autoprefixer",
        "postcss-pxtorem",
        "postcss-simple-vars",
        "postcss-extend",
        "postcss-nested",
        "postcss-flexbugs-fixes"
     ],
  "css-import": {
    "from": "src/css/"
  },
    "autoprefixer": {
      "browsers": "> 5%"
  },
    "pxtorem": {
        "rootValue": 16,
        "unitPrecision": 5,
        "propWhiteList": ["margin", "padding"],
        "selectorBlackList": [],
        "replace": true,
        "mediaQuery": true
    }
}

Any ideas?

Media queries should be in em not rem

Since all media queries level one units are relative to the root element, setting the media queries in rems instead of ems, is useless and reduces the support for media queries in browsers like safari 5 (which do support rems but not in media queries)

mediaQuery is not working for me

hello,
the option "mediaQuery" is not working in my css code, i set it to false but the style in media query is still being converted.Here is my setting:

{
      rootValue: 100,
      unitPrecision: 5,
      propList: ['*'],
      selectorBlackList: [],
      replace: true,
      mediaQuery: false,
      minPixelValue: 5
    }

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.