Hello UI5 Developers,
The case being explained here may not be encountered frequently in UI5 development. We are all familiar with the use of SVGs in frontend applications. However, the case under analysis will concern dynamic SVGs. Dynamic SVGs have internal attributes and properties that depend on global CSS variables. The standard implementation will not yield the desired results either in rendering the SVG or in ensuring compatibility with all themes.
I will explain this case in the context of our project requirements.
Below is the SVG that uses the CSS variables for the linear gradient.
<svg width=”306″ height=”67″ viewBox=”0 0 306 67″ fill=”none” xmlns=”http://www.w3.org/2000/svg”>
<path opacity=”0.9″ d=”M224 0H89V67H156.5L224 0Z” fill=”url(#paint0_linear_2040_121992)” />
<path opacity=”0.6″ d=”M290 0H230V30H260L290 0Z” fill=”url(#paint1_linear_2040_121992)” />
<path opacity=”0.4″ d=”M81 0H0V40H40.5L81 0Z” fill=”url(#paint2_linear_2040_121992)” />
<defs>
<linearGradient id=”paint0_linear_2040_121992″ x1=”83.5497″ y1=”67″ x2=”201.283″ y2=”-5.15128″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.550349″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
<linearGradient id=”paint1_linear_2040_121992″ x1=”227.578″ y1=”30″ x2=”280.115″ y2=”-1.95849″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.550349″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
<linearGradient id=”paint2_linear_2040_121992″ x1=”-3.27019″ y1=”40″ x2=”67.1769″ y2=”-3.38846″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.503258″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.503258″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
</defs>
</svg>
Reason for SVG not rendering as expected,
The primary reason an SVG may not be able to fetch CSS variables in an SAPUI5 application is due to scoping issues, specifically when the SVG is loaded as an external resource (e.g., using an <img> tag or <use> element) or if there are conflicts with the SAPUI5’s theming infrastructure.
The common problem and solution would be
Problem: If the SVG is referenced using an external file (e.g., <img src=”icon.svg”> or <use xlink:href=”images/arrow.svg#arrowLeft”></use>), the browser treats the SVG as an entirely separate document or scope. It cannot access the CSS variables defined in the main HTML document’s CSS.
Solution: You must use inline SVG directly within your HTML or UI5 control’s renderer. This places the SVG elements within the same DOM and CSS scope as the rest of your application, allowing them to inherit or access the CSS variables defined in the main application’s stylesheet.
If the SVG is static, then directly using it inline will fetch the CSS variables, as the SVG will be in the global scope.
If the SVG is dynamic (requiring the SVG to adapt to the change in themes), then the static option won’t be useful. This requires a unique and simple implementation in the controller file.
JavaScript Dynamic Injection from Controller file (Recommended)
In respective controller file, yourComponentName.controller.js
onAfterRendering: function () {
// Post-rendering logic for header controller for rendering SVG in the background
this._setBackgroundImageSVG();
},
// Other methods
_setBackgroundImageSVG: function() {
const vbox = this.byId(“headerSearchContentVBox”);
if (vbox) {
const domRef = vbox.getDomRef();
if (domRef) {
// Get CSS variable values
const computedStyle = getComputedStyle(document.documentElement);
const color1 = computedStyle.getPropertyValue(‘–sapShell_Category_1_Background’).trim();
const color9 = computedStyle.getPropertyValue(‘–sapShell_Category_9_Background’).trim();
// Create SVG with resolved colors
const svgMarkup = `<svg width=”306″ height=”67″ viewBox=”0 0 306 67″ fill=”none” xmlns=”http://www.w3.org/2000/svg”>
<path opacity=”0.9″ d=”M224 0H89V67H156.5L224 0Z” fill=”url(#paint0_linear)” />
<path opacity=”0.6″ d=”M290 0H230V30H260L290 0Z” fill=”url(#paint1_linear)” />
<path opacity=”0.4″ d=”M81 0H0V40H40.5L81 0Z” fill=”url(#paint2_linear)” />
<defs>
<linearGradient id=”paint0_linear” x1=”83.5497″ y1=”67″ x2=”201.283″ y2=”-5.15128″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ stop-color=”${color1}” />
<stop offset=”0.550349″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
<linearGradient id=”paint1_linear” x1=”227.578″ y1=”30″ x2=”280.115″ y2=”-1.95849″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ stop-color=”${color1}” />
<stop offset=”0.550349″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
<linearGradient id=”paint2_linear” x1=”-3.27019″ y1=”40″ x2=”67.1769″ y2=”-3.38846″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.503258″ stop-color=”${color1}” />
<stop offset=”0.503258″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
</defs>
</svg>`;
// Encode and set as background
const encoded = encodeURIComponent(svgMarkup);
domRef.style.setProperty(‘–before-content’, `url(‘data:image/svg+xml,${encoded}’)`);
}
}
}
View file: yourComponentName.view.xml
<mvc:View
xmlns:core=”sap.ui.core”
xmlns:mvc=”sap.ui.core.mvc”
xmlns:m=”sap.m”
xmlns:f=”sap.f”
controllerName=”your.project.name.controller.YourComponentController”>
<m:VBox
id=”headerSearchContentVBox”
class=”headerSearchVBox”
width=”100%”
justifyContent=”Center”>
<m:SearchField
id=”headerMainSearchField”
enableSuggestions=”true”
class=”exampleSearchField sapUiSmallMargin”/>
</m:VBox>
</mvc:View>
I will be placing this SVG in the pseudo-element associated with the VBox bearing the id headerSearchContentVBox.
CSS file: css/style.css
.headerSearchVBox {
/* Other CSS properties as per your use case */
position: relative;
background-color: var(–sapShell_Category_1_Background);
width: 100%;
height: 4.25rem;
border-width: var(–sapElement_BorderWidth);
border-style: solid;
border-color: var(–sapTile_BorderColor);
border-radius: var(–sapTile_BorderCornerRadius);
overflow: hidden;
text-align: right;
box-sizing: border-box;
padding: var(–sapUiSmallMargin) var(–sapContent_Space_Small);
}
.headerSearchVBox::before {
content: var(–before-content, url(../images/SearchBackground.svg));
position: absolute;
top: 0;
right: 1rem;
width: 19.125rem;
height: 4.1875rem;
pointer-events: none;
}
The content property is set to var(—before-content, url(../images/SearchBackground.svg)). As previously stated, the encoded SVG is assigned to the before-content property in the controller. To enhance user experience, the SVG is directly loaded with a fallback color. If an error occurs, it will render with the provided color or the default browser color, which is black.
The primary function of dynamic SVG is to synchronize with changing themes. This can be enabled by subscribing to the event, which is fired when the theme is changed, i.e., the themeChanged event. Whenever the theme is changed,
1. Listen to this event in onInit method of same controller file
2. Call the SVG update function when the theme is changed.
3. Remove the listener attached in the onInit method from the onExit method.
// Import sap.ui.core.Core library
onInit: function () {
// Attach theme change listener to update SVG colors
this._onThemeChangedHandler = this._setBackgroundImageSVG.bind(this);
Core.attachThemeChanged(this._onThemeChangedHandler);
},
onExit: function () {
// Clean up theme change listener
if (this._onThemeChangedHandler) {
Core.detachThemeChanged(this._onThemeChangedHandler);
}
},
This will facilitate the development of the UI using dynamic SVG within the UI5 framework, making it more straightforward and efficient.
Regards,
Sanket Zad
Hello UI5 Developers,The case being explained here may not be encountered frequently in UI5 development. We are all familiar with the use of SVGs in frontend applications. However, the case under analysis will concern dynamic SVGs. Dynamic SVGs have internal attributes and properties that depend on global CSS variables. The standard implementation will not yield the desired results either in rendering the SVG or in ensuring compatibility with all themes.I will explain this case in the context of our project requirements.Below is the SVG that uses the CSS variables for the linear gradient. <svg width=”306″ height=”67″ viewBox=”0 0 306 67″ fill=”none” xmlns=”http://www.w3.org/2000/svg”>
<path opacity=”0.9″ d=”M224 0H89V67H156.5L224 0Z” fill=”url(#paint0_linear_2040_121992)” />
<path opacity=”0.6″ d=”M290 0H230V30H260L290 0Z” fill=”url(#paint1_linear_2040_121992)” />
<path opacity=”0.4″ d=”M81 0H0V40H40.5L81 0Z” fill=”url(#paint2_linear_2040_121992)” />
<defs>
<linearGradient id=”paint0_linear_2040_121992″ x1=”83.5497″ y1=”67″ x2=”201.283″ y2=”-5.15128″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.550349″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
<linearGradient id=”paint1_linear_2040_121992″ x1=”227.578″ y1=”30″ x2=”280.115″ y2=”-1.95849″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.550349″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
<linearGradient id=”paint2_linear_2040_121992″ x1=”-3.27019″ y1=”40″ x2=”67.1769″ y2=”-3.38846″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.503258″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”0.503258″ style=”stop-color: var(–sapShell_Category_1_Background)” />
<stop offset=”1″ style=”stop-color: var(–sapShell_Category_9_Background)” />
</linearGradient>
</defs>
</svg> Reason for SVG not rendering as expected,The primary reason an SVG may not be able to fetch CSS variables in an SAPUI5 application is due to scoping issues, specifically when the SVG is loaded as an external resource (e.g., using an <img> tag or <use> element) or if there are conflicts with the SAPUI5’s theming infrastructure. The common problem and solution would be Problem: If the SVG is referenced using an external file (e.g., <img src=”icon.svg”> or <use xlink:href=”images/arrow.svg#arrowLeft”></use>), the browser treats the SVG as an entirely separate document or scope. It cannot access the CSS variables defined in the main HTML document’s CSS.Solution: You must use inline SVG directly within your HTML or UI5 control’s renderer. This places the SVG elements within the same DOM and CSS scope as the rest of your application, allowing them to inherit or access the CSS variables defined in the main application’s stylesheet.If the SVG is static, then directly using it inline will fetch the CSS variables, as the SVG will be in the global scope.If the SVG is dynamic (requiring the SVG to adapt to the change in themes), then the static option won’t be useful. This requires a unique and simple implementation in the controller file.JavaScript Dynamic Injection from Controller file (Recommended)In respective controller file, yourComponentName.controller.jsonAfterRendering: function () {
// Post-rendering logic for header controller for rendering SVG in the background
this._setBackgroundImageSVG();
},
// Other methods
_setBackgroundImageSVG: function() {
const vbox = this.byId(“headerSearchContentVBox”);
if (vbox) {
const domRef = vbox.getDomRef();
if (domRef) {
// Get CSS variable values
const computedStyle = getComputedStyle(document.documentElement);
const color1 = computedStyle.getPropertyValue(‘–sapShell_Category_1_Background’).trim();
const color9 = computedStyle.getPropertyValue(‘–sapShell_Category_9_Background’).trim();
// Create SVG with resolved colors
const svgMarkup = `<svg width=”306″ height=”67″ viewBox=”0 0 306 67″ fill=”none” xmlns=”http://www.w3.org/2000/svg”>
<path opacity=”0.9″ d=”M224 0H89V67H156.5L224 0Z” fill=”url(#paint0_linear)” />
<path opacity=”0.6″ d=”M290 0H230V30H260L290 0Z” fill=”url(#paint1_linear)” />
<path opacity=”0.4″ d=”M81 0H0V40H40.5L81 0Z” fill=”url(#paint2_linear)” />
<defs>
<linearGradient id=”paint0_linear” x1=”83.5497″ y1=”67″ x2=”201.283″ y2=”-5.15128″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ stop-color=”${color1}” />
<stop offset=”0.550349″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
<linearGradient id=”paint1_linear” x1=”227.578″ y1=”30″ x2=”280.115″ y2=”-1.95849″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.0158962″ stop-color=”${color1}” />
<stop offset=”0.550349″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
<linearGradient id=”paint2_linear” x1=”-3.27019″ y1=”40″ x2=”67.1769″ y2=”-3.38846″ gradientUnits=”userSpaceOnUse”>
<stop offset=”0.503258″ stop-color=”${color1}” />
<stop offset=”0.503258″ stop-color=”${color1}” />
<stop offset=”1″ stop-color=”${color9}” />
</linearGradient>
</defs>
</svg>`;
// Encode and set as background
const encoded = encodeURIComponent(svgMarkup);
domRef.style.setProperty(‘–before-content’, `url(‘data:image/svg+xml,${encoded}’)`);
}
}
}View file: yourComponentName.view.xml<mvc:View
xmlns:core=”sap.ui.core”
xmlns:mvc=”sap.ui.core.mvc”
xmlns:m=”sap.m”
xmlns:f=”sap.f”
controllerName=”your.project.name.controller.YourComponentController”>
<m:VBox
id=”headerSearchContentVBox”
class=”headerSearchVBox”
width=”100%”
justifyContent=”Center”>
<m:SearchField
id=”headerMainSearchField”
enableSuggestions=”true”
class=”exampleSearchField sapUiSmallMargin”/>
</m:VBox>
</mvc:View> I will be placing this SVG in the pseudo-element associated with the VBox bearing the id headerSearchContentVBox.CSS file: css/style.css.headerSearchVBox {
/* Other CSS properties as per your use case */
position: relative;
background-color: var(–sapShell_Category_1_Background);
width: 100%;
height: 4.25rem;
border-width: var(–sapElement_BorderWidth);
border-style: solid;
border-color: var(–sapTile_BorderColor);
border-radius: var(–sapTile_BorderCornerRadius);
overflow: hidden;
text-align: right;
box-sizing: border-box;
padding: var(–sapUiSmallMargin) var(–sapContent_Space_Small);
}
.headerSearchVBox::before {
content: var(–before-content, url(../images/SearchBackground.svg));
position: absolute;
top: 0;
right: 1rem;
width: 19.125rem;
height: 4.1875rem;
pointer-events: none;
} The content property is set to var(—before-content, url(../images/SearchBackground.svg)). As previously stated, the encoded SVG is assigned to the before-content property in the controller. To enhance user experience, the SVG is directly loaded with a fallback color. If an error occurs, it will render with the provided color or the default browser color, which is black.The primary function of dynamic SVG is to synchronize with changing themes. This can be enabled by subscribing to the event, which is fired when the theme is changed, i.e., the themeChanged event. Whenever the theme is changed, 1. Listen to this event in onInit method of same controller file2. Call the SVG update function when the theme is changed.3. Remove the listener attached in the onInit method from the onExit method.// Import sap.ui.core.Core library
onInit: function () {
// Attach theme change listener to update SVG colors
this._onThemeChangedHandler = this._setBackgroundImageSVG.bind(this);
Core.attachThemeChanged(this._onThemeChangedHandler);
},
onExit: function () {
// Clean up theme change listener
if (this._onThemeChangedHandler) {
Core.detachThemeChanged(this._onThemeChangedHandler);
}
},This will facilitate the development of the UI using dynamic SVG within the UI5 framework, making it more straightforward and efficient. Regards,Sanket Zad Read More Technology Blog Posts by SAP articles
#SAP
#SAPTechnologyblog