XF 2.1 Future upgrade for oyejorge LESS compiler?

Wildcat Media

Well-known member
I was trying to use some advanced LESS functions and realized some were failing because the LESS compiler is about five years old. Using conditionals in a LESS stylesheet can really come in handy. For instance, in extra.less, I can have a change of color (or opacity) of an element based on the background color of the content, by using the @xf-contentBg color variable to test against. (I could do a boolean check of the luminance being greater than a given percentage, then use the true/false outcome in an if() statement to apply either of two colors and/or opacities.) That way, I can use it so that it passes down to child styles and saves me having to edit each one separately for each change. (When creating dark and light styles, this can be helpful.) There are a few others functions that are also helpful.
Are there plans for an update of the LESS compiler in the next release of XenForo (2.2)? I see that the oyejorge compiler was archived as of 2017, but Wikimedia has now forked it with newer releases. Alternately, would there be a way to use the official less.js release easily? (I'm thinking no, because XF would have used it in the first place.)
 
Solution
You may be interested in some of XF's default extensions to the Less syntax in order to solve problems like this. It relies on the styleType style property (under Color palette) being either light or dark as appropriate for each style:

Less:
@bg: black;

div
{
   background: @bg;
   color: xf-diminish(@bg, 100%);
}

If it's a light style (so the bg would be black) then xf-diminish will take the black color and lighten it by 100%. If it's a dark style (so the bg would be white) then it will take white and then darken it by 100%.

Essentially that's all that xf-diminish does. It's a context sensitive approach that uses the default Less lighten function if it's a light style and the default darken...
We have to pre-process the Less on the server side so, no, we cannot use Less.js.

We are somewhat at the mercy of the PHP fork. The version we currently use is actually forked from oyejorge but we have enhanced it with additional support for things like the @supports keyword and other fixes.

The MediaWiki one, the last time we checked, only provides some bug fixes and doesn’t further port any functionality from recent versions of Less.js so it wouldn’t help in this case.

So support for conditionals is unlikely in the short term.

However can you confirm more concretely what you want to achieve? There may be other workarounds.
 
However can you confirm more concretely what you want to achieve? There may be other workarounds.
I found a workaround for one issue I was having--the fade function works as expected (it sets absolute opacity as a percentage).

What I was hoping for was a way to change the color of an element based on a light or dark background color automatically. The LESS documentation gives an example of what I was hoping to achieve, combining the luma, boolean and if functions:

CSS:
@bg: black;
@bg-light: boolean(luma(@bg) > 50%);

div {
  background: @bg;
  color: if(@bg-light, black, white);
}

The way I structure my styles, I have them set up in a hierarchy of three or four deep. I do all of my layout edits and branding in the third layer of styles, and use the fourth layer for color edits, which is where I create the public styles that visitors use. So if I edit extra.less in the layout layer, I'd prefer not to have to edit it for each color variation or, at least for a "dark" variation needing its own edit. (It's easy to overlook when there are a couple dozen edits in extra.less.)

Thanks to creative use of LESS, though, I almost have it to where I can change three colors in the color palette and the rest are generated using various LESS functions. The spin function can be used on accent colors--"spinning" a color 180 degrees creates its inverse at 180 degrees on the color wheel. (For example, I can set paletteAccent3 to the opposite color paletteAccent1: spin(@xf-paletteAccent1, 180). Or if I want a triad, I can pick colors at 120 and 240 degrees.) Lighten, darken, fade, and many others used with the XF variables make the styling system very easy to work with.

I should add that certain LESS commands do not render in the style property editor, though, like spin. So some of it is guesswork. They do render on the finished pages, though.
 
You may be interested in some of XF's default extensions to the Less syntax in order to solve problems like this. It relies on the styleType style property (under Color palette) being either light or dark as appropriate for each style:

Less:
@bg: black;

div
{
   background: @bg;
   color: xf-diminish(@bg, 100%);
}

If it's a light style (so the bg would be black) then xf-diminish will take the black color and lighten it by 100%. If it's a dark style (so the bg would be white) then it will take white and then darken it by 100%.

Essentially that's all that xf-diminish does. It's a context sensitive approach that uses the default Less lighten function if it's a light style and the default darken function if it's a dark style. There's an opposite as well called xf-intensify where in a light style it would use darken and in a dark style it would use lighten.

We use xf-diminish and xf-intensify a lot to avoid issues exactly like this so is likely what you want to do.
 
Solution
I can understand that. I seem to recall the naming of those functions being fairly tricky to settle upon! It's not particularly clear but probably the best we could have come up with.
 
I think a slight lack of documentation over what those two actually do might have contributed to it. 😉 But prefixing them with xf- does at least let me know they are not standard LESS. I don't think I came across any others, but I didn't dig deeply into each style property either.

I've just started working with the duotone Font Awesome icons, which is where I was dealing with the unpredictable behavior. But the fade() function took care of the issues I was having, as that will reduce opacity to get the read/unread effect I am after.
 
Top Bottom