<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=1195114&amp;fmt=gif">
Mendix
5 February 2021, last update 17 June 2021

How to add a dark theme to your Mendix app in 5 minutes?

Yes, I know the title seems a bit too good to be true. Every web app has a lot of custom styling and company branding that needs to be considered when designing a dark theme. Normally, this process takes a lot of time. You have to pick the right color palette, then refactor the CSS to support two different color themes. As a consequence almost the entire CSS has to be rewritten, because honestly nobody truly plans for such scenarios in advance.

So how can all of this possibly be done in just five minutes? Easy, follow the steps:

  1. Add the Mendix Dark Theme module from the app store to your Mendix app
  2. Add a nanoflow button (or three) to a layout, navigation or page of your choice
  3. From the nanoflow call the java script action  JSA_ApplyTheme
  4. Run your app and see the results.

I went through these steps for the app store app, Atlas UI Resources. You can find the results at darkreader. This is a great sample app for a dark theme since it has all Mendix components. You can easily see how they all look in a dark theme mode.

Hopefully you find this module useful, and it helps you build better Mendix apps.

"Wait, wait... you must be asking how this module is actually working. The answer is simple: Magic"

Hmm. It seems like you really want to know. Ok, brace yourselves this might get technical.

The magic

Let me tell you the full story.

One nice winter day I was looking for a way to make the Duolingo website more friendly for my eyes (I'm learning Dutch in case you were wondering). In the past, I have tried several dark theme extensions for chrome and my experience with them was not great. But this time I stumbled upon an extension that worked quite well. Then I thought how much I am tormented every day by all the light Mendix websites like sprintr, appstore and the forum. Turns out the extension was even better for Mendix websites which do not have a ton of animations or complicated styling.

Darktheme_1

Darktheme_2

My first idea was to share this extension with everyone, but I am aware that most web users are not thrilled at the idea to install a third party dependency that has access to all their website content. Luckily, after a closer look at the extension it turned out to be completely open source. It even comes with a javascript API so that it can be used from a website without the Chrome extension.

So the module is just a wrapper around this open source library - Darkreader. There was no magic after all 😢

Even though dark reader works pretty well there might be some widgets or pages that need to be tweaked to look even better. Here are a handful of tips, based on my experience of adding dark theme support to a real, working-in-production Mendix app.

 

Tips


  • Start by choosing the primary foreground and background colors. Dark reader will come up with suggestions for you but if picking specific colors based on the company branding will probably look much better. These can be adjusted in the theme options.
  • Use the overall settings to tweak the theme to your liking. In my personal opinion, setting grayscale to 0.25 dims most of the very strong colors that Mendix tends to have to an acceptable level without sacrificing too much.
  • Invert overly dark or bright images. This can be done by specifying a css selector for the image and passing it in the dynamic theme fix. Check github for examples. Alternatively, some JPGs and PNGs may be replaced with glyphicons, fontawesome or other technologies that support color changing. That is probably yet another reason to prefer icon fonts over PNGs.
  • It is a good idea to store user preferences on the  Account  object. Feel free to use the  Enum_Theme  enumeration as an attribute type. If you are looking for ways to run the javascript action on load, without having the user click a button, consider the Microflow timer widget. Fun fact, it also supports nanoflows.
  • Add CSS overrides sparingly. When an element does not look good in a dark theme it is easy to throw in a dark theme css with  !important  and call it a day. But after more carefully checking some offending elements I found that often they had bad css practices like hard-coded inline background colors etc. As it turns out this interferes with dark reader. In that case it was better to refactor the CSS and let dark reader do its thing. I guess you can add dark theme support on the long list of reasons to avoid inline styles.
  • When applying CSS overrides make use of dark reader CSS variables. This will make it much easier to switch the background and foreground colors in the future. A list of available CSS variables:  darkreader-neutral-background, darkreader-neutral-text, darkreader-selection-background, darkreader-selection-text.

Performance

Dark reader works by constantly scanning your website and generating appropriate dark themed css rules. This can slow down the client especially if there is a lot of dynamic content like animations and charts. There are actually two ways to instruct dark reader not to scan such content:

  • ignore image analysis - is specifically for background images
  • ignore inline style - will not scan the inline (hard-coded) style of elements (this is specifically for elements that are generated by charting libraries that tend to use a lot of inline styling)

Another, much more extreme option is to ditch javascript entirely and rely only on the generated CSS. I would only recommend doing this if you are sure that your website will not change much in the future, i.e. if the UI was pretty stable for quite some time (think months).

If this is the case for your app, then you can run the javascript locally and export the generated CSS.

DarkReader.exportGeneratedCSS()

You can then add this css to  index.html  and toggle it with javascript via the  disabled  attribute.

// index.html, css is disabled by default
// <link id="darkreader" href="darkreader-generated.css" disabled="disabled"/>

// javascript snippet
var el = document.getElementById('darkreader');
var osPreferenceIsDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if ( theme == "Dark" ||
(theme == "System" && osPreferenceIsDark ) ) {
el.removeAttribute("disabled");
} else {
el.setAttribute("disabled", "disabled");
}

 

Conclusion

In this blog post we looked at how to add dark theme support to a Mendix app without having to completely refactor the CSS and spend days in design meetings. My personal hope is that we will see more and more Mendix apps supporting dark theme, especially ones that are publicly available.

Until then, remember you can always use the extension: https://darkreader.org/ 

If you find the module or the extension useful consider donating to https://darkreader.org/ They truly did a great job with it and deserve our respect.

 

Andrej Gajduk
Andrej Gajduk is a consultant at Mansystems with over 7 years of experience in software development. Currently, he is a lead developer for Application Test Suite.

No relevant post found