Opened 19 months ago

Last modified 8 months ago

#33689 assigned Cleanup/optimization

Django theme color variables are inconsistently named and poorly documented

Reported by: Murray Chapman Owned by: stimver
Component: contrib.admin Version: 4.0
Severity: Normal Keywords: theme dark mode color variables documentation
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I have written a number of UI customizations for Django and it's difficult to be sure I've done the right thing because the color variables names and usage philosophy is inconsistent.

Consider these variables:

  --body-fg: #333;
  --body-bg: #fff;
  --body-quiet-color: #666;
  --body-loud-color: #000;

The first two are obvious since they are paired, but it's not clear the quiet and loud colors are meant to be used as foreground/text or background colors.

Other variables such as --primary and --selected-row have no suffix and it's unclear how they're supposed to be used.

The --message-*-bg variables aren't pared with any -fg equivalents; this creates an undocumented dependency on which text colors they are compatible with or even use. Without -fg equivalents it's also impossible to precisely control.

I've also seen some variables used as both text and background colors in the Django CSS.

Also: since the scope of these variables is :root it's probably a good idea to prefix them all with --django to avoid collisions with third-party CSS which may accidentally cause name collisions.

The documentation for the theming feature just points developers at the CSS file but doesn't give any guidance on the philosophy or mechanism. It would really help if there was a consistent naming scheme and style guide for using them.

Change History (4)

comment:1 Changed 19 months ago by Carlton Gibson

Easy pickings: unset
Keywords: documentation added
Triage Stage: UnreviewedAccepted

OK, lets accept as a documentation ticket to begin: if we can get the skeleton of a style-guide in place, it'll be easier to see/justify renaming variables.

I've removed the Easy pickings flag as I think is likely a medium sized project to do well. (Out of interest, were you proposing to create the style guide? 🙂)

comment:2 in reply to:  1 Changed 19 months ago by Murray Chapman

Replying to Carlton Gibson:

(Out of interest, were you proposing to create the style guide? 🙂)

This should probably be done by someone with a modicum of visual design talent, which I don't have 🙂, and familiarity with the Django admin's existing visual style.... which I don't see documented or described anywhere. There are probably people more passionate and experienced about this than me, so I'll defer to any of them.

I can offer some guidance based on a long career building websites, though:

(Not suggesting that these need to be done as part of this ticket, but they should be kept in mind)
  • be mindful that visual theme overlaps with usability, accessibility, brand identity, and widget design
  • there are things beyond color that should be made variables (e.g. margins; border width/radius)
  • variables should be consistently named, and refer to concepts rather than specific use cases or colors
  • it should be easy to determine the target of a color: Text? Background? Border? Shadow?
  • text/background color variables should always be paired (current implementation makes assumptions about text/background pairings that are difficult to deduce)
  • every color should be a variable (some are still hardcoded)
  • every variable should be documented and an example given
  • accessibility issues like visual impairment and color blindness should be considered (good work already done on improving visual contrast)
  • usability best practices strongly discourage using color alone to communicate meaning or state (e.g. don't use a red background and assume people will know that means "error". Should be accompanied by verbiage or an icon)
  • very helpful for developers would be a visual "crib sheet" that shows all colors/widgets on a single web view. Ideally this would be part of contrib.admin (so developers can test theme changes) as well as in the online documentation
  • future commits to stylesheets should be policed for hardcoded colors, ideally via automation
  • technical designs should be mindful of ease of maintenance and future expansion (e.g. introduction of other CSS variables for things like border widths)

Django has excellent documentation and a high-quality/consistent visual design; I'm hoping we can get this formally defined/declared somewhere so plugin/extension authors can build consistently on top of it.

comment:3 Changed 13 months ago by Michael

I agree with the original poster. It takes a bit of trial and error to skin the admin. Sometimes you skin something in one situation, and then the same variable is used elsewhere, and then it clashes (doesnt work visually) down the line. I also have had clashes with Django CSS custom property names.

Just a side comment: In the web framework context, it is a common pattern to use a two letter acronym for namespacing, e.g. tw for tailwind, ng for angular. We could prefix all variables with dj. e.g. --dj-body-fg.

Another solution would be to place properties under a top level admin container instead of :root, e.g.

.admin-top-level-container {
  --body-fg: black;

comment:4 Changed 8 months ago by stimver

Owner: changed from nobody to stimver
Status: newassigned
Note: See TracTickets for help on using tickets.
Back to Top