Skip to content

Analysis Under Development

SomMeri edited this page Jan 9, 2013 · 46 revisions

@Import

Bug: https://github.com/SomMeri/less4j/issues/19

Less.js supports three import at-rules: @import, @import-once and @import-multiple. The last one is not available yet, but will be in less.js-1.4.0. All three can be used either on style sheet top level, inside ruleset or anything else that is enclosed in { curly braces }.

Less.js import statement looks exactly the same as standard CSS one. Its first parameter is either string or url(...) and is followed by an optional list of media queries: @import url(file.css) screen, handheld.

Attempts to import css and less files are treated differently and so it is important to understand what is considered CSS file and what is considered less file. If the file name ends with suffix ".css", then the file is considered to be CSS file. Otherwise it is considered to be less file. Less.js supports also url parameters at the end of the name e.g., file.css?id=123 is considered CSS file.

CSS File Import

CSS file import statements remain unchanged during the compilation. However, they may change the location during the compilation. All top-level CSS file import statements are printed at the beginning of the style sheet right after the charset declarations.

Sample input:

h1 {
  color: red;
}

@import "import\imported-1.css" handheld and (max-width: 400px);
@import "import\imported-1.css" screen;
@import "import\imported-1.css?id=123";
@import "import\imported-1.css";

#namespace {
  @import "import\imported-1.css";
}

compiled by less.js-1.3.3:

@import "import\imported-1.css" handheld and (max-width: 400px);
@import "import\imported-1.css" screen;
@import "import\imported-1.css?id=123";
@import "import\imported-1.css";
h1 {
  color: red;
}
#namespace {
  @import "import\imported-1.css";
}

Less File Import

Content of imported less file is copied into the main file. All mixins, namespaces, variables etc. are going to be available and can used inside the main file. If the import statement contains also media queries, file content is enclosed in into the body of @media statement.

Imported less file is copied compiled before the compilation. Imported file can reference any mixin or variable defined in the main file and main file can reference anything defined in the imported file.

First example shows import statement with and without media queries. Import\imported-1.less file:

h1 {
  color: red;
}

main file:

h1 {
  color: red;
}

@import "import\imported-1.less" handheld and (max-width: 400px);
@import "import\imported-1.less" screen;
@import "import\imported-1.less";

#namespace {
  @import "import\imported-1.less";
}

compiled by less.js-1.3.3:

h1 {
  color: red;
}
@media handheld and (max-width: 400px) {
  h1 {
    content: 1;
  }
}
@media screen {
  h1 {
    content: 1;
  }
}
h1 {
  content: 1;
}
#namespace h1 {
  content: 1;
}

Second example shows referencing between imported and main files. Imported file import\needs-main-mixin.less file:

importedSelector {
  .mainMixin(); // mixin is defined in main file
  .importedMixin();
}
.importedMixin() {
  content: "imported mixin";
}
@variable: 3; // main file contains variable with the same name

main file:

@variable: 2; // imported file contains variable with the same name
.mainMixin() {
  padding: @variable @variable @variable @variable;
}
mainSelector {
  .mainMixin();
  .importedMixin(); // mixin is defined in imported file 
}
@import url(import/needs-main-mixin.less);

compiled by less.js-1.3.3:

mainSelector {
  padding: 3 3 3 3; // imported file redefined the variable (last definition wins strategy)
  content: "imported mixin";
}
importedSelector {
  padding: 3 3 3 3;
  content: "imported mixin";
}

Finally, if the import statement contains media query and is placed inside a ruleset, @media statement will bubble up as usually:

#namespace {
  @import "import\imported-1.less" screen;
}

compiles into:

@media screen {
  #namespace h1 {
    content: 1;
  }
}

Import vs Import-once vs Import-multiple

Import-once

Import-once statement imports the same less file only once. It does not matter whether you place it on style sheet top level or inside a ruleset nor whether it has media query attached to it or not nor whether it uses string or url(...). The same file is included only once.

Sample input:

@import-once "import\imported-1.less" handheld and (max-width: 400px);
@import-once "import\imported-1.less" screen; //this will be ignored
@import-once url(import\imported-1.less); //this will be ignored

#namespace {
  @import-once "import\imported-1.less"; //this will be ignored
}

compiles into:

@media handheld and (max-width: 400px) {
  // imported-1.less content
}

Import once of css files works differently. This:

@import-once "import\imported-1.css" handheld and (max-width: 400px);
@import-once "import\imported-1.css" handheld and (max-width: 400px);
@import-once "import\imported-1.css" screen; //this will be ignored
@import-once url(import\imported-1.css); //this will be ignored

#namespace {
  @import-once "import\imported-1.css"; //this will be ignored
}

is compiled into:

@import "import\imported-1.css" handheld and (max-width: 400px);
@import "import\imported-1.css" handheld and (max-width: 400px);
@import "import\imported-1.css" screen; //this will be ignored
@import url(import\imported-1.css); //this will be ignored

#namespace {
  @import "import\imported-1.css"; //this will be ignored
}

TODO: ask less.js whether this is how it should be.

Import-multiple

Import-multiple statement will be available after 1.4.0 comes out. It imports the same less file any number of times.

Sample input:

@import-multiple "import\imported-1.less" handheld and (max-width: 400px);
@import-multiple "import\imported-1.less" screen; 
@import-multiple url(import\imported-1.less); 

#namespace {
  @import-multiple "import\imported-1.less"; 
}

compiles into:

@media handheld and (max-width: 400px) {
  // imported-1.less content
}
@media screen {
  // imported-1.less content
}
#namespace {
  // imported-1.less content
}

Import

The import statement in current less.js acts as @import-multiple. This will change in 1.4.0. The import statement will be modified to act as @import-once.

Combinations

TODO

Limitations

TODO import-once and import-multiple on css files TODO variables and escaped values TODO less4j supports only top-level imports for now.