Over the last 3+ months since we enabled user-driven themes for the Developer Canary Program (see post) we have added theming support for nearly all Confluence Cloud experiences that were previously missing. Additionally we have gathered feedback, polished existing token use, and even added a theming toggle in Presenter Mode.
As a reminder, apps that have not yet adopted theming will render poorly for users who have chosen to use dark mode. In our early rollout metrics, we’ve consistently seen over 60% of users turn to dark mode over light mode. See details below for how to adopt themes if you need more information.
We are also ready to share some timelines and details about the full rollout of theming to all customers as a Beta feature and then moving theming into General Availability (GA).
Timeline
As early September 12 as all continuous release customers will have access to theming as a Beta feature and Light theme will become the new default theme. Customers on release tracks will get access to theming as part of the next bundled release after that.
Over the next couple weeks we will be monitoring feedback and working on some solutions for items we’ve received consistent feedback on:
dark mode support for admin-driven color scheme settings which affect the top navigation background color
better legacy editor/pages support in dark mode
As early as the end of September, we will transition into a phase of General Availability (GA) which indicates to all customers and you, our Marketplace partners, that we consider theming to be ready for mass, stable use. We expect that there will still be a few areas to refine but none that are preventing use of themes.
At the end of October, we plan to remove Original as a “theme” option - Light will remain the default.
We’ve consciously chosen Light to become the new default as opposed to Match browser. This helps ensure more users have a good experience when viewing apps that don’t yet have support for dark mode.
Adopting Themes
In case you missed some of our earlier communication about how to add theming to your apps, we have recently finalized some documentation which formally solidifies theming in Confluence and makes no changes to the approach we’ve previously outlined.
Themes are driven by the Atlassian Design System’s “Design Tokens” which you can read more about and reference here.
Connect
Connect apps should follow the approach as detailed in Theming Connect Apps. In particular, Connect apps would need to invoke window.AP.theming.initializeTheming().
Invoke window.AP.theming.initializeTheming() as early as possible in your application startup to avoid any “flashing” of nonthemed elements before theming is applied. This will apply the appropriate data-theme and data-color-mode attributes to the tag based on the theme defined by Confluence.
Forge
Forge apps using UI Kitwithout any color customizations will automatically inherit tokens.
Forge apps using Custom UI will need to apply design tokens as described above. The implementation follows closely to what was described for Connect apps. See more about Theming Forge Apps. In particular, Forge Custom UI apps would need to invoke view.theme.enable():
Invoke view.theme.enable() as early as possible in your application startup to avoid any “flashing” of nonthemed elements before theming is applied. This will apply the appropriate data-theme and data-color-mode attributes to the tag based on the theme defined by Confluence, consistent with the solution described above for Connect apps.
Questions/Feedback
For general feedback about the look and feel of themes, please use the feedback mechanism within the theme switcher within Confluence.
If you have questions about how to implement theming in your apps, please comment here in this topic.
If you have already added theming support or are planning to do so soon, please share your progress - we’d love to hear about it!
We are implementing the theming, and have a question about the content security policy.
When we call window.AP.theming.initializeTheming();, new styles are loaded through all.js. We can allow this style loading in all.js by using 'unsafe-inline' in the CSP, but this is problematic with style injection attacks. What CSP is recommended to allow the style loading in all.js?
Just to check, are you still tracking a fix for the flash of white background for popup dialogs are that are opened via Connect webItems->target->type=dialog (and with chrome=false)?
@scott.dudley I investigated this particular use case and also saw the brief flash of unthemed background before theming was applied. This is because the dialogs are rendering content within the Connect app iframe and if theming isn’t initialized fast enough in the DOM, the default HTML page background (white) will show. This bit is mentioned in Connect Theming but I realize it’s easier said than done. One trick you may try is to set your html and body background to something like var(--ds-surface, #777) which roughly splits the difference between light and dark surfaces (somewhat hedging your bets) and would lower the perceived change when the styles are actually injected and applied. We are brainstorming some potential improvements on this startup logic and will be sharing them with our Connect and Forge teams.
Thanks for the investigation. From this end, the white flash seems to comes from before our iframe content is even loaded, so I am not sure of how we could impact this on the application side.
I tried creating an iframe with static colors (html { background-color: green; } body { background-color: red; }), and when the dialog loads, it flashes: white (for a long time), briefly green, and then stays red.
It looks like applying background-color: transparent to html and body tags will solve the last half of the problem for the dialog use case (ensuring correct display once the iframe is loaded but before theming is initialized). I believe Atlassian still needs to adjust something on its end while the iframe is waiting to be delivered. As I wrote above, this Atlassian piece currently looks like it is the majority of the delay.
Our design system is rolling out an update to the way theme styles are mounted. Instead of injecting style blocks, css <link> elements will be injected instead. This should be fully rolled out within the month.
Hello everyone! We are pleased to call Theming in Confluence Cloud Generally Available (GA) . Please see our community post for more information.
We know many marketplace partners are still working through adding theming support and are here to help answer questions. As always, please share both your issues and your successes so we know how things are going.
Hi @AlexWhite ,
Is there any progress on the rollout for the link element? It seems all.js is still using js to inject the styles, and we still need to use unsafe inline.
Hi @marc I believe the rollout proceeded a little slower than expected. @DanielDelCore from our design system team will provide an update here soon and can give provide better detail.
Hey @marc
We’ve just published the change and it has started to rollout to production now. It should be live within the next 5 days. Could you please let me know if you see any issues?
@scott.dudley I had started to give you an update yesterday but never hit “Reply”. Here is the latest on our investigation:
We acknowledge the issue is on the Atlassian side of things but unfortunately don’t have a good solution for this right now. This same issue is happening across our products in some way and has to do with the Connect lifecycle. We’ll need to come up with a way to prevent the iframe from rendering until it has been initialized. This problem exists for any Connect content loaded into an iframe. The best advice we have at the moment is to make sure the window.AP.theming.initializeTheming() call is as close to the all.js script in the Connect app’s HTML. There will likely still be a small flash, but that would minimize it.
During testing, even if the empty iframe element is rendered before the iframe content is fetched from the app, I was able to get it to render transparently and eliminate 95% of the white flash by adding the following to the attribute of the iframe itself:
style="color-scheme: light;"
Using this static attribute of “light” seems to solve the problem regardless of whether the dark or light theme is activated. This is presumably related to the fact that browsers will render the iframe as opaque if the color-scheme of the parent and the iframe differ.
Do you know if the team has considered this idea? If it works, it seems like it would be a much easier fix than juggling items in the lifecycle to prevent the iframe from rendering.
I suspect the remaining 5% of the white flash is under the application’s control, once the iframe content is loaded, and that it could be eliminated on the app developer side.
Hi again @scott.dudley This solution is clever but comes with some tricky pitfalls. I checked with the Connect team and they did consider this and some comments on it:
If we set color-scheme: light on the CSS outside the iframe (not dark, it has to be the opposite of what you actually want ) then we replace the light mode flash with a different kind of flash, from a “browser trying to apply dark mode inversion styles to the iframe” to “proper dark mode from design tokens”. This is most noticeable with the text, which goes from dark on dark, to light on dark. This method also has several other caveats:
We have to remove this color-scheme once the iframe has loaded, otherwise it will invert frames that don’t support theming and make them unreadable, and it also interferes with the design tokens as well and overrides them, so must be removed regardless of app support for theming.
We could remove this property once initializeTheming is called, but of course that doesn’t work for apps that don’t support theming, so we don’t know when to remove it for those apps (maybe we could wait x amount of time for initializeTheming to be called, but this is a bit hacky)
We could also remove it once the iframe has finished the init process but that might still leave a tiny gap between init and calling initializeTheming, although this could be mitigated by inlining the call to initializeTheming as we have already suggested. However if we are already hiding the iframe during the init process of connect-module-core, and only showing it once the init is complete, this won’t help
The overall sentiment is that the Connect team should consider a slightly different initialization pattern for Connect apps involving a static property on the HTML tag or perhaps a meta tag which could be read during the Connect init process so that applying theme could be done as a part of the init logic and the iframe not displayed until theme is fully ready. The downside is that this requires app partners, such as yourself, to change the approach.
Please share https://jira.atlassian.com/browse/CONFCLOUD-76999 with others that are interested in improving this issue. That will help drive the Connect platform team’s priority on this issue. Otherwise, we’ll need to live with the occasional flickers for now.
Hi @sash011 The legacy editor in Confluence Cloud does have dark mode support. It was added shortly before we moved theming to GA. Is there some piece in particular you are seeing not support dark mode?
If you’re referring to Confluence Data Center, please follow Log in with Atlassian account - that work is currently in progress.
I am talking about legacy editor in cloud
Try editing page with 3rd party macros in the legacy editor - you will understand what I am talking about
Macro placeholders are with a white background