51

I started using LESS today. But it's kinda weird. This code does not work. I get an error:

! Variable Name Error: @linkColor in a is undefined.

My bootstrap:

@import "variables.less";
@import "normalize.less";

variables.less:

@linkColor:             #08c;
@linkColorHover:        darken(@linkColor, 15%);

normalize.less:

a {
    color: @linkColor;
}
a:visited {
    color: @linkColor;
}
a:hover {
    color: @linkColorHover;
}

When I make an

@import "variables.less"

in the normalize.less file, everything works fine.

Thanks for your help :)

Huangism
  • 16,278
  • 7
  • 48
  • 74
conradkleinespel
  • 6,560
  • 10
  • 51
  • 87
  • how do you compile into .css? using less.js or software compiler? curious if that makes a difference.. host your files somewhere so that we can check (if possible) - i never had problems with such file structure. – bzx Feb 05 '12 at 20:45
  • Sorry I didn't see this comment before now. I think it might have been a problem with wrongly set file permissions on my Linux :s Anyway, everything seems to be working fine now ! – conradkleinespel Feb 14 '12 at 20:13
  • 2
    @conradk I'm experiences the same issue working with Less.app on OS X. How did changing permissions help? – Mr Jonny Wood Mar 12 '12 at 13:42
  • If I remember well enough, I had to restrictive permissions set on the "/home/myAccount" folder, which also contained my webroot. – conradkleinespel Apr 18 '12 at 09:47

10 Answers10

31

This other question ultimately led me to the right answer.

It looks like the LESS compiler is silently failing if files are encoded with a BOM. (That's a Byte Order Mark for those not familiar with the term.) This is the default setting in some editors, such as Visual Studio.

The compiler barfs up an error on the BOM if it's in your root file, but seems to fail silently for @import-ed files.

Try saving your files as UTF-8 without a BOM, and see if that solves your problem.

Community
  • 1
  • 1
Chris Jaynes
  • 2,868
  • 30
  • 29
  • any idea on whether TextMate is guilty of BOM crimes? – ken Jul 20 '12 at 12:38
  • Sorry, I'm not a TextMate user. – Chris Jaynes Jul 21 '12 at 13:43
  • I misread this. I'm using Sublime Text 2 on Windows. I selected `File > Save With Encoding > UTF-8 with BOM` and my `grunt watch` recompiled it and the problem went away straight away. Thanks for the tip anyway! – rtpHarry Jan 28 '15 at 12:45
6

This error can also occur via bad imports in the files you're importing.

I also encountered this issue, when using multiple layers of import, and the 'lessc' compiler from Node.js:

  • The original file imported a file (which we will call 'child')
  • The child file imported a file (which we will call 'grandchild')
  • The grandchild was imported

I attempted to compile the original file, and received the same 'undefined variable' behavior. I could see the variable was defined in the child and the syntax lookedcorrect.

No prior errors were displayed.

The problem turned out that the child was not importing the grandchild properly. Ie,

@import grandchild.less

rather than:

@import "grandchild.less";

Fixing the child importing the grandchild made the original see the variables defined in the child.

This seems like a bug in less - ie, the bad import should show up in the 'lessc' output, so one day it will probably be fixed. Until then, I hope this helps.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
6

There may be another possible root cause.

Here is my original Gruntfile.js:

less: {
      compile: {
        files: {
          'css/less.css': 'less/**/*.less'
        }
      }
    },

The wildcard makes LESS compiler compile all .less files under that folder and merge all results into one CSS. And I got errors running grunt less:compile:

NameError: .transition is undefined in less/core/html.less on line 38, column 3

Once I changed 'less/**/*.less' into 'less/css.less', the compilation succeeds.

Evi Song
  • 862
  • 11
  • 14
5

I encountered the same problem using Winless compiler.

Some of the .less files i was importing into master.less were empty. when i removed these from the list of imported files my variables were recognized!

Adam
  • 51
  • 1
  • 2
1

To help any others that may come across this not want duplicate CSS generated from multiple imports, you have two options.

  1. Either @import-once the variables / mixins files you need in each file you need to use them in.

    Use @import-once "filename.less"; to prevent duplicates.

  2. Upgrade to LESS > 1.4.0, when it arrives; From the less website:

    "The statement @import acts differently before and after 1.4.0. It acts as @import-multiple in all older versions and as @import-once in all less.js versions after 1.4.0."

Austen Cameron
  • 342
  • 4
  • 14
1

You can also get this error if you are trying to import the file twice (not a good idea) and the first import is before your variables referenced in your.less file have been loaded

Note: I'm using django compress

in index.html i had:

{% compress css %}
<link href="{{ STATIC_URL }}less/timepicker.less" rel="stylesheet" type="text/less">
<link href="{{ STATIC_URL }}less/style.less" rel="stylesheet" type="text/less">
{% endcompress %}

then in styles.less i had

...
@import "timepick.less";
lukeaus
  • 11,465
  • 7
  • 50
  • 60
  • 1
    I would recommend against using `STATIC_URL` in templates - http://staticfiles.productiondjango.com/blog/stop-using-static-url-in-templates/ – Kristian Glass Feb 02 '15 at 22:44
  • "You can also get this error if you are trying to import the file twice " - yep, thank you for posting this. It was the key to solving my issue. – jwogrady Oct 28 '16 at 02:15
1

I think it is because of which master less file you are compiling. Likewise

If you have Less/Project_name/project.less and in this project.less you import the variable less and all the other files which has in the directory.

You just have to compile project.less into your css, not all less files. If you try to compile project.less and variables.less at a time you will have this error. And you can avoid redundant declaration of importing the variable less files

0

One other weirdly specific situation in which this occurs: if you're using .NET and dotless, the compiler will choke on nested media queries with variable specifiers. If you have code like this:

@media (min-width: @aVariable) {
    .some-class{
        margin: 10px;

        @media (min-width: @anotherVariable) {
            margin: 20px;
        }
}

... then dotless will tell you that it can't find the definition for @anotherVariable, even if it's used three lines above.

The Digital Gabeg
  • 2,765
  • 3
  • 21
  • 16
0

For me its happened when using @Import-once and nothing help. but with @Import its worked.

as i read in the last version of the Less the Import will work as Import-once.

amichai
  • 718
  • 9
  • 19
0

I would use the nested rules in the normalize.less :

a {
     color: @linkColor;

     &:visited {color: @linkColor;}

     &:hover {color: @linkColorHover;}
}

And in the @import, you don't need to use the ".less", it's optional :

@import "variables";
@import "normalize";

I don't know if this can help...

Stef
  • 1
  • 1