Enforce dark theme for logged out users, too

Hi

I am on Nextcloud Hub 8 (29.0.0) and am trying to enforce the dark theme.

This works nicely after having added

'enforce_theme' => 'dark',

to my config.php, however, it only works for logged-in users.

For logged-out users whose browser sends a prefers-color-scheme: light or a neutral/auto one, the login screen is now a repulsive mess as it clashes with my custom theme which is meant to work on top of the dark theme.

So simply the dark theme must be enforced at all times - in no scenario have I use for the light/default theme.

For now, I have modified apps/theming/lib/Themes/LightTheme.php with all of getCSSVariables() copied over from DarkTheme.php, but would very much prefer a cleaner a solution.

Any ideas?

Hi @h0lly

you can and should do that with Custom CSS as you might have used already for the custom theme you mentioned.

Here is how it works:

  • first of all you need the Cusom CSS App. If not yet installed, install and activate it:
App-Id theming_customcss
App-Name Custom CSS
Summary Adjust the Nextcloud theme with custom CSS
Categories customization
Repository GitHub - nextcloud/theming_customcss
Issue-Tracker Issues · nextcloud/theming_customcss · GitHub
Appstore Custom CSS - Apps - App Store - Nextcloud

  • switch themes to ‘dark’.

  • press “Ctrl + Shift + C” to open the browser’s Developer Tools.
    In the “Elements” panel, click on the opening <body> tag to select it.

  • now, in the “Styles” panel of the Developer Tools, you’ll see the CSS rules applied to the selected element.

  • open a text editor that supports find-replace (Ctrl + H) and create a CSS block like this:

body {
    /* declarations to be insterte here */
}
  • go to the two selectors [data-theme-dark] and [data-themes*=dark] in the “Styles” panel.
    right-click on either of the selectors and choose “Copy all declarations”.

  • paste the copied declarations inside the CSS block where marked.

  • once all the declarations are inside, press “Ctrl + H” to open find-replace.
    replace every semicolon (;) with ' !important;'.

  • copy this CSS block and paste it into the Custom CSS window and save it.

Now, the dark theme should always be used, regardless of user preferences or browser defaults.

You could of course take this CSS Block which I created as described above (on Nextcloud 27) but I guess it is better if you understands how to create that… the declarations may have been changed for NC29 and may change in future after upgrades and/or maybe you want to apply your personal CSS to it, so this may only be as an example:

body {
    --color-main-background: #171717 !important;
    --color-main-background-rgb: 23,23,23 !important;
    --color-main-background-translucent: rgba(var(--color-main-background-rgb), .97) !important;
    --color-main-background-blur: rgba(var(--color-main-background-rgb), .8) !important;
    --filter-background-blur: blur(25px) !important;
    --gradient-main-background: var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100% !important;
    --color-background-hover: #212121 !important;
    --color-background-dark: #292929 !important;
    --color-background-darker: #3b3b3b !important;
    --color-placeholder-light: #313131 !important;
    --color-placeholder-dark: #4a4a4a !important;
    --color-main-text: #D8D8D8 !important;
    --color-text-maxcontrast: #8c8c8c !important;
    --color-text-maxcontrast-default: #8c8c8c !important;
    --color-text-maxcontrast-background-blur: #919191 !important;
    --color-text-light: #bfbfbf !important;
    --color-text-lighter: #a5a5a5 !important;
    --color-scrollbar: #3d3d3d !important;
    --color-error: #e9322d !important;
    --color-error-rgb: 233,50,45 !important;
    --color-error-hover: #ed5a56 !important;
    --color-warning: #eca700 !important;
    --color-warning-rgb: 236,167,0 !important;
    --color-warning-hover: #efb832 !important;
    --color-success: #46ba61 !important;
    --color-success-rgb: 70,186,97 !important;
    --color-success-hover: #6ac780 !important;
    --color-info: #006aa3 !important;
    --color-info-rgb: 0,106,163 !important;
    --color-info-hover: #3287b5 !important;
    --color-loading-light: #777 !important;
    --color-loading-dark: #CCC !important;
    --color-box-shadow-rgb: 0,0,0 !important;
    --color-box-shadow: #000000 !important;
    --color-border: #292929 !important;
    --color-border-dark: #3b3b3b !important;
    --color-border-maxcontrast: #646464 !important;
    --font-face: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, Ubuntu, "Helvetica Neue", Arial, sans-serif, "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
    --default-font-size: 15px !important;
    --animation-quick: 100ms !important;
    --animation-slow: 300ms !important;
    --border-radius: 3px !important;
    --border-radius-large: 10px !important;
    --border-radius-rounded: 28px !important;
    --border-radius-pill: 100px !important;
    --default-clickable-area: 44px !important;
    --default-line-height: 24px !important;
    --default-grid-baseline: 4px !important;
    --header-height: 50px !important;
    --navigation-width: 300px !important;
    --sidebar-min-width: 300px !important;
    --sidebar-max-width: 500px !important;
    --list-min-width: 200px !important;
    --list-max-width: 300px !important;
    --header-menu-item-height: 44px !important;
    --header-menu-profile-item-height: 66px !important;
    --breakpoint-mobile: 1024px !important;
    --background-invert-if-dark: invert(100%) !important;
    --background-invert-if-bright: no !important;
    --background-image-invert-if-bright: no !important;
    --primary-invert-if-bright: no !important;
    --color-primary: #0082C8 !important;
    --color-primary-default: #0082C8 !important;
    --color-primary-text: #ffffff !important;
    --color-primary-hover: #046ca4 !important;
    --color-primary-light: #142128 !important;
    --color-primary-light-text: #99cde9 !important;
    --color-primary-light-hover: #1d2a30 !important;
    --color-primary-element: #0082C8 !important;
    --color-primary-element-hover: #046ca4 !important;
    --color-primary-element-text: #ffffff !important;
    --color-primary-element-light: #142128 !important;
    --color-primary-element-light-hover: #1d2a30 !important;
    --color-primary-element-light-text: #99cde9 !important;
    --color-primary-element-text-dark: #ededed !important;
    --gradient-primary-background: linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-hover) 100%) !important;
    --image-background-default: url("/apps/theming/image/background?v=151") !important;
    --color-background-plain: #0082C8 !important;
    --image-background: url("/apps/theming/image/background?v=151") !important;
    --image-logo: url("/apps/theming/image/logo?v=151") !important;
    --image-logoheader: url("/apps/theming/image/logoheader?v=151") !important;
    --image-favicon: url("/apps/theming/image/favicon?v=151") !important;
    --image-logoheader-custom: true !important;
    --icon-add-white: var(--original-icon-add-dark) !important;
    --icon-add-dark: var(--original-icon-add-white) !important;
    --icon-address-white: var(--original-icon-address-dark) !important;
    --icon-address-dark: var(--original-icon-address-white) !important;
    --icon-alert-outline-white: var(--original-icon-alert-outline-dark) !important;
    --icon-alert-outline-dark: var(--original-icon-alert-outline-white) !important;
    --icon-audio-off-white: var(--original-icon-audio-off-dark) !important;
    --icon-audio-off-dark: var(--original-icon-audio-off-white) !important;
    --icon-audio-white: var(--original-icon-audio-dark) !important;
    --icon-audio-dark: var(--original-icon-audio-white) !important;
    --icon-calendar-white: var(--original-icon-calendar-dark) !important;
    --icon-calendar-dark: var(--original-icon-calendar-white) !important;
    --icon-caret-white: var(--original-icon-caret-dark) !important;
    --icon-caret-dark: var(--original-icon-caret-white) !important;
    --icon-category-app-bundles-white: var(--original-icon-category-app-bundles-dark) !important;
    --icon-category-app-bundles-dark: var(--original-icon-category-app-bundles-white) !important;
    --icon-category-auth-white: var(--original-icon-category-auth-dark) !important;
    --icon-category-auth-dark: var(--original-icon-category-auth-white) !important;
    --icon-category-customization-white: var(--original-icon-category-customization-dark) !important;
    --icon-category-customization-dark: var(--original-icon-category-customization-white) !important;
    --icon-category-dashboard-white: var(--original-icon-category-dashboard-dark) !important;
    --icon-category-dashboard-dark: var(--original-icon-category-dashboard-white) !important;
    --icon-category-files-white: var(--original-icon-category-files-dark) !important;
    --icon-category-files-dark: var(--original-icon-category-files-white) !important;
    --icon-category-games-white: var(--original-icon-category-games-dark) !important;
    --icon-category-games-dark: var(--original-icon-category-games-white) !important;
    --icon-category-integration-white: var(--original-icon-category-integration-dark) !important;
    --icon-category-integration-dark: var(--original-icon-category-integration-white) !important;
    --icon-category-monitoring-white: var(--original-icon-category-monitoring-dark) !important;
    --icon-category-monitoring-dark: var(--original-icon-category-monitoring-white) !important;
    --icon-category-multimedia-white: var(--original-icon-category-multimedia-dark) !important;
    --icon-category-multimedia-dark: var(--original-icon-category-multimedia-white) !important;
    --icon-category-office-white: var(--original-icon-category-office-dark) !important;
    --icon-category-office-dark: var(--original-icon-category-office-white) !important;
    --icon-category-organization-white: var(--original-icon-category-organization-dark) !important;
    --icon-category-organization-dark: var(--original-icon-category-organization-white) !important;
    --icon-category-social-white: var(--original-icon-category-social-dark) !important;
    --icon-category-social-dark: var(--original-icon-category-social-white) !important;
    --icon-category-workflow-white: var(--original-icon-category-workflow-dark) !important;
    --icon-category-workflow-dark: var(--original-icon-category-workflow-white) !important;
    --icon-change-white: var(--original-icon-change-dark) !important;
    --icon-change-dark: var(--original-icon-change-white) !important;
    --icon-checkmark-white: var(--original-icon-checkmark-dark) !important;
    --icon-checkmark-dark: var(--original-icon-checkmark-white) !important;
    --icon-circles-white: var(--original-icon-circles-dark) !important;
    --icon-circles-dark: var(--original-icon-circles-white) !important;
    --icon-clippy-white: var(--original-icon-clippy-dark) !important;
    --icon-clippy-dark: var(--original-icon-clippy-white) !important;
    --icon-close-white: var(--original-icon-close-dark) !important;
    --icon-close-dark: var(--original-icon-close-white) !important;
    --icon-comment-white: var(--original-icon-comment-dark) !important;
    --icon-comment-dark: var(--original-icon-comment-white) !important;
    --icon-confirm-fade-white: var(--original-icon-confirm-fade-dark) !important;
    --icon-confirm-fade-dark: var(--original-icon-confirm-fade-white) !important;
    --icon-confirm-white: var(--original-icon-confirm-dark) !important;
    --icon-confirm-dark: var(--original-icon-confirm-white) !important;
    --icon-contacts-white: var(--original-icon-contacts-dark) !important;
    --icon-contacts-dark: var(--original-icon-contacts-white) !important;
    --icon-delete-white: var(--original-icon-delete-dark) !important;
    --icon-delete-dark: var(--original-icon-delete-white) !important;
    --icon-desktop-white: var(--original-icon-desktop-dark) !important;
    --icon-desktop-dark: var(--original-icon-desktop-white) !important;
    --icon-details-white: var(--original-icon-details-dark) !important;
    --icon-details-dark: var(--original-icon-details-white) !important;
    --icon-disabled-user-white: var(--original-icon-disabled-user-dark) !important;
    --icon-disabled-user-dark: var(--original-icon-disabled-user-white) !important;
    --icon-disabled-users-white: var(--original-icon-disabled-users-dark) !important;
    --icon-disabled-users-dark: var(--original-icon-disabled-users-white) !important;
    --icon-download-white: var(--original-icon-download-dark) !important;
    --icon-download-dark: var(--original-icon-download-white) !important;
    --icon-edit-white: var(--original-icon-edit-dark) !important;
    --icon-edit-dark: var(--original-icon-edit-white) !important;
    --icon-encryption-white: var(--original-icon-encryption-dark) !important;
    --icon-encryption-dark: var(--original-icon-encryption-white) !important;
    --icon-error-white: var(--original-icon-error-dark) !important;
    --icon-error-dark: var(--original-icon-error-white) !important;
    --icon-external-white: var(--original-icon-external-dark) !important;
    --icon-external-dark: var(--original-icon-external-white) !important;
    --icon-favorite-white: var(--original-icon-favorite-dark) !important;
    --icon-favorite-dark: var(--original-icon-favorite-white) !important;
    --icon-files-white: var(--original-icon-files-dark) !important;
    --icon-files-dark: var(--original-icon-files-white) !important;
    --icon-filter-white: var(--original-icon-filter-dark) !important;
    --icon-filter-dark: var(--original-icon-filter-white) !important;
    --icon-folder-white: var(--original-icon-folder-dark) !important;
    --icon-folder-dark: var(--original-icon-folder-white) !important;
    --icon-fullscreen-white: var(--original-icon-fullscreen-dark) !important;
    --icon-fullscreen-dark: var(--original-icon-fullscreen-white) !important;
    --icon-group-white: var(--original-icon-group-dark) !important;
    --icon-group-dark: var(--original-icon-group-white) !important;
    --icon-history-white: var(--original-icon-history-dark) !important;
    --icon-history-dark: var(--original-icon-history-white) !important;
    --icon-home-white: var(--original-icon-home-dark) !important;
    --icon-home-dark: var(--original-icon-home-white) !important;
    --icon-info-white: var(--original-icon-info-dark) !important;
    --icon-info-dark: var(--original-icon-info-white) !important;
    --icon-link-white: var(--original-icon-link-dark) !important;
    --icon-link-dark: var(--original-icon-link-white) !important;
    --icon-logout-white: var(--original-icon-logout-dark) !important;
    --icon-logout-dark: var(--original-icon-logout-white) !important;
    --icon-mail-white: var(--original-icon-mail-dark) !important;
    --icon-mail-dark: var(--original-icon-mail-white) !important;
    --icon-menu-sidebar-white: var(--original-icon-menu-sidebar-dark) !important;
    --icon-menu-sidebar-dark: var(--original-icon-menu-sidebar-white) !important;
    --icon-menu-white: var(--original-icon-menu-dark) !important;
    --icon-menu-dark: var(--original-icon-menu-white) !important;
    --icon-more-white: var(--original-icon-more-dark) !important;
    --icon-more-dark: var(--original-icon-more-white) !important;
    --icon-music-white: var(--original-icon-music-dark) !important;
    --icon-music-dark: var(--original-icon-music-white) !important;
    --icon-password-white: var(--original-icon-password-dark) !important;
    --icon-password-dark: var(--original-icon-password-white) !important;
    --icon-pause-white: var(--original-icon-pause-dark) !important;
    --icon-pause-dark: var(--original-icon-pause-white) !important;
    --icon-phone-white: var(--original-icon-phone-dark) !important;
    --icon-phone-dark: var(--original-icon-phone-white) !important;
    --icon-picture-white: var(--original-icon-picture-dark) !important;
    --icon-picture-dark: var(--original-icon-picture-white) !important;
    --icon-play-add-white: var(--original-icon-play-add-dark) !important;
    --icon-play-add-dark: var(--original-icon-play-add-white) !important;
    --icon-play-next-white: var(--original-icon-play-next-dark) !important;
    --icon-play-next-dark: var(--original-icon-play-next-white) !important;
    --icon-play-previous-white: var(--original-icon-play-previous-dark) !important;
    --icon-play-previous-dark: var(--original-icon-play-previous-white) !important;
    --icon-play-white: var(--original-icon-play-dark) !important;
    --icon-play-dark: var(--original-icon-play-white) !important;
    --icon-projects-white: var(--original-icon-projects-dark) !important;
    --icon-projects-dark: var(--original-icon-projects-white) !important;
    --icon-public-white: var(--original-icon-public-dark) !important;
    --icon-public-dark: var(--original-icon-public-white) !important;
    --icon-quota-white: var(--original-icon-quota-dark) !important;
    --icon-quota-dark: var(--original-icon-quota-white) !important;
    --icon-recent-white: var(--original-icon-recent-dark) !important;
    --icon-recent-dark: var(--original-icon-recent-white) !important;
    --icon-rename-white: var(--original-icon-rename-dark) !important;
    --icon-rename-dark: var(--original-icon-rename-white) !important;
    --icon-screen-off-white: var(--original-icon-screen-off-dark) !important;
    --icon-screen-off-dark: var(--original-icon-screen-off-white) !important;
    --icon-screen-white: var(--original-icon-screen-dark) !important;
    --icon-screen-dark: var(--original-icon-screen-white) !important;
    --icon-search-white: var(--original-icon-search-dark) !important;
    --icon-search-dark: var(--original-icon-search-white) !important;
    --icon-settings-white: var(--original-icon-settings-dark) !important;
    --icon-settings-dark: var(--original-icon-settings-white) !important;
    --icon-share-white: var(--original-icon-share-dark) !important;
    --icon-share-dark: var(--original-icon-share-white) !important;
    --icon-shared-white: var(--original-icon-shared-dark) !important;
    --icon-shared-dark: var(--original-icon-shared-white) !important;
    --icon-sound-off-white: var(--original-icon-sound-off-dark) !important;
    --icon-sound-off-dark: var(--original-icon-sound-off-white) !important;
    --icon-sound-white: var(--original-icon-sound-dark) !important;
    --icon-sound-dark: var(--original-icon-sound-white) !important;
    --icon-star-white: var(--original-icon-star-dark) !important;
    --icon-star-dark: var(--original-icon-star-white) !important;
    --icon-starred-white: var(--original-icon-starred-dark) !important;
    --icon-starred-dark: var(--original-icon-starred-white) !important;
    --icon-tablet-white: var(--original-icon-tablet-dark) !important;
    --icon-tablet-dark: var(--original-icon-tablet-white) !important;
    --icon-tag-white: var(--original-icon-tag-dark) !important;
    --icon-tag-dark: var(--original-icon-tag-white) !important;
    --icon-talk-white: var(--original-icon-talk-dark) !important;
    --icon-talk-dark: var(--original-icon-talk-white) !important;
    --icon-template-add-white: var(--original-icon-template-add-dark) !important;
    --icon-template-add-dark: var(--original-icon-template-add-white) !important;
    --icon-timezone-white: var(--original-icon-timezone-dark) !important;
    --icon-timezone-dark: var(--original-icon-timezone-white) !important;
    --icon-toggle-background-white: var(--original-icon-toggle-background-dark) !important;
    --icon-toggle-background-dark: var(--original-icon-toggle-background-white) !important;
    --icon-toggle-filelist-white: var(--original-icon-toggle-filelist-dark) !important;
    --icon-toggle-filelist-dark: var(--original-icon-toggle-filelist-white) !important;
    --icon-toggle-pictures-white: var(--original-icon-toggle-pictures-dark) !important;
    --icon-toggle-pictures-dark: var(--original-icon-toggle-pictures-white) !important;
    --icon-toggle-white: var(--original-icon-toggle-dark) !important;
    --icon-toggle-dark: var(--original-icon-toggle-white) !important;
    --icon-triangle-e-white: var(--original-icon-triangle-e-dark) !important;
    --icon-triangle-e-dark: var(--original-icon-triangle-e-white) !important;
    --icon-triangle-n-white: var(--original-icon-triangle-n-dark) !important;
    --icon-triangle-n-dark: var(--original-icon-triangle-n-white) !important;
    --icon-triangle-s-white: var(--original-icon-triangle-s-dark) !important;
    --icon-triangle-s-dark: var(--original-icon-triangle-s-white) !important;
    --icon-unshare-white: var(--original-icon-unshare-dark) !important;
    --icon-unshare-dark: var(--original-icon-unshare-white) !important;
    --icon-upload-white: var(--original-icon-upload-dark) !important;
    --icon-upload-dark: var(--original-icon-upload-white) !important;
    --icon-user-admin-white: var(--original-icon-user-admin-dark) !important;
    --icon-user-admin-dark: var(--original-icon-user-admin-white) !important;
    --icon-user-white: var(--original-icon-user-dark) !important;
    --icon-user-dark: var(--original-icon-user-white) !important;
    --icon-video-off-white: var(--original-icon-video-off-dark) !important;
    --icon-video-off-dark: var(--original-icon-video-off-white) !important;
    --icon-video-switch-white: var(--original-icon-video-switch-dark) !important;
    --icon-video-switch-dark: var(--original-icon-video-switch-white) !important;
    --icon-video-white: var(--original-icon-video-dark) !important;
    --icon-video-dark: var(--original-icon-video-white) !important;
    --icon-view-close-white: var(--original-icon-view-close-dark) !important;
    --icon-view-close-dark: var(--original-icon-view-close-white) !important;
    --icon-view-download-white: var(--original-icon-view-download-dark) !important;
    --icon-view-download-dark: var(--original-icon-view-download-white) !important;
    --icon-view-next-white: var(--original-icon-view-next-dark) !important;
    --icon-view-next-dark: var(--original-icon-view-next-white) !important;
    --icon-view-pause-white: var(--original-icon-view-pause-dark) !important;
    --icon-view-pause-dark: var(--original-icon-view-pause-white) !important;
    --icon-view-play-white: var(--original-icon-view-play-dark) !important;
    --icon-view-play-dark: var(--original-icon-view-play-white) !important;
    --icon-view-previous-white: var(--original-icon-view-previous-dark) !important;
    --icon-view-previous-dark: var(--original-icon-view-previous-white) !important;
}

Feel free to ask if you have any further questions!


Much and good luck,
ernolf

1 Like

Also see (and upvote) Theming: Force Light or Dark Theme Regardless of System · Issue #41048 · nextcloud/server · GitHub

Thanks a lot ernolf! And good to know that there’s already an issue jtr.

To be honest, I don’t really feel that ernolf’s solution is significantly cleaner than my current workaround where I turned the light theme into a copy of the dark theme by doing a modification to its PHP class. But I wasn’t aware of the existence of the Custom CSS app, good to know!

I think the only really clean solution would be if enforce_theme would apply to logged-out users, too, so hopefully that will be possible at some point in the future.

2 Likes

… but it is.

The php code should be left completely untouched - vanilla - otherwise you’ll end up in the devil’s kitchen with as result, complaints about failing integrity checks, not working updates etc.

:wink:


ernolf

1 Like

Yes, absolutely.

Just saying that overruling every single CSS property of a theme on the fronted with !important when that theme should not even be enabled in the first place is also not particularly elegant.

That’s right, I agree with you absolutely. But as far as I could find out, unfortunately there is no other way to do it in this case, since it is passed in the html of the opening body tag. I tried other more elegant solutions and then I was left with this brute force solution.
If you can find a better solution with one line, even better!

But it is allways better to add 1000 lines of CSS in custom css as changing one character in the php code :wink:


ernolf