roundcube-color-mode-plugin
Generic light/dark/auto color mode preferences for Roundcube skins that advertise dark mode support.
PHP · MIT License · GitHub
Why
Roundcube skins that add dark mode tend to reinvent the same preference
UI and cookie handling each time. This plugin factors that out: it is
intentionally skin-agnostic, ships no theme, and does not rewrite skin
CSS. It just adds a single color_mode preference (light / dark /
auto) that any skin declaring dark_mode_support in its meta.json can
read and act on --
roundcube-skin-classic-lightdark
is one such skin.
Features
- Light / dark / auto preference --
autofollows the browser or OS color scheme viaprefers-color-scheme. - Skin-agnostic -- exposes the setting; the active skin's CSS and templates decide what light/dark actually look like.
- Admin controls -- set a config default and optionally force it, hiding the preference from users entirely.
- Elastic compatibility -- also writes the
colorModecookie that Roundcube's built-in Elastic skin already reads, so it works there too. - Broad localization -- ships translations for Czech, Dutch, English, French, German, Italian, Japanese, Polish, Brazilian Portuguese, Russian, Simplified Chinese, Spanish, Swedish, Turkish, and Ukrainian.
Requirements
- Roundcube with plugin support.
- A skin that declares
dark_mode_supportin itsmeta.json.
Installation
Copy the repository into your Roundcube plugins/ directory as
color_mode:
Enable it in your Roundcube config:
When the active skin has dark_mode_support: true, the plugin adds a
control at:
Admin configuration
Set a default for new users:
Force a value and hide the preference from users:
If no preference has been saved, the plugin defaults to auto.
How skins consume it
Skins read the saved preference in templates:
A typical integration adds an early script, before stylesheets load, that
resolves auto against prefers-color-scheme and stamps a dark-mode or
light-mode class onto <html>:
<script>
try {
(function(mode) {
mode = mode || 'auto';
var media = window.matchMedia
? window.matchMedia('(prefers-color-scheme: dark)')
: {matches: false};
var dark = mode == 'dark' || (mode == 'auto' && media.matches);
document.documentElement.className += dark ? ' dark-mode' : ' light-mode';
})('<roundcube:var name="config:color_mode" />');
} catch (e) { }
</script>
Skin CSS then scopes to those classes:
For Roundcube's built-in Elastic skin, no custom script is needed -- the
plugin writes the colorMode cookie (light/dark, or clears it for
auto) that Elastic already reads via rcmail.env.color_mode.
Troubleshooting
- Setting doesn't appear -- confirm the active skin's
meta.jsonhasdark_mode_support: trueand that the plugin is listed in$config['plugins']. - Setting appears but nothing changes -- the plugin only stores and
exposes the preference; the skin still needs CSS/template support that
reads
config:color_modeor responds to thecolorModecookie. - Setting is hidden -- check whether
color_modeis listed indont_override, which is expected for admin-forced deployments.