Skin 10.x: Frameworks Support
Description
Switching from Bootstrap 3 to Bootstrap 4
We are using the Bootstrap framework and LESS preprocessor for our Flamingo Skin since Sept 2014.
Bootstrap 4.0 launched in Jan 2018 after more than 2 years of active development (since Aug 2015). It's declared as a "major rewrite of the entire project", but some of the top changes that are affecting us are the break in backwards compatibility by having lots of variables and classes removed and deprecated, the switch from LESS preprocessor to Sass, the change of the Grid system to Flexbox, etc.
Comparison with other frameworks
Before deciding on switching between the two version, I've investigated if there isn't a new framework that was launched meanwhile that could replace Bootstrap. I've analysed 15 of the most popular front-end frameworks and you can see a summary in the spreadsheet.
I've compare on Google Trends how Bootstrap compares to top 5 frameworks according the GitHub Stars (Bootstrap, Semantic UI, Material-UI, Materialize, Foundation) for 1 and 5 years period. I've kept Foundation in the comparison since IMO you will find the most articles that offers it as a Bootstrap alternative. Also I've compare Bootstrap with one of the recent frameworks launched (Bulma), with one framework that support both Less and Sass (UIKit) and with a framework that support multiple layout techniques (Susy).
Bootstrap remains (according to the number of GitHub Stars and Google Trends) the most popular framework for the past 1-5 years. It has over 1000 contributors and over 17000 commits.
Backwards compatibility
Apparently there are no few frameworks that are concerned about backwards compatibility. Maybe because they are intended for small, rapid projects or maybe because some like to do complete UI redesigns. Unfortunately this is not ideal for a platform like our own that needs to support extensions and interface customisations from our users.
If we look at their migration documentation there are 24 occurrences of the word "removed", 27 occurrences of the word "dropped", 20 occurrences of "added", 15 occurrences of "no longer", etc.
LESS to Sass switch
LESS took a perceived big hit when Bootstrap framework announced they will be using Sass for their 4 version (Aug 2015). Although LESS is looking still strong in terms of GitHub Stars, it's kind of hard to have some clean numbers since there are various repositories and various implementations of the compilers (C++, Java, Ruby, JS, etc.)
Preprocessor | Latest Version | Latest Version Release | GitHub Stars Apr 2018 |
---|---|---|---|
LESS | 2.7.2 | Apr 2018 | 15,500 |
Sass | 3.5.6 | Mar 2018 | 11,279 |
We had these comparison discussions also in the past and we decided on LESS mainly because of Sass's variables conflict with Velocity variables (and because Bootstrap / Bootswatch were using it primary). Guillaume also benchmarked the performance.
One concerning thing is that from the 15 analysed frameworks only 18% are using LESS while 62% are using Sass. 2 frameworks (Skeleton and UIKit) are still providing both preprocessors, but they are only in the top 10.
Where are we using LESS?
- Skin ./xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/
- Color Themes ./xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-themes/
- Tree ./xwiki-platform-core/xwiki-platform-tree/xwiki-platform-tree-webjar/
- Menu ./xwiki-platform-core/xwiki-platform-menu/xwiki-platform-menu-ui/
- Notifications ./xwiki-platform-core/xwiki-platform-watchlist/xwiki-platform-watchlist-ui/
What are we using LESS for?
- Skin and ColorThemes variables - can be replaced with CSS Variables
- @media breakpoints - can't be replaced by CSS Vars, can be done by CSS duplication
- :extend() function for backwards compatibility styling inheritance, can be replaced by extensive CSS Vars
- @import - has CSS equivalent
- mixins - unique to preprocessors, can be done by CSS duplication
- minimal usage for .navbars, .text-*(), .make-*-columns(), .btn-*(), .table-(), .alert(), .panel(deprecated), .list-*()
- nested selectors
- etc.
Also, Bootstrap is using Libsass that provides a Java wrapper – jsass. There is also a plugin for Maven - LibSass Maven plugin, but these are not that popular as the C or Python versions. We would need to find a replacement for less4j.
Grid based on Flexbox
CSS Grid module is out and implemented in the major browsers since March 2017. Flexbox is best suited for creating individual components and collections (e.g. toolbars, image collections) while Grid is designed for creating full-page layouts. The Web community considers that CSS Grid is the way to create layouts and Flexbox is just another hack. Also there are several discussions that consider that the new Grid even removes the need to use a front-end framework to do layouts.
Also using Grid removes all the unneeded extra container needed by the frameworks like .row, .col* classes. Separation of concerns is enforced and the styling is exclusive done in CSS and not in the structure. This Divitis reduction that cleans up the HTMl, the easiness of use of Grid and advanced capabilities over Flexbox (the ability to overlap items, independent control of items, fraction units, etc.) make Grid a better suited candidate over Flexbox, that is currently implemented by 62.5% of selected frameworks.
Currently there is no known framework that implements CSS Grid and the Web community suggests that the framework's era has ended when talking about layout needs.
General considerations
I've compared these frameworks based on layout techniques and pre-processor, but another thing to consider is that each framework comes also with its suite of components. These can be considered by some that bloat the size of dependencies, but on the other hand provide very fast iterations on interface, since they come pre-styled and sometimes also with JavaScript interactions. We can find solutions for the Grid and most of the LESS functionality, but we will miss the Bootstrap components.
IMO we haven't overused LESS in our Platform modules, nor rewritten uicomponents to reuse LESS variables instead of Velocity variables. Our major use cases for the preprocessor are the Skin and the ColorThemes. These two modules should be rewritten to use native CSS Grid, cleaning the structure from useless divitis and generic Bootstrap classes.
Another use case where we are using the grid system is inside page's content, where we want to have multiple columns. Generic .row, .col-*-* Bootstrap classes should be changed with the generic {{columns}} macro. Its implementation should be improved to use Flexbox (careful on multiple row solution).
There is not really a question of removing LESS from XWiki. We don't know how it extensively it was used by our users, especially since we allow LESS in SSXs. The question remains if we should also support / integrate Sass, if we consider Sass just because of Bootstrap and how many features can be replaced with native CSS.
Also the power of Bootstrap is in its up to date, the complete documentation and an army of contributors that keep the project relevant.
Native CSS improvements
The past years have brought new functionality that can be used to replaces some of the things we've used preprocessors for. Also one advantage of native CSS is that is here to stay, compared to frameworks and preprocessors that come and go.
CSS Grid
CSS Grid module has reached in the past year a 87.4% global usage, which is quite impressive. The only problematic thing about it is the lack of support for IE11 which we are still supporting, but we could decide to drop the support for the browser or we could provide fallback using the feature queries and Flexbox.
CSS Variables
CSS Variables module has also a 87.73% global usage, again with IE11 as problematic. We could try to use them in order to remove the Velocity + LESS variables.
Conclusions
- Ideally we should not use preprocessors on the Skin / Color Themes part and try to rely on native CSS variants and replace as much of the functionality with native CSS.
- One of the major use cases for a framework is the layout and the grid system. This could be replaced with a native CSS Grid custom implementation.
- Preprocessor variables should be changed with CSS variables.
- We need to provide a solution for dynamic content inside the pages. We should rewrite the {{columns}} macro to use Flexbox.
- In order to use the new CSS techniques we need to drop support for IE11.
- We should definitely support Bootstrap and provide easy integration because of the multitude of components it offers, its documentation and community support. Our users will expect us to have Bootstrap support. Still we should restrict ourselves from using Bootstrap components for our Platform modules, because we will need to rewrite them on each non backward compatible Bootstrap version change (which is also an alternative, but needs man power) and because we have better alternatives for them.