GithubHelp home page GithubHelp logo

less-plugin-functions's Introduction

less-plugin-functions

Write genuine Less functions in Less itself.

npm version dependencies dev dependencies

This experimental "proof-of-concept" plugin extends Less with a possibility to define custom functions directly in Less itself and use them just like regular built-in functions.

Define foo function:

.function {
    .foo(@x) {
        return: @x * 2;
    }
}

Use it:

div {
    width: foo(21em); // -> 42em
}

Installation

npm install -g less-plugin-functions

Usage

lessc --functions file.less

For more details about using plugins with the command line Less compiler see the corresponding section in the Less documentation.

Using with common Less tools:

For more details on a programmatic Less plugin usage see Using a plugin in code.

Feature Details

Custom functions recognizable by this plugin are defined as plain Less mixins having either .function- prefix or being immediate descendant of a .function namespace. For example the following two snippets create the same function named bar.

Using namespace:

.function {
    .bar() {
        return: red;
    }
}

Using prefix:

.function-bar() {
    return: red;
}

The defined function can be used same way and anywhere a CSS/Less function can:

div {
    background-color: bar();    // red
    color: lighten(bar(), 13%); // #ff4242
    // etc.
}

Don't miss that the defined function name is bar, without any prefix or a dot.

Additionally note that the function definitions should use only lowercase names (e.g. .function-bar not .function-Bar). Less function names are case-insensitive so for both bar() and Bar() call statements the compiler will look only for the lowercase bar definition (for more details see #1).

Supported functionality

Since custom functions are defined as regular Less mixins, they inherit most of standard mixin behaviour and functionality. In particular:

Return Value

Function return value is specified via return property.

.function-foo() {
    return: "Hello, I'm the foo return value.";
}

Notice that since the return statement is just a regular CSS property it does not "return immediately", and any code after return is still in effect. Same way all default Less behavior of CSS properties applies to the return property as well.

E.g. it can be overridden:

.function-bar() {
    return: 1;
    return: 2;
    // function returns 2
}

merged:

.function-baz() {
    return+: 1;
    return+: 2;
    // function returns 1, 2
}

etc.

Overriding CSS and built-in Less functions

Custom function definitions override CSS or built-in Less functions of the same name (certain performance critical functions are not overridable by default though, see -a option below for more details). That is, you can "replace"/"extend" any Less or even CSS function by your own implementation.

For example:

// override `calc` globally:
.function-calc(@expr) {
    return: tired, won΄t calculate;
}

div {
    width: calc(50% - 20px);
    color: hsl(0, 50%, 25%);
}

span {
    color: hsl(0, 50%, 25%);

    // override `hsl` locally:
    .function-hsl(@h, @s, @l) {
        return: hsla(@h, @l, @s, 1); // happy debugging!
    }
}

CSS result:

div {
    width: tired, won΄t calculate;
    color: #602020;
}
span {
    color: #9f6060;
}

More examples

See included tests for more advanced examples. Additionally see a few examples on using this plugin in conjunction with list-plugin-lists.

Options

--always-override / alwaysOverride

Always override native CSS or Less functions

Shorthand: -a. For performance reasons (mixin lookup is a costly process) certain CSS and built-in Less functions are marked as not overridable by the custom functions. Setting this option allows you to override any. Note however, this can significantly increase compilation time even if you don't override anything (for a typical Less framework/codebase this option may result in about 20% performance hit).

The list of functions not overridable w/o -a can be found here.

--globals-only / globalsOnly

Use only global scope definitions

Shorthand: -g. By default the plugin searches for a possible function definition(s) starting from the current scope upwards (i.e. standard Less scoping). If your Less code is heavy on using too deep nesting and/or too many local mixins, such scope-aware lookup may negatively affect compilation time. This option allows you to restrict the search to a functions explicitly defined in the global scope.

For an average Less source code the performance difference is insignificant (unless -a option is also set), so normally you don't need this option (consider it as "experimental") unless you're hunting for every single bit of compilation time improvement.

Implementation and Compatibility

To deliver its functionality this plugin has to use certain hackish tricks and methods a standard Less plugin is not supposed to use (simply because a standard Less plugin is not supposed to provide such functionality at all). This makes the plugin to be quite vulnerable to possible compiler internals changes, thus it's more tied to a particular Less version than a typical plugin would be.

Currently supported Less versions are 2.4.0 or higher.

Future

Because of the implementation details and sightly confusing function definition syntax, this functionality/feature ideally should be moved into the Less core (not necessarily using the same syntax).

See corresponding feature request and related discussion at #538. Please, do not hesitate to put your +1 there if you find this functionality valuable.

less-plugin-functions's People

Contributors

seven-phases-max 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

less-plugin-functions's Issues

Uppercase characters not supported in function names?

Hello Max,

Thanks for the 2 less plugins you created (lists & this functions one) - I personally think both are much needed addition to less. 👍
I played with this less-plugin-functions yesterday and couldn't get it to work when I used uppercase characters in my funtion names.

Example:

.function-getStyleNamespace { return: "namespace-"; }

@style-ns: getStyleNamespace(); 
@{style-ns}box { display: block; color: black; }

Output:


.function-getStyleNamespace {
  return: "namespace-";
}
getStyleNamespace()box {
  display: block;
  color: black;
}

If I lowercase the function name then everything works fine.

Regards,
R.

Error on compile: "plugin.install is not a function"

Got this error on compile (i use "grunt-contrib-less": "~1.2.0", which is LESS v2.6.1):

Running "less:core" (less) task
>> TypeError: plugin.install is not a function
>>     at PluginManager.addPlugin (F:\LavkaLavka\Shop\node_modules\less\lib\less\plugin-manager.js:29:12)
>>     at PluginManager.addPlugins (F:\LavkaLavka\Shop\node_modules\less\lib\less\plugin-manager.js:19:18)
>>     at Object.parse (F:\LavkaLavka\Shop\node_modules\less\lib\less\parse.js:34:27)
>>     at Object.render (F:\LavkaLavka\Shop\node_modules\less\lib\less\render.js:25:18)
>>     at F:\LavkaLavka\Shop\node_modules\less\lib\less\render.js:16:24
>>     at Object.render (F:\LavkaLavka\Shop\node_modules\less\lib\less\render.js:15:20)
>>     at compileLess (F:\LavkaLavka\Shop\node_modules\grunt-contrib-less\tasks\less.js:164:17)
>>     at F:\LavkaLavka\Shop\node_modules\grunt-contrib-less\tasks\less.js:63:9
>>     at F:\LavkaLavka\Shop\node_modules\grunt-contrib-less\node_modules\async\lib\async.js:662:13
>>     at iterate (F:\LavkaLavka\Shop\node_modules\grunt-contrib-less\node_modules\async\lib\async.js:146:13)
Warning: Error compiling .less/F133.less Use --force to continue.

Inside gruntfile

    // LESS compilation task.
    less: {
        options: {
            strictImports: true,
            plugins: [
                require('less-plugin-functions')
            ]
        },
        core: {
            src: '.less/<%= pkg.name %>.less',
            dest: 'css/<%= pkg.name %>.css'
        },
        project: {
            src: '.less/style.less',
            dest: 'css/style.css'
        }
    },

Maybe i'm doing something wrong?
I've intialized and used few less plugins this way successfully, so thought i need to write it here)

I reaaaaaallly need this functionality in less now!))

How to use it with webpack?

I want to use this plugin in vue.Then I add this plugin like this.

// https://vue-loader.vuejs.org/en/configurations/extract-css.html
  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less', {
      plugins: [new require('less-plugin-functions')]
    }),
    sass: generateLoaders('sass', {indentedSyntax: true}),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
  }

But it reportes this error.
image
Could you please tell me how to use this plugin with webpack?
Thank you.

How to use it in Sublime?

I want to use this plugin along with Less2Css in Sublime text2. Would you please tell me the way? thanks.

grunt task config

Hi,

I have a problem with using less-plugin-functions. Could you please help me?

I've installed less-plugin-functions, but not globally: npm install --save-dev less-plugin-functions

Here is my grunt task:

    less: {
      production: {
        options: {
          paths: ["assets/css"],
          cleancss: true,
          plugins: [
            new (require('less-plugin-functions'))
          ],
          cleancssOptions: {
            keepSpecialComments: 0
          }
        },
        files: {
          "static/css/tip.css": "static/less/styles.less"
        }
      }
    },

But it does nothing. What I'm doing wrong?

Thanks.

Using return values in @media condition

Maybe I misuse the plugin somehow, but I get the following problem.

My code:

// 1. variable used in function
@foo: 11px;

// 2. function
.function-bar() {
    return: 42 * @foo;
}

// 3. variable that uses function (just for more readability)
@qux: (1px + bar());

// 4. media (@qux value can be copied here directly to media condition as well)
@media (min-width: (@qux)) {

    .baz {
        less: rulez;
    }
}

Expected CSS result:

@media (min-width: 912px) {
  .qux {
    less: rulez;
  }
}

Actual result:

OperationError: Operation on an invalid type in /path/to/myfile.less on line 13, column 28:
12 // 4. media (@qux value can be copied here directly to media condition as well)
13 @media (min-width: (@qux)) {
14

Great work

Thanks this awesome project makes possible to use css variables in less project. The problem was less would not pass compiling less functions, such as fade, tint etc., if are css variables string passed into it. I used this plugin to override those native less functions and passes through whatever params. I used it in my project which based on ant.design, and used css variables to override less variables to achieve multiple themes and dark mode.

I just would like to appreciate the author made this awesome work. My solution may not be elegant but it works :P

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.