Semantic theming with theming-base-content
The open-source @sap-theming/theming-base-content brings theme-ability to your technology stack. To implement an SAP Fiori theme you simply have to use the custom css properties provided by this npm package. The set of theming parameters is the result of years of theming experience in technologies like SAPUI5, UI5 Web Components, Fundamental Library Styles, Web Dynpro for ABAP or SAP GUI for HTML.
This post explains the rationale behind the set of theming parameters. That knowledge will help you both in implementing a SAP Fiori theme for your own technology stack as well as creating a custom theme for any technology stack with the UI theme designer. We will
- explore some history of the theming parameter set, starting with the ancient Bluecrystal theme,
- look into semantic parameters and theme scoping with good old Belize,
- pick apart the namespaces of the current theming parameter set as presented by Quartz, and
- describe the mindset shift that started with the upcoming Horizon.
Bluecrystal: history of the theming parameter set
We started to address the need for a common set of theming parameters across different SAP UI technologies back in 2012. Goldreflection was the state-of-the-art theme, SAPUI5 was just birthed, and Bluecrystal, the first SAP Fiori theme, was around the corner.
All technologies implementing Bluecrystal should follow the same design specifications. So it made sense to create a common set of theming parameters consumed by SAPUI5 and Unified Rendering (the SAP-internal HTML framework which is the basis for Web Dynpro for ABAP and SAP GUI for HTML).
Less was chosen as the common technology, and a consumption infrastructure for both SAPUI5 and Unified Rendering was set up.
The very first parameter set contained parameters from a design perspective. Dark to light versions of background, border and text colors like
@sapBaseBackground: @sapBaseColor; @sapLightestBackground: lighten(@sapBaseBackground, 100); @sapExtraLightBackground: lighten(@sapBaseBackground, 44.7); @sapLightBackground: lighten(@sapBaseBackground, 39.7); @sapMediumBackground: lighten(@sapBaseBackground, 36.5); @sapDarkBackground: darken(@sapBaseBackground, 3.7); @sapExtraDarkBackground: darken(@sapBaseBackground, 30.2); @sapDarkestBackground: darken(@sapBaseBackground, 100);
These parameters would then be mapped to the controls/components in all technologies, according to design specifications.
We quickly learned that this design-driven approach does not go well with custom theming, as it is too restrictive. Customers did not want to change every “extra light background” to the same custom value. In some places it made sense, in others it didn’t. Furthermore, if you custom-themed sapLightBackground to be darker than sapMediumBackground you created confusion all the way through. The same goes for the name of the theme, Bluecrystal, which simply felt odd once the main color of the custom theme was no longer blue.
Belize: semantic parameters, theme scoping
So, around 2015, with the introduction of the Belize theme family, we came up with a (larger) set of semantic parameters, which still is the baseline for todays theming parameter set.
There is a small set of palette parameters, which
- is not exposed to custom theming,
- is the root for all other parameters (the exception proves the rule),
- and is simply named sapPrimary1 to sapPrimary6.
On top of these palette parameters there are semantic namespaces that describe control/component families. E.g. sapField_BorderColor would be the border-color for all form field components from input fields over radio buttons to checkboxes or multi-input tokenizers. These semantic parameters are mapped to palette parameters and with that allow for the “design perspective” (with the palette parameters) but still have high customizability for custom themes.
Also with SAP Belize came the advent of dark mode. We introduced a second set of parameter mappings for a “dark” Belize version under the technical id sap_belize_plus, and used theme scoping to combine the light and dark versions into a single theme, where dark mode could be activated with a CSS “scope” class (sapContrast in Belize, sapContrastPlus in Belize Deep). Contrast scoping is described in more detail in Contrast scoping in Belize and Belize Deep.
Quartz: namespaces of the current set
Long story short: theme scoping was a bad idea and we removed it with Quartz and instead offered two separate themes, Quartz Light and Quartz Dark (that’s not 100% correct, theme scoping is still used, e.g. in Unified Rendering for controls in table rows, but no longer for a combined light-dark-mode).
But we extended the semantic parameter set.
Quartz was the first theme to fulfill the WCAG 2.1 accessibility guideline. Amongst others that meant to fulfill a 4:5:1 (or even 7:1 for the high-contrast themes) contrast between text and background as described in Success Criterion 1.4.3 Contrast (Minimum).
To achieve that, a lot of “parameter pairs” of Background and TextColor were introduced, that, when used together, ensure the necessary contrast with a Less contrast() statement:
@sapButton_Background: @sapBaseColor; @sapButton_TextColor: contrast( @sapButton_Background, @sapHighlightColor, @sapContent_ContrastTextColor, @sapContent_ContrastTextThreshold );
Still, the semantic parameters in Quartz describe control families, which should ideally apply to more than one similar control, to allow consistent custom-theming. These control families are often called namespaces.
The parameter naming scheme follows our rule of consistent inconsistency: new parameters should fit well into the existing structure, even if, on a green field, it would make sense to name them differently. (e.g. we have sapField_InformationBackground and sapButton_Information_Background – with a second separating underscore – because the namespaces behave a little differently)
As of theming-base-content 11.1.36 there are the following namespaces.
- general parameters like sapBrandColor, sapHighlightColor, or sapBackgroundColor, which apply to almost all controls, everywhere
- semantic parameters like sapNegativeColor, that come in different flavors (e.g. as sapCriticalElementColor for foreground elements or sapSuccessBackground for backgrounds)
- sapShell for the Fiori Launchpad shell
- sapLink for links
- sapAvatar for avatars (these parameters are new with 11.1.36 and may not be used yet by the different consuming UI technologies)
- sapButton the large collection of button parameters, including different button “flavors” like emphasized or transparent (lite) buttons, accept/reject/attention as well as negative/critical/success/information/neutral buttons
- sapButton_Track and sapButton_Handle that describe parameters for Switch controls (also newly introduced with 11.1.36 and most likely not used by all technologies as of the time writing)
- sapField parameters that describe input fields, radio buttons, checkboxes and other form fields
- sapGroup for grouping controls like groups, panels, trays etc.
- sapToolbar for toolbars
- sapList for all kinds of lists and tables
- sapMessage parameters that describe message areas and message boxes (also new with 11.1.36)
- sapProgress for progress bars (new with 11.1.36 as well)
- sapScrollBar for scrollbars
- sapSlider for sliders and range sliders (introduced with 11.1.36 as well)
- sapPageHeader and sapPageFooter for the header and footer of standalone applications
- sapInfobar for info bars for lists
- sapObjectHeader for the object header of Fiori applications
- sapTile for tiles and cards
- sapAccentColor and sapAccentBackgroundColor a palette of accent colors used in different controls
- sapIndicationColor a palette of industry-specific indication colors
- sapLegend for legends of graphs and tables
- sapChart for charts
- sapFont as a namespace for font family and font size definitions. There’s also sapFontUrl as an internal namespace for URLs to webfonts (woff2, woff or ttf) used in the themes.
- sapContent a smorgasbord of single parameters that did not fit anywhere else or where we did not anticipate that a separate namespace would make sense
- sapContent_Illustrative as a color palette for Fiori Moments / Illustrations
- sapElement a set mostly of protected (i.e. not theme-able) parameters that describe all elements
Horizon: mindset shift
With more and more SAP UI technologies adopting the theming-base-content, and more of them, like UI5 Web Components and Fundamental Library Styles, relying solely on custom css properties and a 100% complete parameter set, we see a mindset shift regarding the theming parameter set.
Where previously it was acceptable to hard-code parameters that should not be available for custom-theming in every technology, we now
- tend to have a large theming-base-content, and
- ideally have an “abstract baseTheme” in all technologies, that
- connects all parameters of the theming-base-content to CSS of the technologies and
- allows to switch between themes just by loading the css_variables.css of a different theme.
For that, we keep introducing new namespaces and new parameters. Most of these have been introduced to the theming-base-content 11.1.36, and there should be a separate blog post to go in-depth on them. Until then, the Release Notes of 11.1.36 give a little insight.
The theming-base-content has evolved since its birth in 2012. It allows palette theming for SAP UX designers as well as semantic theming for customers. With more and more UI frameworks adopting the theming-base-content, we’re heading towards a full parameter set for an abstract baseTheme that can switch between Fiori themes just by loading a different set of parameter mappings.
Have you already created a custom theme using the UI theme designer? Let me know in the comments what you liked most about it, and also what your pain points were!
Have you used the theming-base-content in your technology stack? Write a comment on what went well, and what is still missing!