SAML2 Login Dark mode
Open
Beginner friendly
Nobody has claimed this yet.
Product Area: Settings - Auth
Waiting for: Product Owner
- Dominant language
- Python
- Stars
- 44.8k
- Forks
- 4.9k
- Avg merge
- 21h 23m
- Merged PRs (30d)
- 607
Description
Problem Statement
It would be great to have a Dark mode for this screen, as it is a jarring experience for users using Dark mode.
Solution Brainstorm
As a test you can inject this chrome snippet to see what it could look like
const style = document.createElement('style');
style.textContent = `
@media (prefers-color-scheme: dark) {
body.auth {
background: #24202b;
color: #e9e5eb;
}
body.auth a {
color: #a396e8;
}
body.auth .pattern-bg {
background-color: #24202b;
opacity: 0.1;
}
body.auth .box {
background: #2f2937;
border-color: #453e4f;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
}
body.auth .box .box-header {
background: #39323f;
color: #e9e5eb;
border-bottom-color: #453e4f;
}
body.auth .auth-container.border-bottom {
border-bottom-color: #453e4f;
}
body.auth .auth-provider-column {
border-left-color: #453e4f;
}
body.auth .auth-container .help-center-link {
color: #a396e8;
}
body.auth .auth-footer .secondary {
color: #b5b0bd;
}
body.auth .auth-footer .secondary:hover {
color: #e9e5eb;
}
body.auth .nav-tabs > li > a {
color: #b5b0bd;
}
body.auth .nav-tabs > li > a:hover,
body.auth .nav-tabs > li > a:active,
body.auth .nav-tabs > li > a:focus {
color: #e9e5eb;
}
body.auth .nav-tabs > li.active a,
body.auth .nav-tabs > li.active a:hover,
body.auth .nav-tabs > li.active a:focus {
color: #e9e5eb;
}
body.auth .form-control {
background: #24202b;
border-color: #453e4f;
color: #e9e5eb;
box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.12);
}
body.auth .form-control::placeholder {
color: #b5b0bd;
}
body.auth .form-control:focus {
border-color: #6c5fc7;
box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.12), 0 0 6px rgba(108, 95, 199, 0.5);
}
body.auth .form-control:-webkit-autofill,
body.auth .form-control:-webkit-autofill:hover,
body.auth .form-control:-webkit-autofill:focus {
-webkit-text-fill-color: #e9e5eb;
box-shadow: inset 0 0 0 1000px #24202b;
caret-color: #e9e5eb;
}
body.auth .help-block {
color: #b5b0bd;
}
body.auth .btn-default {
color: #e9e5eb;
background: #39323f;
border-color: #453e4f;
}
body.auth .btn-default:hover {
color: #e9e5eb;
background: #413a48;
border-color: #51495d;
}
body.auth .btn-default:hover:active,
body.auth .btn-default:focus,
body.auth .btn-default:active,
body.auth .btn-default.active,
body.auth .btn-default.active:hover {
color: #e9e5eb;
background: #342e3a;
border-color: #51495d;
}
body.auth .provider-logo.github,
body.auth .provider-logo.rippling {
filter: invert(1);
}
body.auth .alert-danger {
background: #3b2733;
border-color: #6b3a44;
color: #f3b0b5;
}
body.auth .error,
body.auth .has-error .help-block,
body.auth .has-error .control-label {
color: #f3b0b5;
}
body.auth .has-error .form-control {
border-color: #6b3a44;
}
body.auth .has-error .form-control:focus {
border-color: #6b3a44;
}
}
`;
document.head.appendChild(style);
To make this permanent
static/less/auth.less
/**
* Auth Dark Mode
* ============================================================================
* These pages are rendered by Django rather than the React app, so the body
* never gets a `.theme-*` class to key off of. Visitors are also usually signed
* out, meaning there is no stored theme preference to read. Follow the OS
* setting instead.
*/
@auth-dark-bg: #24202b;
@auth-dark-surface: #2f2937;
@auth-dark-surface-raised: #39323f;
@auth-dark-border: #453e4f;
@auth-dark-content: #e9e5eb;
@auth-dark-content-muted: #b5b0bd;
@auth-dark-link: #a396e8;
@auth-dark-danger-bg: #3b2733;
@auth-dark-danger-border: #6b3a44;
@auth-dark-danger-content: #f3b0b5;
@media (prefers-color-scheme: dark) {
body.auth {
background: @auth-dark-bg;
color: @auth-dark-content;
a {
color: @auth-dark-link;
}
// The tiled pattern is light line art, so once the backdrop behind it is
// dark it reads as a subtle highlight rather than a wash of gray.
.pattern-bg {
background-color: @auth-dark-bg;
opacity: 0.1;
}
.box {
background: @auth-dark-surface;
border-color: @auth-dark-border;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
}
.box .box-header {
background: @auth-dark-surface-raised;
color: @auth-dark-content;
border-bottom-color: @auth-dark-border;
}
.auth-container.border-bottom {
border-bottom-color: @auth-dark-border;
}
.auth-provider-column {
border-left-color: @auth-dark-border;
}
.auth-container .help-center-link {
color: @auth-dark-link;
}
.auth-footer .secondary {
color: @auth-dark-content-muted;
&:hover {
color: @auth-dark-content;
}
}
.nav-tabs > li > a {
color: @auth-dark-content-muted;
&:hover,
&:active,
&:focus {
color: @auth-dark-content;
}
}
.nav-tabs > li.active {
a,
a:hover,
a:focus {
color: @auth-dark-content;
}
}
.form-control {
background: @auth-dark-bg;
border-color: @auth-dark-border;
color: @auth-dark-content;
box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.12);
&::placeholder {
color: @auth-dark-content-muted;
}
&:focus {
border-color: @purple-light;
box-shadow:
inset 0 2px 0 rgba(0, 0, 0, 0.12),
0 0 6px rgba(108, 95, 199, 0.5);
}
// Chrome paints autofilled inputs with an opaque light background that
// ignores `background-color`; an inset shadow is the only way to cover it.
&:-webkit-autofill,
&:-webkit-autofill:hover,
&:-webkit-autofill:focus {
-webkit-text-fill-color: @auth-dark-content;
box-shadow: inset 0 0 0 1000px @auth-dark-bg;
caret-color: @auth-dark-content;
}
}
.help-block {
color: @auth-dark-content-muted;
}
.btn-default {
color: @auth-dark-content;
background: @auth-dark-surface-raised;
border-color: @auth-dark-border;
&:hover {
color: @auth-dark-content;
background: lighten(@auth-dark-surface-raised, 4);
border-color: lighten(@auth-dark-border, 6);
}
&:hover:active,
&:focus,
&:active,
&.active,
&.active:hover {
color: @auth-dark-content;
background: darken(@auth-dark-surface-raised, 3);
border-color: lighten(@auth-dark-border, 6);
}
}
// Both marks are solid black and would disappear against a dark button.
// Every other provider logo is full color and needs no adjustment.
.provider-logo.github,
.provider-logo.rippling {
filter: invert(1);
}
.alert-danger {
background: @auth-dark-danger-bg;
border-color: @auth-dark-danger-border;
color: @auth-dark-danger-content;
}
.error,
.has-error .help-block,
.has-error .control-label {
color: @auth-dark-danger-content;
}
.has-error .form-control {
border-color: @auth-dark-danger-border;
&:focus {
border-color: @auth-dark-danger-border;
}
}
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with static/less/auth.less, which styles the Django-rendered authentication screens, and compare the existing light-mode selectors with the dark-mode behavior shown in the issue. Implement the prefers-color-scheme rules there, then run the relevant frontend or asset-build checks and verify the authentication screens in a dark browser setting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, django, python
- Domain
- authentication, design, frontend
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100