Fully custom colors by overriding CSS variables

Hi and thanks for a great framework!

I have a specific situation where I’d like to fully customise the colors, no matter the OS or preferred light/dark mode.

I can easily achieve a lot of this by applying:

// In App.tsx

const f7params: Framework7Parameters = {
    darkMode: false,
    theme: "md"
    colors: { primary: "#2c3f5c" }
}

This forces the Material theme and disables dark mode. In addition F7 automatically calculates (as far as I understand) the color palette using my provided primary color #2c3f5c.

Unfortunately, calculating the palette from #2c3f5c is not what I need in this case: I want to further modify the theme by providing a custom palette.

I think that changing a couple of the CSS variables would do it. So I tried something like:

/* app.css */
:root {
  --f7-ios-primary: #2c3f5c;
  --f7-ios-primary-shade: #ababab; /* some really wired color from our palette, unrelated to #2c3f5c */
  --f7-ios-primary-tint: #aeaeae; /* more custom colors, impossible to calculate from #2c3f5c */
  --f7-ios-primary-rgb: 123, 5, 0;   /* and so on.... */
  --f7-md-primary-shade: #970100;
  --f7-md-primary-tint: #e90100;
  --f7-md-primary-rgb: 192, 1, 0;
  --f7-md-primary: #c00100;
...

However, it seems as all CSS variables are dynamically overridden when F7 initiates, so the values I set in app.css have no effect.

Is there any other way I can override the CSS variables and make them prevail even after F7 initialises? Perhaps I somehow must stop F7 from running setColorTheme() on init?

I found a solution for this. I’m not sure if it’s the best one and it’s certainly not an official way to do this, so if F7 developers know of another way, please let me know. Anyway, it goes like this:

/* public/custom.css */
:root {
  --f7-md-surface: #2c3f5c;
  /** more custom overrides. */
}

Now we have a CSS file with some CSS variables, but we can’t just import it in our app.css, because F7 will calculate a theme and inject it into <head> upon init. So our custom values would be overridden by the injected <style>

But we can do something similar. Just make sure that you run this after F7’s colors generation. Inside f7ready() is a good place:

if (store.state.ui.injectCustomCss === true) {
      const customCssResponse = await fetch("custom.css");
      const customCss = await customCssResponse.text();
      const styleTag = document.createElement("style");
      styleTag.innerHTML = customCss;
      document.head.appendChild(styleTag);
}

Hopefully this helps someone in the same situation!

1 Like