4

I am trying to develop a 'theming engine' in LESS CSS to allow clients to update the colour scheme for their site with the least number of variables. At present we have a variables file where we are assigning the default set, and to shorthand the number of user inputs we utilise the lighten and darken functions a lot e.g.

// snippet 1
@grayLight: #999999;
@grayLighter: darken(@grayLight, 10%);

Is there a way in which the lighten/darken functions can be assigned as a variable? This way we only need to specify the tone contrast (dark/light or light/dark):

// snippet 2 (does not work)
@contrastVerb: darken;
@linkColorHover: @contrastVerb(@linkColor, 10%);//#FFA500;

I have tried using Javascript bracket notation to call the function request e.g.

// snippet 3 (does not work)
@linkColorHover: `window[@contrastVerb]`(@linkColor, 10%);//#FFA500;

An option is pattern-matching:

// snippet 4
@tone: light;
.linkColor(light, @color){
    color: lighten(@color, 10%);
}
.linkColor(dark, @color){
    color: darken(@color, 10%);
}

.linkColor(@tone, #f17900);

However snippet 4 will is much more verbose than snippets 2 or 3, and will result in a lot of extra code being generated.

Thanks in advance!

2 Answers 2

3

I'm in a similar situation regarding user generated themes and I've come up with the following LESS mixin to help me manage colour schemes generated from a few base colours:

//LESS 1.3.3
.color (@color, @amount: 100) {
        color: contrast(@color, darken(@color, lightness(@color) * (@amount / 100)), lighten(@color, (100 - lightness(@color)) * (@amount / 100)), 0.5);
    }

The above code was written for LESS 1.3.3 which has a different contrast function to the LESS version I normally use in Sublime Text 2! If this doesn't give the expected result try:

.color (@color, @amount: 100) {
    color: contrast(@color, lighten(@color, (100 - lightness(@color)) * (@amount / 100)), darken(@color, lightness(@color) * (@amount / 100)), 50%);
}

This mixin works by generating a contrasting colour based on an input colour and an amount between 0 - 100 inclusive. 100 = full contrast (i.e. black or white); 0 = no contrast (i.e. input colour). E.g.

LESS

@c: #4f2634;
.c0 {.color(@c, 0)}
.c20 {.color(@c, 20)}
.c50 {.color(@c, 50)}
.c80 {.color(@c, 80)}
.c100 {.color(@c, 100)}

CSS

.c0 {color: #4f2634;}
.c20 {color: #844057;}
.c50 {color: #bf7a92;}
.c80 {color: #e5cad3;}
.c100 {color: #ffffff;}

This example obviously generates a text colour so is useful when given a background colour, but the same idea can be re-purposed for border colours etc. Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

0

Try just add a class in the <body> and create css rules (with mixin) to change whatever in the site.

<body class="section1"></body>

LESS Demo:

.color-mixin (@color) {
    color: @color;
    .foo{
         background-color: darken(@color, 10%);
    }
    a {
        &:hover{
            background-color: lighten(@color, 30%);
        }
    }
}

.section1 {
    .color-mixin(red);
}
.section2 {
    .color-mixin(blue);
}

CSS Result:

.section1 {
  color: #ff0000;
}
.section1 .foo {
  background-color: #cc0000;
}
.section1 a:hover {
  background-color: #ff9999;
}
.section2 {
  color: #0000ff;
}
.section2 .foo {
  background-color: #0000cc;
}
.section2 a:hover {
  background-color: #9999ff;
}​

3 Comments

Good suggestion. Unfortunately each 'theme' is the entire CSS of the website re-skinned with the same variables. When a user switches theme they get an entirely new several thousand line CSS file. As there is the potential to be ten or more themes I can't see it being feasible to have the class on the body tag switching the styles.
So the solution in this case has nothing to do with LESS. It would be better load a new CSS file by AJAX.
You're right - we will end up switching out the CSS when needed. However my original question was: is there a more succinct way than pattern-matching to generate the light/dark switch when changing an elements tone?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.