Code Monkey home page Code Monkey logo

Comments (9)

itswillta avatar itswillta commented on September 15, 2024

This is what I imagine what will happen when we use CSS Variables:

  1. On the frontend side, each SPA will have to call to the /api/themes/:domainId endpoint to get the theme of the current domain.
  2. After getting all the theme variables from the endpoint, we append a style block to define the CSS Variables, e.g.:
:root {
  --primary-color: #223c50;
  --accent-color: #401b32;
  --body-bg-color: #f7f7f7;
  --text-primary-color: #ffffff;
  --text-color: #333333;
}
  1. If all the CSS files that particular SPA uses have already been reconfigured to use CSS Variables instead of LESS Variables, e.g.:
@media (min-width: @screen-md-min) {
  .calendar-sidebar-title {
    border-left: 5px solid var(--primary-color);
    margin-bottom: 5px;
  }
}

then all the CSS styles will use the correct CSS Variables that are defined in the second step.

The most time-consuming should be the third step because you'll have to do that with every LESS file of every single SPA that previously uses LESS Variables, but I suppose we don't have any other way, right?

However, if we implement theming this way, the users are likely to face the flash of "unthemed" content (similar to the flash of unstyled content - FOUC), where they will see the default theme for a brief moment and then the current theme after the request to get the current theme has succeeded. I'll try and see how bad it is, and maybe we can resort to displaying a loading screen while waiting for the current theme. We can also mitigate it by using some sort of cache (e.g. using Local Storage), so most of the time the users will only experience a flash of unthemed content the first time they load the app.

from esn-frontend-common-libs.

RomaricMourgues avatar RomaricMourgues commented on September 15, 2024

Hi,
what we do on Twake is loading the theme on the first app call, and we don't display the app while the theme is not loaded. I don't know if you also get languages from the backend but it's the same process (wait for it to display page).

About replacing all less variables to css variables, you can also put css variable as value of less variables like this:

@primary: var(--black);
//Sass $primary: var(--black);

On Twake we had a single file with all less variables, we duplicated the less variables, transformed them into css variables with a regex, and update the remaining less variables values (the one we copied) to use the new css variables as values.

:root {
  --primary: #837dff;
}
@primary:        var(--primary);
//Sass $primary: var(--primary);

Of course it depends on your architecture and the number of variable you have. (and a big search-and-replace using regex can also work I suppose)

(Edit this is for Sass not Less, I'm fixing this)
(Edit 2, ok fixed it should work like this, and may be the whole process is a bit obvious in the end and not adapted in your case :) )

from esn-frontend-common-libs.

chamerling avatar chamerling commented on September 15, 2024

from esn-frontend-common-libs.

itswillta avatar itswillta commented on September 15, 2024

Yes. But here's the problem: LESS functions (e.g. darken, lighten) don't understand CSS Variables.

:root {
  --primary-color: #ff0000;
}

@primaryColor: var(--primary-color); // valid

.whatever {
  color: @primaryColor; // valid
}

.trouble {
  color: darken(@primaryColor, 10%); // invalid
}

From what I read in its documentation, those functions mainly revolve around HSL/HSLA color. So we'll need to convert HEX values to HSL/HSLA. Hopefully, if you have a better way, please converse with me. For now I'll just go with converting HEX to HSLA.

from esn-frontend-common-libs.

itswillta avatar itswillta commented on September 15, 2024

Well I take it back. LESS functions just don't work with CSS Variables (badlydrawnrob/print-first-css#29). Since there are like thousands of places where LESS functions are used, it's not quite possible to manually convert them all into something that can work with CSS Variables. So I'll need to find another solution.

Edit: Investigating into using LESS plugins that can override those default functions to work with CSS Variables.

from esn-frontend-common-libs.

itswillta avatar itswillta commented on September 15, 2024

Mh... Even using LESS plugins can only solve half of the problem. The other half of the problem is that we need to also convert the other LESS variables that depend on the "root" theme variables (primary color, accent color, body background color, text primary color and text color) at runtime (on the client side).

You can look at the example below and the comments to understand what the problem is:

:root {
  --primary-color: #223c50;
}

// This should work without any problem. This will appear on the client side as something like `var(--primary-color, #2196F3)`
@primaryColor: var(--primary-color, lighten(@m-blue, 20%));

// This line won't work without the plugin that I'm writing.
@subHeaderBackground: darken(@primaryColor, 4%);
// However, with the plugin, I'm going to get it transformed into this:
// @subHeaderBackground: var(--primary-color-darken-4-percent);

As you can see, on the client side, I'll have to actually define --primary-color-darken-4-percent based on its name (getting the primary color and then darkening it by 4%).

However, I find this approach a little bit brute-forcing. There'll probably be hundreds of CSS variables such as --primary-color-darken-4-percent, --accent-color-lighten-10-percent, --text-primary-color-fade-5-percent, etc. Let's name this solution Solution No.1.

Edit: Hold on, I might have actually found a better way to do this, but I'll have to test it out first. The idea is something like this:

:root {
  --primary-color-h: 0;
  --primary-color-s: 100%;
  --primary-color-l: 50%;
}

@primaryColor: hsl(var(--primary-color-h), var(--primary-color-s), var(--primary-color-l));

@subHeaderBackground: darken(@primaryColor, 4%); 
// The above will be transformed into this: 
// @subHeaderBackground: hsl(var(--primary-color-h), var(--primary-color-s), calc(var(--primary-color-l) - 4%))

@subHeaderBackground2: lighten(@subHeaderBackground, 5%);
// The above will be transformed into this: 
// @subHeaderBackground2: hsl(var(--primary-color-h), var(--primary-color-s), calc(var(--primary-color-l) + 1%))

Let's name this solution Solution No.2.

from esn-frontend-common-libs.

RomaricMourgues avatar RomaricMourgues commented on September 15, 2024

Interesting solution No.2, on Twake we used the solution No.1 but we have less customisation and less colors variables.

If I can suggest a third solution, may be this is already your idea of implementation of the solution no.2:

  1. The server send a limited number of colors (like primary-color and secondary-color), in hexa (or rgb)

  2. On the frontend, and for each color, you generate with JS primary-color-a, primary-color-b, and primary-color-c. I'm sure it shouldn't be too hard to convert hexa and rgb to hsl (https://gist.github.com/mjackson/5311256).

If you can do that, you have the best of the two sides, a limited number of colors and variable from the server (and better structured than separating the 3 parts everytime) and you can use the darken/lighten feature.

from esn-frontend-common-libs.

itswillta avatar itswillta commented on September 15, 2024

Yes the solution you suggest is what I have in mind to implement Solution No.2. The most time-consuming part now will be to write a plugin to automatically transform all those darken/lighten/fade functions accordingly, because doing it manually is near impossible. Hopefully there won't be another problem arising when I actually get to the implementation details.

from esn-frontend-common-libs.

itswillta avatar itswillta commented on September 15, 2024

OK, so the plugin worked. Now I just have to pull all of them altogether.

Screenshot from 2020-07-17 14-54-44

from esn-frontend-common-libs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.