My last post was on Headless Magento at the DevExchange session at Imagine. The next table I sat in on was on frontend directions led by Bartek Igielski from SNOW.DOG. Bartek, with Alex Sommerville (Demac Media), had that morning presented a talk on frontend work being done by SNOW.DOG, which they had open sourced for community involvement. James Zetlen, who joined Magento recently as lead frontend architect and gave an entertaining talk on the first day of the conference, was also at the table, along with Brendan Falkowski and others. (Sorry if I missed your name here!)
My personal interest was to see if we could come up with a simple action plan for template and CSS management, so this post restates my thinking after the table discussion (Some of this I have said in previous posts on my old personal blog.). UI Components and NodeJS based build tools were discussed at a different table during the first session, and the group came to general agreement that we must integrate standardized and community-supported build tools from the Node community.
Selecting Good CSS Class Names
The day before I had chatted with Brendan over lunch and he had educated me a bit more on best practices for CSS, such as:
“Don’t try to create a CSS class name based on the page purpose, such as ‘newsletter-button’. Always create CSS class names to capture the semantics of the presentation wanted so it can be easily used across multiple pages that want the same style. That is use a descriptive name, rather than attempting to prescribe a purpose or use within the name. The name “large red square button would be more globally useful than “newsletter button.” Then, if needed, customize the PHTML file to use that new class name. It keeps the CSS more manageable and it’s rare for a serious build not to need to do some PHTML file tweaking anyway.”
Hopefully I did not mangle that too badly! ;-)
This was echoed by comments during the session. People were more interested in markup that could be easily reused across a site. There was almost active discouragement of making just one button look different. That was considered bad practice, not something desirable. This echoes some older principles of software design which are starting to have more influence in the frontend community, such as the “Zero-One-Infinity” rule: it makes sense to have zero types of button, or one type of button, or no limit to the types of button. But having any arbitrary number of types is an anti-pattern.
An interesting observation for extension developers then is the importance of clean PHTML files. Minimize the PHP code in PHTML files by keeping it in the block class, to make upgrades easier for developers using your extension in real projects. This is also a principle found across the frontend development world: templates and view logic should have as few branches as possible.
LESS vs Sass
Bartek and Alex had presented earlier around the relative popularity of LESS vs Sass, with LESS on the decline and significantly lower than Sass. Slides are available online, but keep an eye out for the video as well – it had some interesting content. But it felt to me like there were two types of developers at the table – those who were passionate for a specific technology, and those who were passionate about solving customer problems using standard, Magento-recommended technologies. People were using Less successfully to solve real customer problems.
The whole LESS to Sass port undertaken by SNOW.DOG was kicked off by the question of whether Magento should move to Sass. The official position from Magento is “we are not moving unless the benefit of moving clearly outweighs the disruption of the change to the customer base”. Developers can already use Sass with Magento 2, using replacement CSS files managed externally by projects such as Frontools – however those projects will also be responsible to deal with any CSS needed by extensions. Magento 2 moving to Sass would involve both Magento and extension developers updating the code base, followed by all existing sites using LESS files with local modifications today. That is why such a change would be so impactful.
More generally, even the strongest LESS vs. Sass partisans agreed that it would be best if the software offered a simple way to use any CSS preprocessor the implementer wanted, both in development and production.
Block Element Modifier (BEM)
Back at the DevExchange table, the discussion moved on to CSS class naming. The general feeling was the first step was to document a larger pattern library with correct new BEM class names. Developers needed simple, clear guidelines to follow.
There were several benefits listed around BEM, including:
I also got the impression there was preference for just making the break and kicking over to the new class names (and tweaked HTML where necessary) rather than trying to keep the old class names intact in parallel. There was also a recognition of keeping two sets of PHTML files for two sets of CSS class names would be a maintenance nightmare, and would not provide much benefit for extension developers (they need to pick one or the other). So, to roll out such a change I think will involve (1) clear communication in advance of the change and its benefits, (2) clear community support, and (3) forward warning of what future release the change would be rolled out in.
Note that a part of BEM is creating a CSS file per BEM block. While not discussed, this has the advantage of making it easier to replace CSS for say buttons across the site. With BEM there will be more, smaller CSS files, with clear structure – you can replace one file at a time, then use CSS file merging to improve performance. And to replace a single file you can do so by just using raw CSS if you want to (so quick patching at a customer site should be easier and more efficient).
Block Based PHTML versus Smaller (Component?) PHTML Files
There was also some discussion around whether the current PHTML files should be made smaller, to better align with blocks. The general feeling was that using PHTML files was fine, but it is important to clearly document the list of BEM blocks to ensure consistency of class name usage.
The question came up of effort to change the one thousand PHTML files to use the new approach. The idea of getting community help here to update a few files each came up. Some at the table seemed willing to be involved – first step however is to gather support for the change.
If Magento 2 moves to a CSS file per BEM block, where BEM block names are global, then we should consider a previous slack channel discussion, which raised the idea of extensions shipping with both pre-generated CSS files as well as the Less/Sass/etc file used to generate the CSS file. The reason for this is that it allows each module to pick its preprocessor of choice. All that matters at the end of the day is the CSS file. Shipping modules with generated CSS means that when you deploy the extension you don’t have to have the exact tool pipeline the extension developer used. Brendan reminded me of this during the discussion.
The challenge here, however, was related to CSS variables. Currently Magento supports global LESS variables, so you can change (for example) a “default highlight color” variable and all the different CSS classes would update to use your new value when the preprocessor ran. Pre-generated CSS files as in the previous paragraph would then not be possible – the files would need to be regenerated when the LESS variable was changed.
There was some discussion around the possibility of replacing the publicly modifiable LESS variables with CSS3 Variables, a different syntax and an emerging standard. James Zetlen summarized the new native CSS support for variables, but after some quick checking, only 70% of browsers in the wild currently support CSS variables. The question was then would this percentage be “high enough” by the time changes were rolled into an official release? Or, with the new BEM approach of a file per BEM class, was the need for global variables reduced enough that 100% browser support wasn’t necessary?
It was clear that people were using the global LESS variables in the current themes. Replacing them with CSS Variables would make LESS unable to understand and modify them via functions (though that might be a feature), and would add an extra step to the build process. However, it would be a way to support both the “global variables” that extensions and modules could hook into, and any CSS preprocessor or post-processor, instead of just LESS. One idea was to support an optional setting to use PostCSS to expand CSS variables by default, but allow sites to use native CSS variable support if they chose to—thus enabling extensions to use them on install. More thinking is required here.
One thing mentioned however was that declaring local variables in a specific BEM file was easy to do. This means you could have a convention for how to name the variables – so instead of having a truly global variable, you just give it the same name at the top of each BEM file. Changing the variable would be a matter of grepping through BEM files and adjusting multiple files. Not as easy as a global variable, but a possible stop-gap measure until CSS variables were available across a large enough set of web browsers.
Anyone else at the table is welcome to extend, clarify, or correct the above. Others are also welcome to comment or add your perspective. From the Magento perspective, I will repeat the guiding principle above – the benefit of change needs to significantly outweigh the cost of moving the whole community to a new approach. Changes such as Sass, CSS3 Variables, PostCSS, or BEM will be discussed openly in forums such as this before any change is likely.
But I left the session thinking this is a discussion worth having. In my mind a next step would be to turn the above into a more solid proposal for community comment, possibly with a forked version of Magento 2 to demonstrate what the new approach would feel like in real code (for a few files). Keep an eye out for that in a future blog post.
(And thanks James Zetlen for review and filling in some gaps!)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.