SNOW.DOG, led by Bartek Igielski, have been working on a Sass port of the blank theme Less files. This work is spinning up a number of parallel discussion threads, some of which I thought worth sharing here, with the intent of getting community feedback.
Example discussion threads include:
- Reviewing CSS class naming – will improved class names in the HTML simplify the Sass files? For example, should BEM be adopted for CSS class naming?
- What do themes really need to be able to change? How much can be truly expected of a theme, versus themes being good starting points and some site specific tinkering being required.
- What is the relationship between third party themes and extensions with respect to CSS?
- Does Magento’s support for CSS file merging need to be improved?
This blog post proposes conventions for introducing Sass into Magento 2, taking into account the needs of solution partners, extension/theme developers, and merchants with and without access to developers.
Note that there is no change in Magento functionality required for this proposal – the proposal is purely conventions to be followed by developers. That means it can be adopted at any time for any version of Magento 2.
Note that the Less files shipped with Magento are not the focus of this discussion. This blog post focuses on how best to introduce Sass in a consistent way.
Sass in the Blank Theme
So what is SNOW.DOG working on exactly? Shipped with Magento is a set of Less files representing
- A library of mixins for assembling CSS files, where changing a few variables (such as button styles) can consistently change the look and feel across the whole site.
- A base set of CSS rules used by common UI patterns.
SNOW.DOG are rewriting this set of Less files in Sass, in part due to the popularity of Sass over Less, and in part with an eye to simplification while retaining “just enough” flexibility.
Another goal is to avoid any customizations like the custom Magento “//@magento_import” Less directive, making it easier to use standard frontend development tools. (I have a number of previous posts in this area on my blog, such as on Gulp in Magento 2.) Instead of locating files across all modules, each module that needs to add additional CSS rules should instead add a new CSS file to hold those rules.
One of the topics that came up in the SNOW.DOG design was whether the Sass files can assume “Autoprefixer” is being used. (The same holds for any other “cool” CSS processing tools.) Autoprefixer is a utility (developed in NodeJS) that parses CSS files, expanding standard property names to all browser specific property names supported by older browser versions. For example, “-webkit-border-radius” was supported by the WebKit rendering engine before “border-radius” became officially accepted by the CSS standards body. So to increase compatibility across browsers, it is recommended to set “-webkit-border-radius” whenever “border-radius” is set.
This is what Autoprefixer does automatically – it reads in the standard property names and injects all known variants supported by older browsers. The benefit of Autoprefixer is a frontend developer can focus on a simple, clean CSS file. They do not need to worry about remembering all of the variations of property names.
So what did developers do before Autoprefixer? Mixin libraries like the Magento UI Library and the Sass Compass library used mixins to set properties. Instead of setting “border-radius” directly, a mixin is defined to set the property. This mixin can then set all of the variations. This works, but the Sass source file looks less clean as a result, and frontend developers could make a mistake of setting a property directly instead of using the provided mixin, resulting in not all variations being set.
Let’s explore the rules.
Proposed Rule for Extension/Theme Developers – Ship Sass and Precompiled CSS
It is proposed that extension/theme developers on Magento Marketplace follow a number of new rules. The first rule is as follows:
- Extensions/themes should be shipped both with Sass files for any new CSS needed by the extension/theme, plus the compiled CSS generated from that Sass file.
Magento will use the supplied CSS file when the extension/theme is loaded. This is because Magento only attempts Sass compilation if it finds a Sass file but no CSS file.
This rule implies the extension/theme developer is expected to install NodeJS and frontend CSS compilation tools like Grunt or Gulp. They use these tools to perform the Sass compilation (including the Autoprefixer), then include the generated CSS with the shipped product.
This is not what is done today with Less files in the Magento UI library. The Less files are compiled on demand, meaning themes do not need to ship CSS files – only changes to Less variables to change button colors or similar.
Similarly, the rule implies simple sites built purely from Marketplace purchases will not perform any Sass compilation. They will just use the supplied CSS files. This allows advanced Sass compilation tools to be used when developing for Magento, without need for low end merchants to have to worry about such tools.
It also means that deployments will be faster as there is no Sass compilation phase during deployments. (And the crowd goes wild!) The native CSS files are used instead. All such compilation will occur during development.
A limitation of this approach however is it is not possible to have locale specific CSS generated from Sass files. Locales are only known for a specific merchant site.
Question #1: Is the limitation of no per-locale Sass variations considered acceptable?
Proposed Rule for Extension/Theme Developers – Avoid Adding CSS Class Names that Themes Should Redefine
The next rule for extension/theme developers is:
- Try to use existing CSS class names to pick up colors for buttons etc that should be themed, rather than introducing additional CSS classes styled using existing Sass mixins/variables.
The reason for this rule is if an extension introduces a new CSS class name, themes in the Marketplace will not know of this name and so will not override the CSS with the new desired styling. Themes will only override the base Magento class name styles.
Question #2: Is it acceptable that extensions may ship with Sass files that use the default Sass rules and variables, but theme changes to Sass variables (e.g. to change a button color variable) will not be by default picked up. A developer will be required to recompile the Sass file in such cases.
Sometimes it is the correct to introduce new CSS class names. If a theme is not intended to change the supplied styling, then using new CSS class names is recommended.
Merchants Without Developers
For merchants building a site without developers, they will purchase extensions and themes from the Magento Marketplace and add them to the site. No Sass compilation will be required.
If any tweaking of the end result is required (e.g. the color of an extension button is incorrect), it will be required for a theme to be created to add/override the CSS rules to get the correct styling. One area of further exploration is how hard is it for non-developer merchants to create a simple CSS based theme, so small CSS tweaks or fixes can be applied. No NodeJS tools, just native CSS files. Such cases would help fix specific problems without recompiling the underlying Sass file.
Proposed Rule for Merchants with Developers – Recompile Sass Files to Pick Up Variable Changes
For merchants with developers,
- The developers can build a new extension or theme which recompiles the Sass files of an existing theme or module. These developers, like extension/theme developers, would be expected to install NodeJS based frontend tools.
This would be common for theme developers.
This is why extension developers and theme developers should provide the Sass files inside extensions/themes, even though normally the precompiled CSS files will be shipped. Sass variables can be changed in this process, to change button colors etc. New CSS files would be created that override the original CSS files.
In summary, the proposed conventions for Sass based CSS development with Magento is
- Ship extensions/themes with compiled CSS files so production sites can just use the CSS files.
- Developers would install NodeJS, change Sass variables, then recompile the CSS files. This is a development activity, not a deployment activity. (I should also note that Magento is working on a standard Docker image for development that includes NodeJS preinstalled.)
- Themes purchased from the Magento Marketplace will replace the default set of CSS files, rather than just change a few Sass variable settings with Magento recompiling the CSS files from the Sass files.
For example, in Magento Cloud, an implication of the above would be that the generated CSS files would be committed by developers to the git repository, rather than CSS compilation occuring during the build and deployment phases. The developer will be expected to install NodeJS and Grunt/Gulp and use them during frontend development, not rely on Magento performing Sass compilation on demand for CSS files.
It is a tricky balancing act allowing frontend developers to use the tools they love. Further, there seems to be still rapid change in the area of frontend development. As such, building tools such as Autoprefixer into Magento seems dangerous – new tools will be constantly appearing. As a result, delivering raw CSS files with modules seems preferable. Simple sites and merchants do not need to worry about such technologies – such technologies would be left to developers.
My main question in my mind is how well will themes replacing the base set of CSS files work (by recompiling the provided Sass files after any Sass variable changes). And will it be acceptable that new CSS classes introduced by extensions will not pick up such changes by default – a developer will need to recompile the files.
The reason I believe this may be acceptable is based on feedback that any sophisticated site is likely to need some tweaking by development resources. Keeping Sass and Autoprefix compilation out of Magento by shipping plain CSS files, and requiring developers to install and use NodeJS and similar tools instead, may be a better balance allowing frontend developers to use modern tools.
I do have another concern is that extensions and modules may need guidance around standardization of Sass compilation to avoid different extensions requiring different tools to be used. So the rules above may need to be extended to the Sass compilation instructions.
Well, over to you the reader! Are the positives worth the negatives? Feedback in the comments below welcome!