1

I have 20-30 elements that should share the same color and font-family. Therefore I set it as a mixin. Now the cn website identified as <html class='cn'> should have the font of mango-arial and the jp should be hentai-arial.

I want the following sing CSS result file:

html.cn .div
{   
    color:green;
}

html.jp .div 
{
    color:yellow:
}

I'm, trying the following less code, each rule is defined in a separate language file:

-- in cn.less
html.cn
{
    .textColor { color:green}
}

-- in jp.less
html.jp
{
    .textColor { color: yellow} 
}

-- in general.less
.div {.textColor;}
.someOtherElement1 { .textColor; otherstyles:here;}
.someOtherElement2 { .textColor; otherElem2Styles:here;}
...

Pay attention, I want all the language overrides in their separate less files.

Alex
  • 11,479
  • 6
  • 28
  • 50
  • Why do you do that? I think something like cn.css and jp.css will solve the problem. – SaidbakR Nov 20 '12 at 13:13
  • I have 20-30 elements that should share the same `color` and `font-family`. Therefore I set it as a mixin. Now the `cn` website should had it as `mango-arial` and the `jp` should be `hentai-arial`. – Alex Nov 20 '12 at 13:39
  • 1
    Well, You may have to link several css files, for instance, the common 30 elements will be defined in common.css followed by linking your language css. which will mask any value in common you want to qualify it to the language. – SaidbakR Nov 20 '12 at 14:00
  • Yep, and thats exactly where the `less` compiler comes in ;) I want to define the styles for my elements using the mixin, and the mixin to be changed according to the lang files. My question is, what is the right `less` syntax for that. – Alex Nov 20 '12 at 14:13
  • Just make a few less file, each takes different `@color` declarations, and import the rest of your code. which will automatically generates different csses. – xiaoyi Nov 20 '12 at 16:07
  • Either I'm not getting you correct or I don't know how to implement it. I want to define in my `cn` file that `@color` is `green` and in my `jp` file that `@color` is `yellow`. And use that as the font color of text in 20 divs. The markup for both sites and the code is the same. The only difference is the `` – Alex Nov 20 '12 at 17:22

1 Answers1

3

New Answer

What you desire is not exactly an easy task. LESS is not quite designed to do it they way you intend. However, I do believe I found a way to get something that would work for you.

Define Your Language Specifics

Note that you will need to change how you have the languages defined, but they can be defined in separate files. Below is an example. Note:

  1. An index number for the language must be defined as the first part of the language mixin (this will be explained later). This must be NON-ZERO, POSITIVE, unique to that language, and all the languages must be in sequence (no skipping numbers) from 1 to whateveer. If you want the languages to output in alphabetical order, then you need to number them in reverse (so 'z' starting languages would be starting the numbering at 1, while 'a' starting languages would hold the last and highest number).
  2. These files will automatically append the html.lg code where lg is the language. That code needs to be defined in the .htmlAppend mixin portion.
  3. You need to define getter mixins in these langauges for the properties you want (such as textColor, etc.). If you may want multiple properties for a class you are defining and you do not want to define them as a group (so you want to sometimes access them individually, sometimes as group), then you need to define a separate group getter (see the colorPkg getter below for an example).

Language Files Code

// in cn file 

.lang(1, @class, @prop) { //cn
   .htmlAppend(@class, @prop);

   .htmlAppend(@class, @prop) {

      (~"html.cn @{class}") { //lang code here
         .getProp(@prop);
      }

      .getProp(textColor){
         color: green;
      }
      .getProp(bkgColor) {
         background-color: #fff;
      }
      .getProp(colorPkg) {
         .getProp(textColor);
         .getProp(bkgColor);
      }
   }
}

// in jp file 

.lang(2, @class, @prop) { //jp
   .htmlAppend(@class, @prop);

   .htmlAppend(@class, @prop) {

      (~"html.jp @{class}") { //lang code here
         .getProp(@prop);
      }

      .getProp(textColor){
         color: yellow;
      }
      .getProp(bkgColor) {
         background-color: #000;
      }
      .getProp(colorPkg) {
         .getProp(textColor);
         .getProp(bkgColor);
      }
   }
}

Core Variable and Mixins in Your Main File

You would import your language specific LESS files, then following that, have a few other things defined as noted below. Note:

  1. You must define a variable with the maximum number of languages you are importing.
  2. The following code uses a loop structure as found here which this post clued me in on. This is why the languages must have the sequential index number. The number ZERO ends the loop, which is why the indexes must be positive.

Core Main File Code

// in main file
//must tell it the maximum number of languages defined, 
//and they must be numbered in sequence
@numLang: 2; 

//a getter function for all languages
.getLangProp(@class, @prop, @index: @numLang) when (@index > 0) {
     //get and define the language specific class
     .lang(@index, @class, @prop);

     // next iteration
     .getLangProp(@class, @prop, @index - 1);
}

// end the loop when index is 0
.getLangProp(@class, @prop, 0) {}

Now Define Your Class Info

This is done in two stages for any classes that need the language aspects. First, call the property or property set from the language files, using the pattern matching name defined in the language files. Then define your other base class. Note that the "class" can be a selector string of any kind (see the third example).

Main File: Define Language Specific Class Code

.getLangProp(".myClass1", textColor);
.myClass1 {
    height: 20px;
    width: 40px;
}

.getLangProp(".myClass2", bkgColor);
.myClass2 {
    position: absolute;
    top: 10px;
}

.getLangProp(".parent > .myClass3", colorPkg);
.parent {
    & > .myClass3 {
       float: right;
    }
}

Which Outputs This CSS

html.jp .myClass1 {
  color: yellow;
}
html.cn .myClass1 {
  color: green;
}
.myClass1 {
  height: 20px;
  width: 40px;
}
html.jp .myClass2 {
  background-color: #000;
}
html.cn .myClass2 {
  background-color: #fff;
}
.myClass2 {
  position: absolute;
  top: 10px;
}
html.jp .parent > .myClass3 {
  color: yellow;
  background-color: #000;
}
html.cn .parent > .myClass3 {
  color: green;
  background-color: #fff;
}
.parent  > .myClass3 {
  float: right;
}

Original Answer

The original answer did not accommodate the structure of what the OP wanted, but I have left it here so that others might benefit.

LESS Code

One Solution Organized under html tag

html {
  &.cn .div {color: green;}
  &.jp .div {color: yellow;} 
}

Another Solution Organized on the .div class (not sure why you would want a class named that, but I went with it).

.div {
   html.cn & {color: green;}
   html.jp & {color: yellow;}
}

Both Output This CSS

html.cn .div {
  color: green;
}
html.jp .div {
  color: yellow;
}
Community
  • 1
  • 1
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • Thanks for the answer, but in both cases would be hard for me to have a special `cn.less` file with `cn` overrides, and `jp.less` with `jp` overrides. + there are 30 different elements I'm willing to use this class for, not only that single `div`, but also some `span`s with some concerete classes. – Alex Nov 23 '12 at 21:27
  • Your question did not mention you were storing values in separate LESS files. So if I understand you correctly, you are wanting these separate files to come together into a single file that then outputs as you stated you wanted the output to be. – ScottS Nov 23 '12 at 22:37
  • Yep, you understand correctly now. I've edited the question. Thanks for pointing that out ;) – Alex Nov 24 '12 at 10:05
  • I'm a little confused though. Is your result that you seek supposed to be happening in each individual LESS language file, or are all the language files coming together in one file to produce the CSS output. Your language file is mentioned in the output. – ScottS Nov 24 '12 at 12:16
  • I want to define the overrides in separate language files, but the compiled result I want as a single file. – Alex Nov 24 '12 at 12:44
  • @Alex--That is not as easily done as you would have it be. I have, however, come up with one solution to make it function somewhat as you desire (separate language files, each compiling code for a specific class you desire to be affected by that). – ScottS Nov 24 '12 at 16:24
  • Seems exactly like what I need. Although a bit complicated, but supposed to work. By the way, maybe less is not the best fit for my task here. Maybe you could suggest another tool for that ? `sass`? – Alex Nov 25 '12 at 09:19
  • Yes, it is complicated. `LESS` is not designed for that. It is designed to be used more like my original answer. You might have variables stored in the language files, but if you are bringing them together in one file, then that file would have to refer to those languages as well. OR, all the language code is in the files, including the classes below, and then only one language served at a time depending upon the language chosen (which is less clutter to the final CSS). Basically, your pattern of organization is not typical for what most do. I don't know if `SASS` would be better. – ScottS Nov 25 '12 at 14:25
  • Alright, thank you very much. Although I'll still consider to use some custom pre-processing prior to less; – Alex Nov 25 '12 at 14:34
  • Impressively thorough answer. – zrooda Nov 26 '12 at 14:30
  • @Alex--thanks for the extra bounty points. I trust you found it useful enough to offer that extra bit for my efforts. – ScottS Nov 27 '12 at 12:17