Evaluating CSS frameworks
I have been using Bootstrap (v. 3) for several years now, and have been quite happy with it. However, Bootstrap relies on JQuery, and JQuery does not work well with reactive frameworks (Vue.js, React, Angluar, etc.), which is becoming a problem for me, as I am working to integrate Vue.js into our web-sites and products.
Also, it is redundant and feels wrong to include 2 JavaScript frameworks (Vue.js / JQuery) in my web-pages / products.
Bootstrap just announced that v. 5 will not have the JQuery dependency, but no information on if it will work better with reactive frameworks like Vue.js. It took a long time (years) from when Bootstrap v. 4 was announced until it was actually released, so who knows when v. 5 will be ready. Also I doubt that upgrading the web-sites to Bootstrap v. 5 will be much easier than replacing Bootstrap with something else entirely.
So it is time to ditch Bootstrap v. 3 and find a new CSS framework.
I want just one CSS framework that I can use for everything between static / server rendered plain HTML web-sites and Vue.js rendered SPAs - both to avoid spreading myself too thin as well as achieving a consistent look.
My (very subjective) requirements
My future CSS framework must...
- Work for plain web-pages with a minimum of JavaScript.
- Work for "web apps" / SPAs using Vue.js.
- Have a comprehensive list of components.
- Not be "Material Design".
Google's "Material Design" is nice for Android apps, but I am not fond of it for web-sites and desktop. For one thing - the text input boxes without borders and with the same background color as the page are not intuitive in these contexts. - Must be actively maintained.
Don't want to make a new start with something that is already abandoned.
Frameworks considered
Based on various "top X" lists around the web, I considered each of the following popular frameworks in relation to my requirements above:
- Bootstrap v. 4 (fails #1 / #2)
- Bootstrap-Vue.js (fails #1)
- Bulma / Buefy
- Element (fails #1)
- Foundation (fails #1)
- Framework7 (fails #1)
- Material Design Lite (fails #4 / #5)
- Materialize.css (fails #2 / #4)
- Milligram (fails #3)
- Picnic CSS (fails #5)
- PrimeVue (fails #1)
- Pure.css (fails #3 / #5)
- Quasar Framework (fails #1 / #4)
- Semantic UI (fails #1 / #5)
- Skeleton (fails #3 / #5)
- Spectre
- UIkit (fails #1)
- Vuetify (fails #1 / #4)
Which leaves 2 final candidates: Bulma/Buefy and Spectre.
And the winner is...
The Bulma/Buefy combo has the best of both worlds. For plain web-pages one can just use Bulma and small pieces of vanilla JavaScript. And when more functionality is needed, throw in Vue.js / Buefy. Spectre looks good too, but is not as popular (GitHub stars) as Bulma and doesn't have anything similar to Buefy (collection of Vue.js components).
However, while evaluating the different frameworks, I learned a few things:
- Most frameworks requires writing framework specific ugly HTML code - with way too many nested DIVs and classes. I am currently stuck with Bootstrap v. 3 for exactly this reason - it will require a lot of work to rewrite the HTML for something else. It seems to me that a more sustainable approach would be to style tag names directly instead of all those class names. For example CSS styling "a" instead of ".link". The "Picnic CSS" framework does exactly this and calls it "invasive CSS" vs. "opt-in CSS". Unfortunately Picnic CSS appears to be abandoned. (Update Feb 2021: "Skeleton" appears to do the same)
- Most (if not all) frameworks use CSS preprocessors (LESS/SASS/Stylus). I never really paid much attention to this before, but after customizing the color schemes of a couple of the frameworks with SASS, I now see the light. SASS is really cool and makes writing CSS a lot easier and a lot more manageable! There are Visual Studio extensions that compile SASS files (.scss) to native CSS on save, making it easy to integrate into my work flow.
- Most (if not all) frameworks use some kind of "CSS reset" to make different browsers render HTML the same way - and many use normalize.css.
- Many frameworks come with a lot of complete unnecessary "helper" classes. Like Bootstrap's
text-right
class.style="text-align:right"
does exactly the same, so why clutter things up with yet another proprietary class-name? - Many of the fancy controls offered by the frameworks, such as custom radio/check boxes, are really just CSS tricks that are easy to copy - and even easier to recreate under Vue.js.
- I will probably never use more than 10% of the CSS and JavaScript included with most frameworks. Chrome's "Coverage" tool for this web-site (built with Bootstrap v. 3): in other words - using a framework causes a lot of wasted bandwidth and browser CPU time. Some frameworks do allow picking specific modules (via SASS), but even so, there would still be a lot of unused CSS code.
- For layout, all the frameworks use CSS flexbox or floats. Using CSS grid would be simpler and make for cleaner HTML.
- (Added Feb 2021) Many frameworks include elaborate form validation visuals. This seems like a waste since HTML5 comes with this built-in (required, minlength, maxlength, min, max, type, and pattern attributes, and "setCustomValidity" for custom error messages).
- (Added Feb 2021) Using someone else's framework means that you are constantly playing version catchup - with the risk of messing up your web-sites / applications with each new framework update (learned the hard way that Bootstrap versions are not backwards compatible).
So rather than using one of the frameworks, I will probably end up writing my own custom CSS using:
- "invasive CSS"
- SASS
- Normalize.css as a base
- "Borrowed" styles and CSS tricks that I like from different frameworks
- CSS grid
- (Added Feb 2021) HTML5 form validation.
Other advantages to this approach:
- I learn more and become better at CSS/SASS.
- I can use the latest CSS features (such as grid) without waiting for a framework to catch up.
- Won't get stuck in an old and eventually unsupported version of a framework.
- Smaller footprint (include only what I need).
- Will be easier to use various 3rd party Vue.js components.
- No more DIV in DIV in DIV...