Strive is our second product that aims to improve Magento experience. This time, it's aim is making significant improvements to the frontend development workflow.
Magento 2 came out with improvements in many areas, including the ones on the frontend. Prototype was replaced by jQuery, templates are now based on HTML5 & CSS3, built-in LESS preprocessor and Knockout JS. By the time Magento 2 came out, more advanced web technologies rapidly evolved and began to gain traction. We feel that it should follow the same path to easier and progressive web development.
The thing we believe is going to make a difference is PostCSS.
As we believe that Magento frontend development process can always be improved especially by making it easier and faster. We created "Strive" for this exact reason. The postCSS choice is the right one as we believe it is the future of web development as CSS naturaly evolves.
Pragmatically, this is what we needed in our day to day development and postCSS delivered:
- Faster CSS Compilation
- Instant CSS Browser Injection
- Painless Static Content Deployment
As of now, we think that the goals are initially achieved and prooved in practice working on several Magento 2 custom projects.
Check out how all this works, our findings and how to contribute to this open source project.
Strive base is PostCSS, Browsersync and Gulp. We guess the only term which is relatively new here is PostCSS.
- Modularity - Use what you actually need and create your own environment. Unlike LESS or SASS which comes with nesting, variables, mixins, import... by default, PostCSS is vanilla! In practice this means that you write CSS syntax which will be compiled to CSS! Not much use of, right? Here come PostCSS plugins. You need variable support? Install postcss-simple-vars plugin. You need nesting support? Install postcss-nested. There are many plugins here on npm.
Plugins which offer some type of LESS/SASS features usually have very similar syntax to those. Strive PostCSS has somewhat of SASS-like feel.
- Overall development speed
- Fast CSS compilation thanks to PostCSS & Gulp.
- BrowserSync - instant css injecting into browser & weinre support
- Child theme support / realtime PostCSS theme fallback
- Theme static content being watched & transferred directly into 'pub/static' via Gulp. No need to use Magento content deploy during development!
- Minimal footprint - Small (as possible) set of PostCSS base styles and settings needed to get a working development system. Hey, it looks somehow like a Magento base theme, right? ;)
- Additional gulp tasks that come in handy during development
- Set of postCSS packages (SASS-like environment) needed to get a good development workflow
PostCSS files are organized inside web/src/preCSS folder. Main style.css and print.css are compiled to theme web/css and pub/static css folder. Styles.css has settings.css & files from lib & theme folder imported.
Lib - contains some mixins, reset, box-sizing and bare minimum of styles needed for certain elements.
Theme - contains styles related to a theme.
Bear in mind that Strive is not a port of blank (less) Magento theme and it does not rely on blank or luma theme (It doesn't have a parent theme).
Note that Magento blank theme comes with some js files. This projects subject was CSS only so JS files are borrowed from blank theme in order to get all functionalities. If something changes on this field and we decide to implement our own custom JS, we will announce it.
Test is performed on 'settings.css' and gulp taks execution time was between 215ms & 285ms.
(Tested on MacBook Pro i5/8GB RAM/SSD)
Creating a child theme with realtime PostCSS theme fallback
Child theme will need to have 'styles.css' inside the same folder structure like Strive (web/src/preCSS/), so you'll need to copy this file from 'Trive/blank' to the child theme.
After this, you'll probably want to override 'settings.css' and desired postCSS files. (And don't forget to add a parent theme into theme.xml)
The 'postcss-import' constantly watches newly imported CSS files inside 'Trive/theme-name' and if it can't find them here, it'll look into 'Trive/blank'. To override existing blank theme CSS file, add the CSS file with the same name and path inside the child theme. The 'postcss-import' will include that file instead of 'Trive/blank' CSS.
All of this happens in realtime, which means as soon as a new child theme override file is created, CSS gulp task recompiles it and changes are immediately injected into the browser. If child theme file gets deleted, fallback happens, so now the blank theme file is compiled. Same process happens, CSS task recompiles css, and changes are injected into the browser.
File override example: Trive/blank/web/src/preCSS/ theme/header.css
-> Trive/theme-name/web/src/preCSS/ theme/header.css
Test was performed on 'settings.css' and 'header.css'. Gulp task execution time was between 574ms & 864ms. We expected it would probably be slower as 'postcss-import' checks two paths, blank and child theme but we were pleasently surprised with it actually being fast.
(Tested on MacBook Pro i5/8GB RAM/SSD)
Note that header looses its styling once we make a override in child theme with new header.css, as it's actually empty.
Gulp - Starts a default gulp task (it drives 'css', 'static', 'watch' & 'browser-sync' tasks). At Trive, we mostly use this one.
Two main gulp src files are 'styles.css' & 'print.css'. After PostCSS processing, compiled CSS files are generated into theme's CSS folder (Strive comes with pre-compiled CSS) & 'pub/static' CSS folder. Sourcemaps are included in CSS task by default and cssnano processor (minification) with comments.
For production, just comment source maps and uncomment cssnano. Development and production modes will be probably added in the next versions of Strive.
Strive's compiled & minified 'styles.css' is around 57KB (one CSS file with responsive styling). This is significantly smaller than Magento blank theme which has 'styles-m.css' (254KB) & 'styles-l.css' (42KB) being both loaded on page load and styles-l.css for media screens above 768px.
One reason for results like this is our effort to a get working base Magento theme with less CSS selectors as possible. It is meant to be used as a starter theme.
PostCSS plugins used on this project:
- postcss-import - PostCSS plugin to transform @import rules by inlining content.
- postcss-simple-vars - PostCSS plugin for Sass-like variables
- postcss-extend - As close to cssnext @extend as possible for PostCSS
- postcss-nested - PostCSS plugin to unwrap nested rules like how Sass does it.
- autoprefixer - Parse CSS and add vendor prefixes to CSS rules using values from the Can I Use website
- cssnano - A modular minifier, built on top of the PostCSS ecosystem.
- css-mqpacker - Pack same CSS media query rules into one media query rule.
- postcss-mixins - PostCSS plugin for mixins
- lost - LostGrid is a powerful grid system built in PostCSS that works with any preprocessor and even vanilla CSS.
- postcss-responsive-type - PostCSS plugin that adds responsive magic to font-size
- postcss-custom-media - PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS
- postcss-color-function - PostCSS plugin to transform W3C CSS color function to more compatible CSS.
It works on CSS, HTML, images & js files. These files, if changed, are automatically transferred from theme to 'pub/static folder', so deployment of Magento static content would not be needed during development. Files in the theme folder don't have same the folder structure as in 'pub/static' folder (for example 'web' folder is not present in 'pub/static'). This was also considered and it shoud be working fine.
If the Strive package is installed through composer, both packages, 'theme-frontend-strive' and its dependency 'strive-gulp' are installed inside 'vendor/trive' (same parent directory) unlike manual install where it's advised to have the 'gulpfile' inside some folder in magento root. Static task resolves this problem too.
Actually, this would not be needed if only aboslute paths are used, but it was neccessary to create relative paths as the task is speedier that way. (Tested on MacBook Pro i5/8GB RAM/SSD)
'Gulp-watch' package is added to gulpfile so next to modified files, newly added files are watched also. Default 'gulp.watch' has this feature also but we experienced certain issues with new folders being added and that was the reason to use the gulp-watch package. In short, it's not needed to restart gulp task if new files are added.
Great tool when it comes to CSS browser injecting & synchronisation. No need for aditional browser livereload extensions. It has weinre support built in, so wireless mobile debug comes baked in.
Additional gulp tasks
'gulp clean' - Removes everything in 'var/cache', 'var/generation', 'var/view_preprocessed' & 'pub/staticfolder', except '.htaccess', magento blank & magento luma theme.
'gulp deploy' - It's a shorthand for 'bin/magento setup:static-content:deploy'.
We've added these features to our roadmap:
- Support for email styling
- Extensive borwser compatibility testing
Let there be more light
Strive comes with the compiled CSS, so once it's installed, and static content is deployed, you'll get a working starter theme. In order to modify theme's styling you'll need to have gulp & its plugins installed as explained above.
If you are not used to compiling CSS in your development environment this approach is not for you. Because of this, Strive is more focused on commerce teams with full developer support in this area at the moment.
Strive repository & installation details: https://github.com/trive-digital/Strive
Working demo of Strive can be checked here: http://strive.jakesharpdev.com/