Currently dark mode is determined solely by the new Admin theme. This means that when the theme is not in use, any dark mode setting is not respected.
This can become disconcerting when navigating between the front-end and back-end of the site. The Navigation Toolbar will be light, and then when navigating to the admin area, it will be dark.
In my opinion, this isn’t only disconcerting, it's sloppy. Drupal is a premium CMS, and our end users need to feel this.
Proposal
Lets move the dark mode setting (which will be set to auto by default) into a module. We’ll also attach various CSS variables there that can be used within Admin user interfaces.
Questions
What module should this functionality live in?SystemShould the dark mode setting be per user (I think it should be)?YesWhere should the UI (per user) for enabling dark mode be? What is the path?The option for the user should live under /user o user/settings?. That page is a mess now, but let's try not to solve all the things in one issue.Should the UI above include things like accent color, etc?That user UI should not have accent color. At least not as a core feature. That's a whole site/theme feature.What should the UI look like?Page title: "User settings" or "UI user settings" (for example, not a copy expert). Form > Dark mode toogle
Steps
Get signoff from product managers- Place code in the system module (per @catch)
- Place any CSS / JS in core/libraries (per @catch)
- Build UI at user/settings
Issue fork drupal-3606655
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gábor hojtsyAs a Drupal core product manager, I think having first class support for this would be great. Where to put it I'm not sure, it may depend on what other frontend settings we need. Currently the main appearance settings are handled by system module.
Comment #3
kentr commentedMy understanding is that some people struggle with one or the other, so I think there's an accessibility piece to it.
+1 to making it per user.
To me, it would be equally disconcerting / sloppy if the Navigation UI is dark while the rest of the front-end page is light.
Of course, themes can opt to get the setting and use it. However, I think it would be misleading to provide the setting when the theme doesn't use it.
So, maybe include a way for themes to indicate support for it and only present the setting when they do, or display a notice that the theme doesn't support it.
Comment #4
mherchelI think we'd need to phrase the description of the checkboxes to indicate what it affects and does not.
This is a bad idea IMO, because it takes away functionality from the backend. There are certain users who (content editors) who do the majority of the work in the backend.
Comment #5
tolstoydotcomI don't know what "auto by default" means, but please don't force dark mode on people. Here's a starting point:
https://medium.com/@h_locke/why-dark-mode-causes-more-accessibility-issues-than-it-solves-54cddf6466f5
Light mode/day mode should be the default. Those who want dark/night mode can easily select it.
Comment #6
mherchelIt means that Drupal will respect the OS/Browser preferences by default.
Comment #7
kentr commentedI just noticed @mgifford's "Light/Dark Mode Accessibility Best Practices" linked from the a11y office hour notes.
The User override pattern section is pertinent to this issue:
Comment #8
mherchelComment #9
tobiasbOur journey in OpenCulturas with light/darkmode:
We used prefers-color-scheme to set the color for dark-mode.
And I hate it. My system is per default dark, but when a theme is half-baked for a dark-mode, or just not all pages looks good, I want to switch it, without hacking tools.
So I searched for better way and found the contrib module dark_mode_toggle.
We forked the module into OpenCulturas, customized it to allow us to reuse the same code for frontend (block) and backend (Toolbar).
The toggle does also toggle the gin dark/light mode, on some pages I wish I could make an exception. :D
Comment #10
kentr commentedI suggest making that a separate issue.
If we're providing sensible & accessible defaults for light & dark themes, then I view the ability to fine-tune the colors as a lower priority than the ability to control light / dark.
Comment #11
hexabinaerFirst of all: Great move, thanks for emphasizing the importance of an accessibility feature!
IMHO it is not a matter of "fine-tuning". Colors convey meaning and they need to have accessible and understandable contrasts, otherwise we sacrifice a strength of Drupal (overall accessibility) for the sake of one related feature. Futhermore, the design is vital for decision-makers, and that includes dark-mode design.
I'd like to share or learnings from making OpenCulturas dark-mode compatible and what should be considered beyond that for moving ahead in core:
Recommendations
--dr-color-background-lightproperty could foster a lot of low-hanging contributionsHow we approached it
As @tobiasb stated, we started with prefers-color-scheme in OpenCulturas. We already had defined custom properties for all colors and thus it was a no-brainer to re-fill them with adapted colors under this condition. This had put some pressure on setups that inherited from the base theme (the need to adjust colors inherited from the base theme's dark mode to the brand colors).
Then we moved on to a dark-mode toggle (keeping the front-end default theme and Gin as the back-end theme in sync. This adds the class "dark" to the html tag. With
:root.dark { }we are then re-defining the color set, that's it. In one instance I know of, that class was simply globally set because the designer wanted a "dark mode only" theme anyways.Themers may have opinions about our approach to deliver the dark-mode and any objection may be valid.
TL;DR
My point is: let's define standards. Contributed modules and themes need a little preparation.
This may slow down this initiative a bit but it will save so much time for implementers.
Comment #12
hexabinaerAssuming the latter refers to the first: Using logical properties (
inset-block-start,inset-inline-end) instead of physical properties (top,right) would be another standard I'd like to promote. That way we can get rid of[ltr]selectors adding specificity and positioning automatically follows the reading direction.Comment #13
catchSee #3312966: Enforce the use of CSS Logical Properties in core and #3471595: Use CSS Logical Properties in files without [dir=] for logical properties.
Comment #14
mherchel@hexabinaer Note that the admin theme (derived from Gin) already supports and implements dark mode. You can see the current variable structure at https://git.drupalcode.org/project/drupal/-/blob/main/core/themes/defaul... (note this will continue to evolve over the next few months).
We need to think about this now. We'll need to figure out the UI and where the toggle(s) are kept.
Comment #15
mherchelPer @catch in https://drupal.slack.com/archives/C079NQPQUEN/p1783429146306869
Updating IS
Comment #16
mherchelComment #17
mherchelComment #18
kentr commented@mherchel,
I was referring to the implementation of other UI settings within the Admin theme (accent color, focus color, etc).
Planning and designing first, definitely. But please don't delay deployment of the dark mode toggle feature on the deployment of a feature for the other UI settings. They're independent features (though related) and for me the dark mode toggle is higher priority.
@hexabiner,
It sounds like you thought I was referring to dark mode, or dark mode toggling, as fine-tuning. I wasn't.
I was referring to a user choosing personal values for accent color, focus color, etc as fine-tuning. From Webster:
Take heart that Drupal policy states that core changes must pass through the core gates quality gates—which include usability and accessibility—and for accessibility we generally use WCAG 2.2 AA as a standard (even though the accessibility gate still officially declares WCAG 2.1 AA. Some things slip through the cracks, but @mherchel is on the accessibility team (from my POV 🙂).
The accessibility team is already tracking bugs for the new dark theme.
Can't speak for @mherchel, but the reason I voted for per-user selection of dark mode is exactly because of the user choice that you mentioned.
It's not my bailiwick, but I thought there was already an initiative to define standards. IIRC I've seen it discussed.
AFAICT this issue is only about moving the existing controls in the new Default Admin theme out of theme and into a standalone feature.
Comment #19
mgiffordGreat to see this discussion. I love that this is something that we might be able to start providing support for, as this is definitely an accessibility issue (even if it isn't a WCAG issue). It is definitely a best practice.
I would argue for support for a Light/Dark/System mode. Defaulting to the browser default, but over-ruled by user preferences. This could be something stored with a users account, but not all users will have an account, so it should also be something we consider as something we store in a cookie.
I've tried to aggregate some best practices here:
https://github.com/mgifford/accessibility-skills/blob/main/skills/light-...
or, another view of the same content:
https://mgifford.github.io/ACCESSIBILITY.md/examples/LIGHT_DARK_MODE_ACC...
There are so many great guides on light/dark mode, it is hard to keep up.
Every browser and every operating system supports light/dark mode. Users expect it, but it is so poorly done.
It does add complexity to both creating style guides and testing accessibility compliance.
I think partly it is about not just choosing colors, but choosing types of functionality and ideas expressed by the choice of color.
It's done quite well here:
https://www.radix-ui.com/colors
https://github.com/radix-ui/colors
I've developed something like it here:
https://mgifford.github.io/ui-palette-generator/
I tried to move beyond simply looking at the seed value. This code definitely needs work.
But yes, this should be something that is moved out of the Default Admin theme and into something that is supported system-wide.
Comment #20
catchIf this is done, the mode will have to be controlled via JavaScript, otherwise it can't be compatible with page caching. I'm not sure we need to do that in core, especially since core won't provide a UI to switch mode for anonymous users.
Comment #21
kentr commentedTo me, providing this for anonymous users is desirable, so that there's a seamless experience that FE themes can use regardless of whether the user is logged in. For example, the login page should respect the user's preferences also IMO.
We can't make themes use the setting, but since it's a best practice hopefully more and more themes would.
Couldn't it be a theme-able JavaScript widget in a block that FE themes can put in their page header?
Comment #22
mherchelSpoke to User Experience maintainer @ckrina via DM in Slack and have some answers to questions:
Where should the UI (per user) for enabling dark mode be? What is the path?
Should the UI above include things like accent color, etc?
What should the UI look like?
Comment #23
mherchelFrom @kentr
I don't think this is in scope for this issue. This issue is specifically about the admin /editorial experience including the navigation sidebar and top bar when logged in and viewing the site's front-end.
I don't think a block helps front-end themes much. It's extremely simple to code a dark mode toggle button, and have it change a CSS class. The hard part is the front-end to have a theme that supports dark mode. And we don't have the capability to do that.
Comment #24
mherchelI think if we want to do this for general front-end themes or anonymous sessions, we should do this in a followup, since that dramatically increases scope and might not be realistic (though it might be, too).
Comment #25
mherchelUpdating IS.
Comment #26
kentr commentedRegarding frontend: Looks like the Dark Mode Toggle module has an issue related to this: #3554120: Add functionality to persist a user's preferred dark mode setting in their account.
I suggested that they coordinate with the setting that we're talking about in this issue.
Comment #27
nevergoneMaybe? https://www.drupal.org/project/dark_mode_user
Comment #28
mherchelComment #29
jurgenhaasComment #30
jurgenhaasComment #31
jurgenhaas@mherchel regarding the location of that user setting:
Does that have to be a separate tab in the user profile, or could this be included in the user profile form? I mean, there are already settings about language preference, timezone, and other settings that impact the rendering for each user. Selecting their dark mode preference there would feel like a natural choice. Any objections?
Comment #32
kentr commentedSeems like it would be simpler / easier / quicker to put it on the user profile form, also. Doesn't Default Admin already do that when the per-user changes setting is enabled?
Comment #33
jurgenhaasYes, we would build back the settings from default_admin as part of this issue anyway.
Comment #34
mherchelYeah, go the easy route for now. Once its built, I'll run it by the UX maintainers again and they can suggest tweaks.
Comment #35
hexabinaerTrying to keep my points concise this time ;-)
We should offer an option to keep front-end and back-end theme color scheme in sync.
Gin sets a class
gin--dark-modeand only handles the theme's dark mode. What would be soothing for any theme: define and set a theme-agnostic class (dark|light|auto) with any color scheme toggle.Of course, we could leave that to respective theme development but then users would have to make their choice for each theme separately and would probably find different, incompatible solutions.
Comment #36
kentr commented@hexabinaer
Yeah, I was pushing for that also. But it was determined out of scope for this issue.
I'm planning to work on it from another angle.
Comment #37
pdureau commentedHello all,
This topic is related to #3517033: Add a style utility API because, from a design system point of view, dark mode is a "special" case (with the browser and the CSS having a specific knowledge) of mode switching.
Example of other modes:
Ping @grimreaper
Comment #38
mherchelYeah, I have a feeling once that gets in, we'll need to rework the UI a lot to make things usable, accessible, and beautiful.
In the meantime, we'll proceed with adding the setting to the user settings form per @ckrina in #22.
Comment #40
jurgenhaasThe MR now provides the following parts:
data-color-schemeattribute in the html element, defaulting toautoif no setting is available; the user cache context is addedHere are a couple of questions:
<meta name="color-scheme">to the page header? That would tell the browser to render native UI (form controls, scrollbars) in light or dark. Or should that be delegated to the themes?As soon as the approach of this MR gets approved, I'll also add tests to it.
Comment #41
mherchelNo. I don't want to change native front-end UI elements, because the front-end theme might not support dark mode. Themes can rely on the color-scheme CSS property
Lets keep it simple for now, and leave the front-end to a different issue.
Comment #42
mherchelReviewed while on a call today. Changes needed:
html_attributes, lets output acolor_schemevariable in the html.html.twig, and then do the work in that template.Also, tests are failing :)
Comment #43
jurgenhaasAddressed all review items from #42 except for the handling of the html attribute. We've discussed that on Slack:
I left it for now as the code is significantly simpler, and the other use case is (a) unclear and (b) may be achievable anyway.
Also, all tests are now green and this issue is ready for another review.
Comment #44
pdureau commentedI agree
$variables['html_attributes']['data-color-scheme']is too specific. This attributes will depend of the design (system) implementation in the theme.Examples:
data-bs-themeattribute, anywhere, in https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-modedata-themeattribute in https://daisyui.com/docs/themes/data-fr-schemeattribute, only inhtmlelement, in DSFRSometimes this attribute or class can be added only on specific elements, like HTML or BODY, HTML, sometimes anywhere.
That's why I believe ticket must be done and merged hand-to-hand with #3517033: Add a style utility API. Here, we manage:
admin_themeIn #3517033: Add a style utility API, we miss the User specific part, but we manage:
Comment #45
kentr commentedI agree with everyone else about the importance of exposing the setting to frontend themes, with @pdureau about the value of making it more agnostic, and with @mherchal and @jurgenhaas that it can be done later and that there's a workaround available (aka, preprocess, possibly even twig).
I opened #3613964: [PP-1] Make dark mode a first class citizen of Drupal core, Part 2 for making those improvements.
Comment #46
jurgenhaasIn my view, the dark-mode setting is different from all other theme and style settings: it is a global preference that's important for both the admin and the default theme. That's not the case for other preferences. And whether a theme (again, either admin or default, i.e. frontend) will leverage that data attribute or not, is not being enforced.
Therefore, the narrow scope of this issue seems like what would be an important improvement to core in its own right.