In 2020, many front-end developers use style sheet languages with more features - such as Sass and Less, and no longer utilize pure CSS. Sass (specifically, the more recent SCSS syntax of Sass) has gained popularity and overtaken Less. Both Bootstrap and Material now use Sass. Angular CLI, Vue CLI, and Create React App also support Sass out-of-the-box, and Webpack includes a Sass loader.
DevExtreme style sheets are written in Less. Unfortunately, Less and Sass style sheets are not compatible with each other. The result is that our Less style sheets cannot be integrated into a project that uses Sass.
Based on the popularity of Sass, we plan to migrate our style sheets to SCSS syntax. You will be able to import and set widget styles in your SCSS files. For instance, if you wish to apply our Material Blue Light Compact theme and use only DevExtreme Accordion and Button components in your app, the SCSS configuration would appear as follows:
// set theme settings
@use "node_modules/devextreme/scss/widgets/material/colors" with (
$color: "blue",
$mode: "light"
);
@use "node_modules/devextreme/scss/widgets/material/sizes" with ($size: "compact");
// widgets used by app
@use "node_modules/devextreme/scss/widgets/material/accordion";
@use "node_modules/devextreme/scss/widgets/material/button";
Our SCSS style sheets are modular, and they require Dart Sass compiler v1.23.0 or later. If your application does not yet use modules, refer to the following article for migration details: Sass: The Module System is Launched.
Although our Less styles were not declared as public API (and were not documented), some developers may have used them to customize CSS in their projects. Please let us know in the comments below if you used them. We will come up with a migration plan just for you.
How does the new Feature meet your needs?
Which style sheet language did you use in your last application?
Subscribe to this thread, or to our Facebook and Twitter accounts, for updates on this topic.
A "theme" is not just a color. Please also consider using configurable variables for
So, customisable colors with predefined size sets ($size: "compact") would be a great first step, but a first step only. An app might be using themes on its on, even if just dark and light.
Also, a full theme always means consistent animations (speed, and character) and icons across app. So, if an app uses one component from DevExpress (datagrid, for example), it could be, ideally, fully customised to feel like an integral part of the rest of the app.
@sapelson, scss files - are our sources, not an API. To configure scss, you can change any variable (see https://github.com/DevExpress/DevExtreme/blob/20_2/scss/widgets/material/_colors.scss#L6 where variables used by the entire theme are defined). $color/$mode variables are used to set the color scheme and they are mandatory. Please note that we can change source files at any time.
I have been proposing this to DX for years I am very happy to see @babich-a taking it up. Thank you.
Our app is a Bootstrap 4 app, and we have overridden many of the BS4 $scss variables. This is the cheapest and easiest way to customize a whole set of BS components that utilize those bootstrap classes.
I want the exact same thing for DX. Currently, I had to use the theme exporter site and then hack / convert to scss. I only want to import the dx/core scss sheets that I need. For example the scheduler thing is huge, we don't use it, and bloats our css terribly.
I have never seen this @use syntax before, Bootstrap just does !default on their variables so if you define (as we do) _custom_theme_vars.scss it will win and override the downstream one.
My other pain with dx is the extremely deep and bloated html that is hard to override and customize. There is a ton of overlap and duplication of css utilities in DX which also adds bloat. I really wish that dx would just let me configure all of it to use bootstrap 4 utility classes. Having DX bring their own for this is a lot. I could see a config that lets me choose between say Material and Bootstrap (tailwind is another) and just have DX use those utility classes for basic positioning and layout.
I think, asking Devexpress to use Bootstrap classnames is a bit of a stretch :P.
But Bootstrap-style configuration file that lists all available variables would be awesome.
The ultimate would be to be able to configure the utility class library, if you want to bring your own, falling back to DX's. All utility libraries pretty much do the same thing for example d-block is display: block in Bootstrapese.
But the essential part is devextreme's theme variables distilled as bootstrap 4's like this:
https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss
and then importing each component's sheet selectively.
Would anyone be able to provide example of a setup in Angular ? I was not able to set up SCSS dx styles with and Angular 9 app.
The @use does not seem to be working but (no error just ignored) - I can't find a working setup example anywhere. Any ideas on how to make this work with Angular app would be much appreciated. Thanks in advance.
Hi, @sapelson, @httpete.
According to the new sass module system, you need to configure each module separately. The @import directive, that allows defining all variables in one file and use it in another file will be deprecated before October 1, 2021 and then dropped.
(The following examples will be shown for the material theme)
You can find base variables for the DevExtreme theme in the node_modules/devextreme/scss/widgets/material/colors module. Color constants for a widget can be found in the widget modules (for example, node_modules/devextreme/scss/widgets/material/button/colors).
I have prepared a simple example to show how a theme can be configured.
First of all, install sass, a pre-release version of devextreme and jquery (to simplify code running):
npm i sass [email protected] jquery
Create the index.html file with the following content:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./node_modules/devextreme/dist/css/dx.common.css"/>
<link rel="stylesheet" type="text/css" href="./test.css"/>
<script type="text/javascript" src="./node_modules/jquery/dist/jquery.js"></script>
<script type="text/javascript" src="./node_modules/devextreme/dist/js/dx.all.debug.js" charset="utf-8"></script>
</head>
<body class="dx-viewport">
<div id="button"></div>
<script>
$(function() {
$("#button").dxButton({
text: 'Click me!',
icon: "home"
});
});
</script>
</body>
</html>
Then create the test.scss file with the following content:
@use "node_modules/devextreme/scss/widgets/material/colors" as A with (
$color: "blue",
$mode: "light",
// base variables (affects entire theme and all widgets)
$base-text-color: green,
$base-bg: gray
);
@use "node_modules/devextreme/scss/widgets/material/sizes" with ($size: "compact");
@use "node_modules/devextreme/scss/widgets/material/button/colors" as B with (
// colors, specific for button
$button-normal-icon-color: blue
);
// typography settings (fonts, background color)
@use "node_modules/devextreme/scss/widgets/material/typography";
// widgets used by app
// my button has an icon, so I need icon classes
@use "node_modules/devextreme/scss/widgets/material/icons";
// button
@use "node_modules/devextreme/scss/widgets/material/button";
Compile the theme and copy icons.
npx sass test.scss test.css
cp -r node_modules/devextreme/dist/css/icons .
Open index.html. You'll see a page with a gray background and a button with green text and a blue icon.
@miro-ur, angular docs states that you can use scss instead of css. Make sure that you use the dart-sass compiler (that allows using the @use directive), not node-sass. Starting with 8.0, angular-cli uses it by default.
To start a new project with Sass, use the following command
ng new my-scss-app --style=scss
To migrate the existing project, you can follow this guide.
I dont see how this will work what you are proposing. I don't have to do any compilation to css, I just import my bootstrap 4 scss sheet and angular cli does the internal compiling. An example stackblitz that showcases using angular-cli to compile devextreme scss would be very helpful.
Hi, @httpete . I have prepared a simple project that shows how SCSS can be used. Take a look this repository. It has two branches. master shows how to import full bundle (
https://github.com/babich-a/angular-scss-example/blob/master/angular.json#L28), and master-configurable shows how to import separate widgets (https://github.com/babich-a/angular-scss-example/blob/master-configurable/src/styles.scss).
@babich-a how will this work when using devextreme-cli?
@hakimio repository in this reply is an angular-cli project.
@hakimio repository in this reply is an angular-cli project.
So, you won't be using devextreme-cli to generate style bundles anymore, but I still have to manually import styles for each component I am using in main styles.scss file?
@hakimio repository in this reply is an angular-cli project.
So, you won't be using
devextreme-clito generate style bundles anymore, but I still have to manually import styles for each component I am using in mainstyles.scssfile?
Sorry, @hakimio. You asked about devextreme-cli, not angular-cli. You can use devextreme-cli to generate styles like before.
You can use devextreme-cli to generate styles like before.
Would be nice if it could generate scss bundle instead of just pre-processed css.
You can use devextreme-cli to generate styles like before.
Would be nice if it could generate
scssbundle instead of just pre-processedcss.
What do you mean by 'scss bundle'? DevExtreme scss with changed variables?
What do you mean by '
scssbundle'? DevExtremescsswith changed variables?
I was thinking about two files:
metadata.json file, so that I could easily change them and use them in my own SCSS style-sheets. Auto-generated variables.scss file right now only contains 5 main variables.metadata.json. It could either be module imports like the ones you showed or just all widget SCSS inlined in a single file. SCSS bundles provided by DX right now, include all the widgets, no matter if you are using them or not.I was thinking about two files:
One SCSS file with all the variables from all the widgets specified in DX
metadata.jsonfile, so that I could easily change them and use them in my own SCSS style-sheets. Auto-generatedvariables.scssfile right now only contains 5 main variables.One with the actual style-sheets for all the widgets specified in
metadata.json. It could either be module imports like the ones you showed or just all widget SCSS inlined in a single file.SCSSbundles provided by DX right now, include all the widgets, no matter if you are using them or not.
We will consider SCSS archive importing with the ThemeBuilder (or the number of files with devextreme-cli). At present you can change scss/widgets/generic/_index.scss to exclude some widgets and scss/widgets/generic/_variables.scss to change variables.
I was able to use this new feature successfully by creating the following scss file, and include it in my angular.json file :
$dx-accent-color: #9c27b0;
@use "node_modules/devextreme/scss/widgets/material/colors" with (
$color: "blue",
$mode: "light",
$base-accent: $dx-accent-color
);
@use "node_modules/devextreme/scss/widgets/material/sizes" with ($size: "default");
@use "node_modules/devextreme/scss/widgets/material/typography";
// widgets used by app
@use "node_modules/devextreme/scss/widgets/material/icons";
@use "node_modules/devextreme/scss/widgets/material/button";
@use "node_modules/devextreme/scss/widgets/material/dataGrid";
But I am not able to use a CSS variable to define $dx-accent-color value. If I write this :
$dx-accent-color: var(--theme-secondary-500);
I get a Error : "SassError: $color: var(--theme-secondary-500) is not a color."
I know it is not a devextreme specific issue, more a @use configuration limitation, but I'm not able to find a workaround to that.
More generally, I don't really know how can I use a color from my material palette or css variable to set my $base-accent color value, and not a static color value.
(maybe I should juste create my own version of node_modules/devextreme/scss/widgets/material/colors file, and import it with @use ... ?)
Hi @dh-fallen. Thank you for your feedback.
It is not a full Sass-relative issue. We use some variables to calculate other colors (eg. https://github.com/DevExpress/DevExtreme/blob/20_2/scss/widgets/generic/gridBase/_colors.scss#L208). Sass requires the first argument of color.change, lighten, darken and other functions to be a color and can't use css variables as values (it should know a color value at compile time).
Hi @dh-fallen. Thank you for your feedback.
It is not a full Sass-relative issue. We use some variables to calculate other colors (eg. https://github.com/DevExpress/DevExtreme/blob/20_2/scss/widgets/generic/gridBase/_colors.scss#L208). Sass requires the first argument ofcolor.change,lighten,darkenand other functions to be a color and can't use css variables as values (it should know a color value at compile time).
Yeah that is what I am realizing since yesterday : my problem is a very common matter, and we cannot use a runtime css variable in a precompiled Sass color function ...
What a pity, since I have defined angular material palettes in my app using css variables, and it's working great.
The DX SASS feature is great, but we should have some way to add theming capabilities to the styling approach : how can I change the accent color depending on my client ?
@dh-fallen There is no way to change the DevExtreme accent color at runtime. You can change only the entire theme.
@babich-a devextreme should support either way of variables - scss or css3.
@babich-a I'm struggling to modify sizes and would love any assistance or further understanding you can provide.
Building on the example you shared above, I am attempting to adjust the button padding.
@use 'node_modules/devextreme/scss/widgets/generic/colors' with ( $color: 'light' );
@use 'node_modules/devextreme/scss/widgets/generic/sizes' with ( $size: 'default' );
@use 'node_modules/devextreme/scss/widgets/generic/button' with ( $generic-button-horizontal-padding: 10px);
This configuration doesn't work. Even though $generic-button-horizontal-padding is declared using !default, I get this error: SassError: This variable was not declared with !default in the @used module.
Should this variable be available? If I am simply going about this the wrong way, any guidance you can provide would be greatly appreciated.
Hi @bzupancic. The scss/widgets/generic/button module does not have a $generic-button-horizontal-padding variable. The scss/widgets/generic/button/sizes module contains it.
To configure this variable, you need to modify your code as follows:
// sizes namespace already declared so we need buttonSizes namespace
@use "../node_modules/devextreme/scss/widgets/generic/button/sizes" as buttonSizes with ($generic-button-horizontal-padding: 10px);
@use "../node_modules/devextreme/scss/widgets/generic/button";
It will compile but will not work. Unfortunately, it is impossible to configure sizes now. This variable will be rewritten in this line.
We have plans to allow customization of size variables. So, I created a ticket in our support center. You can subscribe to it so that you receive a notification when it is updated.
Most helpful comment
@babich-a devextreme should support either way of variables - scss or css3.