CSS preprocessing
The topic describes how stylesheets are preprocessed and compiled to CSS in the Magento application. It provides the theoretical background a frontend developer needs to effectively debug stylesheets.
Terms used
Term | Description |
---|---|
Root source files |
The
For example, in one of the layout files of the Magento Blank theme, the following The root source files for the Blank theme are: |
Less compilation modes
In the Magento application, the following modes of compiling .less
files to CSS are implemented:
- Server-side Less compilation - This is the default compilation mode, and is the only option in production application mode. In this case the compilation is performed on the server, using the Less PHP library.
- Client-side Less compilation - When your application is not in production mode, you can set Magento to compile
.less
files in a browser, using the nativeless.js
library
To set the compilation mode:
- In the Magento Admin, navigate to Stores > Settings > Configuration > Advanced > Developer.
- In the Store View dropdown field, select Default Config.
- Under Frontend development workflow, in the Workflow type field, select the compilation mode.
- Click Save Config.
- Make sure that the same compilation mode is set for each configuration scope. Switch the Store View dropdown field to the website scope, and then to the store view, to check the Frontend development workflow option. Change the option to match the default config if it is different.
Server-side Less compilation
This section describes how the Less preprocessor works in server-side compilation mode. For each CSS file included in the layouts, Less preprocessor:
- Checks if the requested
.css
file is found. If it is found, the pre-processor stops its execution. Otherwise, it proceeds to the next step. - Changes the extension of the requested file to
.less
and tries to find the file using the Magento fallback mechanism. If the.less
file is not found, the Less pre-processor stops its execution. Otherwise, it proceeds to the next step. - Reads
.less
file contents and resolves@magento_import
and default Less@import
directives. - Resolves all paths in
.less
files to relative paths in the system using the Magento fallback mechanism. All files resolved by the Less pre-processor are copied tovar/view_preprocessed/less
. Imported files are processed recursively. - All source files are passed to the PHP Less compiler. The resulting compiled
.css
files are published topub/static/frontend/<Vendor>/<theme>/<locale>
.
Styles debugging in server-side compilation mode
In server-side Less compilation mode, to have your changes applied, clear pub/static/frontend/<Vendor>/<theme>/<locale>
by deleting the directory in the file system (excluding .htaccess), and reload the store pages to trigger compilation and publication.
You might also need to clear the var/cache
and var/view_preprocessed
directories.
Alternatively, to streamline the process of applying and debugging styles customizations, in server-side compilation mode, you can use the Grunt JavaScript task runner.
See the Compile Less with Grunt topic for details on how to install, configure, and use Grunt.
Client-side Less compilation
The client-side compilation flow is similar to the server-side flow. The difference is in the set of files, published to pub/static
on the last step. In the client-side mode, these files are published to the pub/static/frontend/<Vendor>/<theme>/<locale>
directory:
- Root source (.less) files with resolved
@magento_import
directive - Symlinks to the root source file that do not contain
@magento_import
- Symlinks to all other
.less
files imported recursively by the@magento_import
and@import
directives
Symlink is not created, and a copy of the processed file is published to pub/static
instead, if the source file differs from the processed one. One of the reasons for this difference might be the usage of the @import
directive without the file extension in the source file. See The @import directive usage for more details.
Styles debugging in client-side compilation mode
Client-side Less compilation is implemented using the native less.js
library. The default configuration is set in lib/web/less/config.less.js
. You can change it as needed.
Find detailed information about the configuration and other options of the less.js
used in a browser at http://lesscss.org/usage/#using-less-in-the-browser.
In client-side compilation mode, most of the stylesheet customizations display immediately after you reload a page in a browser.
There are certain types of changes, that require you to clear the pub/static/frontend/<Vendor>/<theme>/<locale>
directory and trigger the compilation and publication processes anew.
This is required if:
- You change the root source files that contain the
@magento_import
directive or the@import
directive where the imported file is specified without extension. - You rename, remove, or add a
.less
file imported with a@magento_import
or@import
directive but you did not correct the directives accordingly.
To clear the pub/static/frontend/<Vendor>/<theme>/<locale>
directory, delete the directory in the file system, and reload the store pages in a browser to trigger compilation and publication.
The @import
directive rules of usage
You can import local and remote .less
and .css
files in your .less
Magento stylesheets by using the standard Less @import
directive.
According to the @import
syntax, specifying the file extension for the imported file is not mandatory. For example, the following notation is allowed:
1
2
@import 'source/lib/_lib';
@import (css) 'styles';
In process of resolving the file path, Magento adds the .less
extension for the imported files in all @import
entrees. So in the processed files, the statements from the previous example will look like:
1
2
@import 'source/lib/_lib.less';
@import (css) 'styles.less';
As a result, the processed files are different from the source files. So in the client-side compilation mode, or when using grunt commands, Magento cannot use symlinks to the source files. Instead it uses the copies of processed files, and they are published to the pub/static
directory. In the case of importing CSS resources, this also results in not finding and not importing the required files.
Import remote CSS files
If you need to import a remote CSS file in your .less
source, use url()
notation. For example, to import a Google font:
1
@import url('//fonts.googleapis.com/css?family=Titillium+Web:400,300,200,600.css');
To include the font in your theme’s CSS files, use the @font-face
CSS rule for the fastest loading time.
In this instance, Magento will skip the @import
directive while resolving paths to the local resources.
The @magento_import
directive
@magento_import
is a Magento-specific Less directive that allows including multiple files by a name pattern. It is used to include files with the same name from the different locations, such as different modules. The standard @import
directive includes a single file, which is found according to the static files fallback.
@magento_import
can be used in the root source files of a theme only.
@magento_import
rules of usage
To include a .less
file using the @magento_import
directive:
-
To avoid any conflicts with the original Less syntax,
@magento_import
must be commented out with two slashes. Otherwise, the Less preprocessor ignores it.Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Comment in a Less document // Standard Less import directive // --------------------------------------------- @import 'source/_reset'; @import '_styles'; // // Custom Magento Less import directives // --------------------------------------------- //@magento_import 'source/_module.less'; // Theme modules //@magento_import 'source/_widgets.less'; // Theme widgets //@magento_import 'source/_extend.less'; // Extend for minor customization
-
@magento_import
must contain the file path. The path is specified relatively to the file, where the directive is called and put in either single (‘’) or double quotes (“”).The best practice is to specify the file extension in the path, though technically you can omit this.
@magento_import
processing
In the scope of static resources preprocessing, the built-in Less preprocessor:
- Searches for all
@magento_import
directives. - Replaces the original
@magento_import
directives with the standard@import
directives. The latter specify the paths to the particular files that correspond to the pattern specified in@magento_import
.
@magento_import
is used and processed in <Magento_Blank_theme_dir>/web/css/styles-l.less
:
Before | After |
---|---|
In /web/css/styles-l.less there's a following
directive:
.. //@magento_import 'source/_widgets.less'; // Theme widgets .. |
In the processed file, this results in the following: @import '../Magento_Catalog/css/source/_widgets.less'; @import '../Magento_Cms/css/source/_widgets.less'; @import '../Magento_Reports/css/source/_widgets.less'; @import '../Magento_Sales/css/source/_widgets.less'; // Theme widgets |