DarkColorScheme
How to add a dark color theme to my skin?
Description
PmWiki helper functions for a dark color theme.
Work is underway to enable a dark color theme for the PmWiki-responsive skin. The functions and the user interface can be reused with other skins, if the skin maintainer prefers it.
This page outlines how a custom skin can offer a dark mode with the core functions.
To enable these functions for your skin, add to your skin.php file something like this:
global
$EnableDarkThemeToggle
;# Enable dark theme toggle, Auto theme by default
SDV(
$EnableDarkThemeToggle
, 3);
(Using SDV()
here will allow admins to override this variable from config.php.)
If the skin doesn't have a skin.php file but supports toggling between light and dark themes, a wiki administrator can add
to config.php.
$EnableDarkThemeToggle
= 3;
See $EnableDarkThemeToggle
, it can be 0, 1, 2, or 3.
Core functions
PmWiki 2.3.30 has new functions that make it easy to enable a dark color theme (or scheme). The PmWiki-responsive skin has styles for a dark theme, but the core functions are also available and can be reused in other skins.
The dark theme is toggled automatically by adding or removing a class name "pmDarkTheme" to the <html>
element of the wiki page, and the settings are remembered in local storage on the browser.
This happens in 3 cases:
- a user clicks on a Dark theme label or icon somewhere in the page;
- a user browses to a new page;
- a user has opened multiple tabs and toggles the dark theme in one of them -- in this case all other open tabs are also toggled.
The functions can also activate and deactivate stylesheets from the page if they have the attribute data-theme="dark"
or data-theme="light"
.
There is a theme toggle switch which can be easily inserted either in the skin template, or in a wiki page, header, footer or sidebar. The switch can be just an icon, or it can have a label. You can have more than one toggle switch in a page, any of them toggles the dark theme.
It is also possible to have CSS classNames and WikiStyles displaying and hiding content based on the color theme. All these are in the core and can be enabled (and customized) in other skins.
Most of the core functions are in the file pmwiki/pub/pmwiki-utils.js -- make sure it is updated and enabled (it is by default, per $EnablePmUtils
).
Syntax highlighting
This applies to the syntax highlighting with the core PmWiki-Responsive skin and with other skins.
There are 2 types of syntax highlighting.
One is PmSyntax for the PmWiki markup, and it already includes styles for the dark theme. As usual, you can override the core styles with your own in pub/css/local.css, and feel free to suggest a better color theme at PITS:01497.
The other is WikiStyles#highlight for displaying code from different programming languages. PmWiki uses the HighlightJS library which comes with many light and dark color themes, and the installation code at WikiStyles#highlight can be adapted to load any of them. See below Separate stylesheets per color theme for an explanation of the data-theme="dark" disabled
attributes.
The recent extension Cookbook:CodeHighlight makes it easy to select light and dark color themes for HighlightJS.
Custom skin styles
In the skin.css file, it may be easiest to define all your colors as custom properties or variables.
/* Define the colors for the light theme */ :root { --myskin-color: black; --myskin-bgcolor: white; --myskin-linkcolor: blue; } /* Define the colors for the dark theme */ @media screen { html.pmDarkTheme { --myskin-color: #ccc; --myskin-bgcolor: #111; --myskin-linkcolor: #8ff; /*this is for the input forms, links*/ color-scheme: dark; } } /* Optional: Define styles for the ◪ toggle icon */ .pmToggleDarkTheme { cursor: pointer; } .pmToggleDarkTheme:before { content: "\25ea"; } /* Use the variables in your definitions for texts, backgrounds and links */ body { color: var(--myskin-color); background-color: var(--myskin-bgcolor); } a { color: var(--myskin-linkcolor); } /* Slightly dim embedded images and videos in dark mode */ @media screen { html.pmDarkTheme img, html.pmDarkTheme video { filter: brightness(.8) saturate(.8) contrast(1.1); } } /* Optional: classes to show/hide depending on the theme */ html.pmDarkTheme .onlyLightTheme, html:not(.pmDarkTheme) .onlyDarkTheme { display: none; }
Separate stylesheets per color theme
You can use CSS variables as outlined above, or separate stylesheets that will be enabled or disabled when needed.
Stylesheets that will be toggled need to have the attribute data-theme
with the value either "light" or "dark", and the dark one is initially disabled
:
<!-- Always loaded --> <link rel='stylesheet' href='$SkinDirUrl/skin.css' type='text/css' /> <!-- Only loaded when the theme is light/default --> <link rel='stylesheet' href='$SkinDirUrl/light.css' type='text/css' data-theme="light" /> <!-- Only loaded when the theme is dark, initially disabled --> <link rel='stylesheet' href='$SkinDirUrl/dark.css' type='text/css' data-theme="dark" disabled />
Custom skin template
In the skin template, you can insert something like this at an appropriate position:
<span class="pmToggleDarkTheme" title="$[Toggle dark theme]"></span>
<span class="pmToggleDarkTheme" title="$[Toggle dark theme]"> $[Dark theme]</span>
Note that the first example has an empty element; the icon defined in .pmToggleDarkTheme:before{}
will appear inside it. In the second example the element will display Dark theme with the icon before the label.
Wiki markup in page, header, footer, sidebar
If you prefer adding the toggle icon or label in a wiki page, just use the wikistyle %pmToggleDarkTheme%
:
* %pmToggleDarkTheme% %% (empty wikistyle, icon only) * %pmToggleDarkTheme% $[Dark theme] %% (with label) |
|
You can add this in Site.SideBar, Site.PageActions, or for example in a skin header wiki page.
Any element with the class name "pmToggleDarkTheme" will toggle the dark theme.
In a wiki page, you can use the class names (wikistyles) %onlyLightTheme%
and %onlyDarkTheme%
to indicate parts of the text to be shown only when a theme is enabled:
* Welcome to the %onlyLightTheme% LIGHT %onlyDarkTheme% DARK %% theme! * %item orange onlyLightTheme% Item shows when light * %item yellow onlyDarkTheme% Item shows when dark |
|
Images
On a dark theme, images with white or very light backgrounds may appear too bright, and images with transparent backgrounds and black or very dark lines or text may appear too dark.
One approach is to prepare separate pictures that look better on the dark theme. With PmWiki 2.3.32, wiki administrators can enable a suffix for pictures to be shown when the dark theme is active:
$ImgDarkSuffix
= '-dark';
On the wiki, when using Attach:my-picture.png
, if there is another uploaded picture "my-picture
-dark.png" the latter will be shown on the dark theme.
I don't recommend enabling the $ImgDarkSuffix
variable in the skin -- this is better left to be enabled by the wiki administrators.
A second approach may work for monochrome pictures (black on white or transparent). A skin author may define styles to invert the picture when on the dark theme, or a wiki admin in pub/css/local.css:
@media screen { html.pmDarkTheme #wikitext .dark-image-invert img { filter: invert(.928); } html.pmDarkTheme #wikihead .dark-image-invert img, html.pmDarkTheme #wikisidebar .dark-image-invert img, html.pmDarkTheme #wikifoot .dark-image-invert img { filter: invert(.893); } html.pmDarkTheme .dark-image-invert-100 img { filter: invert(1); } /*100%*/ }
Then in the wiki page, wrap the monochrome picture in the >>dark-image-invert<<
wikistyle.
>>dark-image-invert<< Attach:MonochromePic.png Or a small inline icon Attach:icon.png within text. >><< |
The invert()
values defined above match an inverted white to the background of the wiki elements in the PmWiki-responsive skin.
Notes
See PITS:01497 (Dark color theme) for a discussion or to report any problems.
A recent browser with JavaScript and localStorage enabled is needed; localStorage may be unavailable if the browser is configured to reject cookies.
The dark theme cannot be enabled by default, and a browser/OS preference is not detected (yet). The theme is toggled per-user and the user choice should be remembered by the browser on subsequent visits.
If a wiki extensively uses WikiStyles directly setting colors and backgrounds (instead of CSS class names), these styles may not look great on the dark theme. For best experience and easier maintenance, in your wikistyles use CSS class names that can be redefined in the stylesheet.
Change log / Release notes
- 2024-02-29 Added
$ImgDarkSuffix
. - 2024-01-23 Added
$EnableDarkThemeToggle
. - 2024-01-22 Added section Core functions, update Notes.
- 2024-01-21 Added section Syntax highlighting, Separate stylesheets per color theme, update CSS.
- 2023-12-20 First draft.
See also
Contributors
- Written and maintained by Petko.
Comments
See discussion at DarkColorScheme-Talk
User notes? : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.