I think I understand what you want to do. You kind of want to change one variable, the basic color, and have several colors changed on your site depending on that basic color.
As Flarum uses less for CSS, as clarkwinkelmann just pointed out, this can be done quite easily.
First let me show you my forum, as I've practised this idea: https://moccato.de
If you go to the tag Café you can see that the predominant color is blue, if you enter the tag Gesundheit it's green. There are several elements changing their color, some just very subtly, but they don't all just get the same color, the basic color, they get a color derived from the basic color.
How is that done?
If you look at the generated source code (press F12 to look at it), you can see that in the Café there is a class col-23-144-243
attached to the <body>
element whereas in the tag Gesundheit it has the class col-96-176-96
instead. This class, as you might suspect, deliveres the basic color that affects the whole page. To put this class into effect, you can use less which can be put into an extension.
How does that less CSS look like?
I will shorten the code that I actually use on my website to concentrate on the principle.
First I define a function. That doesn't work in pure CSS but you can do that in less CSS. Flarum takes care to translate this into pure CSS which all the browsers understand:
.colorize(@r, @g, @b) {
@base: rgb(@r, @g, @b);
@hue: hue(@base);
@sat: saturation(@base);
@light: lightness(@base);
@base-lighten10: hsl(@hue, @sat, @light*1.1);
@base-lighten30: hsl(@hue, @sat, @light*1.3);
@base-darken10: hsl(@hue, @sat, @light*.9);
.DiscussionPage-nav .App-primaryControl,
.IndexPage-nav sideNav .App-primaryControl,
.App-composer .App-primaryControl,
.IndexPage-newDiscussion {
background-color: @base !important;
}
#header,
.App::before {
color: hsl(@hue, @sat*.2, 20%) !important;
background-color: hsl(@hue, @sat*.6, 20%);
}
header.Hero {
background-color: hsl(@hue, @sat*.35, 90%) !important;
}
.Composer-controls .Button {
color: @base-darken30;
}
.Scrubber-bar {
background-color: @base-lighten10;
}
}
As you can see, this function takes three values as an argument: @r
, @g
and @b
. Then it recombines them to create other variables (@hue
, @sat
and @light
) and colors (@base
, @base-lighten10
etc.). These variables and colors can then be used in the following definitions of elements on the page.
@base-lighten10: hsl(@hue, @sat, @light*1.1);
... means: create a color with the same hue and saturation as the basic color, but a lightness, that's 110% of the basic color's lightness.
.Composer-controls .Button {
color: @base-darken30;
}
... means: apply @base-darken30
as the color of the button in the composer.
color: hsl(@hue, @sat*.2, 20%)
... means: apply a color to the given element with the hue of the basic color, 20% of the saturation of the basic color and a lightness of 20% (independent from the basic color).
What's next
Now we need to apply this .colorize(@r, @g, @b)
function to the page, that means, we have to tell the page which basic color should be applied. Now the class attached to the <body>
element comes into play which I was talking about in the beginning. That's also not too complicated:
body { .colorize( 85, 65, 55 ) } // Default
body.col-23-144-243 { .colorize( 23, 144, 243 ) } // Cafe
body.col-96-176-96 { .colorize( 96, 176, 96 ) } // Gesundheit
This means: if the body has a class .col-23-144-243
then call our function with these values: .colorize( 23,144,243)
.
And finally
Finally you need to apply these special classes to the <body>
element. This needs to be done by the extension as well. I wrote an extension for my forum, which is quite a hack, so it's not ready for prime time. What I did? I wait for the page to load, use javascript to read the color of the .hero
element, turn this into a class name and apply it to the <body>
element. A hack, sure, but it works so far as you can see in my forum.
It would be much cleaner, if I could apply the class to the <body>
element in the first place and didn't have to wait for the page to load completely and apply it afterwards, but to do that first I have to learn a little more myself.
Ultimately I think of an extension, which is able to add classes to the <body>
element based on tags, user groups, a discussion being closed or stickied, time of the day, or user preference, so a dark theme could be done easily as well as hiding elements for guests or different themes for different tags (as I did it).
I know, that at first sight this is not easy to understand and implement, but if you are willing to dive into CSS and less CSS, that's probably a good place to start. And as you seem willing to learn about extensions, maybe you can solve the shortcomings of my solution.