Customizing Sandstone skin at Runtime

박승호 Seungho Park
Enact JS
Published in
4 min readDec 15, 2022
Sandstone custom skin

Enact provides several ways to customize components' appearance, such as via using css property, Theming, etc., but these methods are at design time. Since Sandstone 2.1, we’ve added Sandstone skin customization feature to support runtime customization. Thanks to this feature, you can customize the appearance of Sandstone components after the application is built. It allows you to customize the skin of your app without code modification.

You might wonder how does this work? We’ve made a list of CSS variables and made those variables can override the Sandstone skin. This approach makes style changes work properly and safely after the build.

Build the app

All you need to do is build your app with --custom-skin and add a CSS file named custom_skin.css which includes a preset of colors, under the customizations folder in the build result like below. Make sure you’ve installed Enact CLI 5.1.0 or later.

enact pack --custom-skin
my-app/
README.md
.gitignore
package.json
dist/
customizations/
custom_skin.css
main.css
main.js
...
node_modules/
src/
resources/
webos-meta/

Custom skin generation sample

Custom skin generator

You can make custom_skin.css file from the Sandstone custom-skin sample. The sample also supports a preview of your customized skin. The content of an example custom_skin.css looks like this:

/* custom_skin.css */
/* Full set of customizable Sandstone default skin variables */
.sandstone-theme {
--sand-bg-color: #000000;
--sand-text-color-rgb: 230, 230, 230;
--sand-text-sub-color: #ABAEB3;
--sand-shadow-color-rgb: 0, 0, 0;
--sand-component-text-color-rgb: 230, 230, 230;
--sand-component-text-sub-color-rgb: 171, 174, 179;
--sand-component-bg-color: #7D848C;
--sand-component-active-indicator-bg-color: #E6E6E6;
--sand-component-inactive-indicator-bg-color: #9DA2A7;
--sand-focus-text-color: #FFFFFF;
--sand-focus-bg-color-rgb: 230, 230, 230;
--sand-component-focus-text-color-rgb: 76, 80, 89;
--sand-component-focus-active-indicator-bg-color: #4C5059;
--sand-component-focus-inactive-indicator-bg-color: #B8B9BB;
--sand-selected-color-rgb: 230, 230, 230;
--sand-selected-text-color: #E6E6E6;
--sand-selected-bg-color: #3E454D;
--sand-disabled-focus-bg-color: #ABAEB3;
--sand-disabled-selected-color: #4C5059;
--sand-disabled-selected-bg-color: #E6E6E6;
--sand-disabled-selected-focus-color: #E6E6E6;
--sand-disabled-selected-focus-bg-color: #4C5059;
--sand-fullscreen-bg-color: #000000;
--sand-overlay-bg-color-rgb: 87, 94, 102;
--sand-selection-color: #4C5059;
--sand-selection-bg-color: #3399FF;
--sand-toggle-off-color: #AEAEAE;
--sand-toggle-off-bg-color: #777777;
--sand-toggle-on-color: #E6E6E6;
--sand-toggle-on-bg-color: #30AD6B;
--sand-progress-color-rgb: 230, 230, 230;
--sand-progress-buffer-color: #6B6D73;
--sand-progress-bg-color-rgb: 55, 58, 65;
--sand-progress-highlighted-color: #FFFFFF;
--sand-progress-slider-color: #8D9298;
--sand-spinner-color-rgb: 255, 255, 255;
--sand-checkbox-color: #E6E6E6;
--sand-item-disabled-focus-bg-color: #E6E6E6;
--sand-keyguide-bg-color-rgb: 55, 58, 65;
--sand-slider-disabled-knob-bg-color: #666666;
--sand-alert-overlay-bg-color-rgb: 202, 203, 204;
--sand-alert-overlay-text-color-rgb: 46, 50, 57;
--sand-alert-overlay-text-sub-color: #2E3239;
--sand-alert-overlay-focus-text-color: #575E66;
--sand-alert-overlay-disabled-selected-color: #FFFFFF;
--sand-alert-overlay-disabled-selected-bg-color: #788688;
--sand-alert-overlay-disabled-selected-focus-color: #E6E6E6;
--sand-alert-overlay-disabled-selected-focus-bg-color: #4C5059;
--sand-alert-overlay-progress-color-rgb: 55, 58, 65;
--sand-alert-overlay-progress-bg-color-rgb: 161, 161, 161;
--sand-alert-overlay-checkbox-color: #858B92;
--sand-alert-overlay-checkbox-disabled-selected-color: #FFFFFF;
--sand-alert-overlay-formcheckboxitem-focus-text-color: #575E66;
--sand-alert-overlay-item-disabled-focus-bg-color: #989CA2;
}

Note: You should be sure to put RGB-separated values in the CSS variable names ending with -rgb if you edit the value in the file directly.

The output shows only the modified value of CSS variables from the Sandstone default skin but you can see all the CSS variable list by turning on the Save full set of variables.

Next steps

As of now, we support colors in the Sandstone UI component but we are planning to expand this feature beyond that.

If you run into problems or have questions about the skin customization, you can report issues on GitHub or find the Enact team on Gitter. We’d love to hear from you.

--

--

박승호 Seungho Park
Enact JS

LG webOS Platform engineer. enactjs.com App Framework Lead. Interested in making web native-quality