workgroup
Since Django 3.2 the built-in admin app comes with built-in support of dark mode css styles. Many developer use it - also when evaluating software. django CMS uses the admin for front-end editing, page admin and so forth.
Add names here
Fabian
โ Done, PR merged and released.
โ๏ธ Done, PR created and reviewed.
โ๏ธ Work in progress
status | date | description |
---|---|---|
โ | 27.03.2022 | Dark mode for djangocms-admin-style |
โ | 04.04.2022 | Dark mode for djangocms-text-ckeditor |
โ๏ธ | 12.03.2022 | Dark mode for django CMS v3 |
โ๏ธ | xx.xx.xxxx | Guidelines for admin styles in CMS apps |
โ๏ธ | xx.xx.xxxx | Dark mode for djangocms-alias |
โ๏ธ | xx.xx.xxxx | Dark mode for djangocms-versioning |
โ๏ธ | xx.xx.xxxx | Dark mode for django CMS v4 |
Main points:
lighten
, darken
, and rgba
which do not work with css variables by css filters (e.g., brightness()
)The django CMS core styling uses a set of grayscale colors. See cms/static/cms/sass/settings/_cms.scss
These are the colors designed for light mode:
Name | Color | Variable name |
---|---|---|
$white |
#ffffff | --dca-white |
$black |
#000000 | --dca-black |
$color-primary |
#0bf | - |
$color-danger |
#669933 | - |
$color-warning |
#ff0000 | - |
$gray |
#666 | --dca-gray |
$gray-lightest |
#f2f2f2 | --dca-gray-lightest |
$gray-lighter |
#ddd | --dca-gray-lighter |
$gray-light |
#999 | --dca-gray-light |
$gray-darker |
#454545 | --dca-gray-darker |
$gray-darkest |
#333 | --dca-gray-darkest |
$gray-super-lightest |
#f7f7f7 | --dca-gray-super-lightest |
The dca-
prefix is used to avoid conflicts with other css variables and stands for "django CMS association".
The admin frontend pulls the style from django admin styles and - if present - from djangocms-admin-style. Django itself also uses css variables to implement admin mode, these can be used as dark mode-aware fall-back colors.
Variable name | Color | Fallback | Color |
---|---|---|---|
--dca-white |
#ffffff | --body-bg |
#ffffff |
--dca-black |
#000000 | --body-fg |
#303030 |
--dca-gray |
#666 | --body-quiet-color |
#666 |
--dca-gray-lightest |
#f2f2f2 | --darkened-bg |
#f8f8f8 |
--dca-gray-lighter |
#ddd | --border-color |
#ccc |
--dca-gray-light |
#999 | --close-button-bg |
#888 |
--dca-gray-darker |
#454545 | ||
--dca-gray-darkest |
#333 | ||
--dca-gray-super-lightest |
#f7f7f7 | ||
--dca-primary |
#00bbff | --primary |
#79aec8 |
If at all posible only the first four fallbacks should be used. Other django admin css variables might be overwritten by a theme and might not represent a level of gray.
Three modes may be selected:
data-color-scheme="light"
to the document's html
tag, i.e., <html data-color-scheme="light">
.data-color-scheme="dark"
to the document's html
tag.color
, background
etc. styles where possible and meaningfulvar(--dca-color-var, var(--fallback-color-var, #xxxxxx))
where #xxxxxx
represents the light version of the color.@media (prefers-color-scheme: dark)
since they would ignore forced settings to light or dark.Third party libraries might present an edge case: CKEditor 4, for example, does not offer dark mode compatible skins for djangocms-text-ckeditor. A similar situation exists for the code editor Ace which is used by djangocms-frontend or djangocms-snippet. Two options exist:
For CKEditor 4 we patch the standard skin during the build process of the editor. The patch replaces color literals by var(--dca-color-var, var(--fallback-color-var), #color)
in the already minified css. See this python scrippt.
For ACE dark color designs exist. When invoking the editor in javascript we check for the preferred mode (with the drawback that after invoking the editor a change in preference by the user is only reflected after a reload of the page):
โโโโโโโ // init editor with settings
โโโโโโโ var editor = ace.edit(div[0]);
โโโโโโโ var darkMode = False;
โโโโโโโ
โโโโโโโ if (window.parent.CMS.API.Toolbar.get_color_scheme) {
โโโโโโโ darkMode = window.parent.CMS.API.Toolbar.get_color_scheme() === 'dark';
โโโโโโโ } else {
โโโโโโโ // django CMS pre-3.11
โโโโโโโ darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
โโโโโโโ }
โโโโโโโ if (darkMode) {
โโโโโโโ editor.setTheme('ace/theme/tomorrow_night');
โโโโโโโ } else {
โโโโโโโ editor.setTheme('ace/theme/github');
โโโโโโโ }
Of course, an improved implementation will not inline the dark and light themes as literals but revert to settings to allow for better configurability.