Skip to content

Allow themes to override chrome with custom properties - #108

Open
ghalse wants to merge 1 commit into
simplesamlphp:release-2.6from
ghalse:patch-themevar-r26
Open

Allow themes to override chrome with custom properties#108
ghalse wants to merge 1 commit into
simplesamlphp:release-2.6from
ghalse:patch-themevar-r26

Conversation

@ghalse

@ghalse ghalse commented Aug 18, 2026

Copy link
Copy Markdown

This pull request moves all of the colours related to the default red SimpleSAMLphp into CSS custom properties so they can be more easily overridden by themes. This is useful to people who are maintaining their own theme modules, but also allows for very lightweight theming without a module.

Consider adding the following to templates/_head.twig:

<style>
 :root {
   --ssp-chrome-primary-background: #0e6d32;
   --ssp-chrome-transition-background: #21a754;
   --ssp-chrome-secondary-background: #0a5a28;
   --ssp-chrome-text-shadow: #02260d;
   --ssp-chrome-menu-active: #0e6d61;
  }
</style>

That alone becomes sufficient to match corporate brand colours centred on the #0e6d32 green, with no further changes required anywhere in SimpleSAMLphp. The result of the above is:

image

Because templates/_head.twig is optionally included by _header.twig and is not part of the stock distribution, it doesn't get overwritten, and we only need to remember to port one file in addition to the config between versions.

Looking at what our own users of SSP do, and what we did with the SSP theme generator, I suspect this change addresses the many cases in a much more straightforward way.

This resolves #104

notes on implementation

old browsers

I've erred on the conservative side and kept support for legacy browsers that don't support CSS custom properties via var(). https://caniuse.com/css-variables suggests that these are things like IE11, old webview implementations, and notably Opera Mini.

The way the fallback works is the current colours are first statically declared (sometimes with the existing SCSS variables), and then overridden with a var(), like this:

color: $chromeText;
color: var(--ssp-chrome-menu-text);

If we don't care about the older browsers, we can remove the first static declaration and rely only on var().

only chrome

I've not tried to parameterise all colours, only those relevant to the header and footer chrome and the red colour scheme reflected in the pure-button-red class.

There are more properties available than declared in the initial :root simply because I've tried to avoid overloading uses. Most are defined in terms of their existing default or in terms of one of the properties that is in :root. This is an attempt to keep it simple for people who're looking to just override the red colour, but allow some flexibility for people who want to tweak the active state, etc.

@monkeyiq

Copy link
Copy Markdown

I like this idea. Reasonably simple colour changes for sites to make the login experience blend more with the enclosing site.

@monkeyiq

Copy link
Copy Markdown

After a bit of efforts getting the assets to build and unpack into my sspdev env I found that the green didn't come through for me.

After more tinkering with things I noticed that Configuration.php sets the DEFAULT_SECURITY_HEADERS to have style-src not include 'unsafe-inline'. Adding that I saw the green banner.

The _head.twig is being inlined into the base.twig so the <style> tag is declared there and it leads to the interaction with Content-Security-Policy.
https://github.com/simplesamlphp/simplesamlphp/blob/df5020bead3a7b894d40fccdde6e0989471608a7/templates/base.twig#L12

Perhaps we could have the content :root { --ssp-chrome-primary-background: #0e6d32;... inside a css file which gets linked if it exists?

@tvdijen

tvdijen commented Aug 20, 2026

Copy link
Copy Markdown
Member

Perhaps we could have the content :root { --ssp-chrome-primary-background: #0e6d32;... inside a css file which gets linked if it exists?

That would be the theme's CSS-file, right? Or is this something that also needs to be loaded on a vanilla deployment using the SSP-theme?

@ghalse

ghalse commented Aug 20, 2026

Copy link
Copy Markdown
Author

The CSP issue is slightly out of scope for this pull request and can be resolved in a couple of different ways1. But from the perspective of this pull request, the CSP is under the user's control in config/config.php and can be worked around. It can also be avoided by adding a link to an external stylesheet in _head.twig that's simply hosted statically on a web server.

This pull request creates a framework to simplify theme colour changes, either in _head.twig or in a theme's custom CSS. It doesn't dictate how those changes should happen :).

I have two different implementations against versions of SSP 2.5.x patched with this change:

  1. The simpler case described here in _head.twig. In that case, I've managed to completely abandon a theme module I've maintained since 2018 in favour of a small bit of Ansible. It comes at the cost of understanding the CSP implications, but because I control config.php too (also in Ansible), it's easy.

  2. The more complex case is in a theme module itself. In that case I've managed to reduce my custom CSS substantially by simply setting the right colours in the theme's CSS. That's good for my maintainability, because I don't have to merge in changes every time the upstream updates.

Both those examples have live versions I'm happy to share, but would rather not post in GitHub.

Footnotes

  1. IMHO the right way to do this is with nonces, and I do that myself. I've thought about suggesting adding a nonce implementation in SSP that filters to Twig (I do this in the second example). That would eliminate the inline problem entirely, even for other modules. But again, overly complicating this PR :)

@monkeyiq

Copy link
Copy Markdown

Grr, after chasing this and wondering if it was how I was building the asset bundle etc, I should have stepped back and thought yeah "It can also be avoided by adding a link to an external stylesheet in _head.twig that's simply hosted statically on a web server.". That is the solution I am happy with for this PR. Simple but I was hyper focused on other things and didn't step back for a moment to get that part.

Looking into nonces is interesting but certainly something for future PRs.

I can see the point about being able to define just a few colours to make it work better for a site. I will also look at having some docs in the ssp/docs tree to describe this once it is merged. And also mention the potentially frustrating outcome of trying to put the style inline in _head.twig.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants