Recommendations: CSS stack for 2019?

Dear frontend developers of Clojureverse!

I learned CSS back in 2011, without frameworks, flexbox and grid, using divs and floats. The cool kids didn’t use tables! Coming back to the scene now, the landscape has changed. For instance, I noticed that Luminus is now bundling Bulma CSS instead of Bootstrap.

  • How do you develop CSS in 2019?
  • For a developer that understands the web stack, how do you recommend learning modern CSS?

I’d really appreciate some opinions, now that there are so many options.

Thanks!
Teodor

Hi Teodor,

at the moment we are switching from material design to Bulma, since the latter is more lightweight.

However I find it even more important to decide, how you are going to write the majority of your CSS code. Besides Sass, Less and Garden many people also tend to use inline styles nowadays. This talk was an eye-opener for me a few years ago:

http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html

The talk lists several typical CSS issues, for example that everything is in the global scope. I was astonished that almost all of these issues can be solved by embedding CSS in a programming language. Most of the time it is referred to as CSS-in-JS. In ClojureScript React libs like Reagent, it is very comfortable to work with inline styles.

We are going to use a combination of Bulma and inline styles.

Best regards,

Max

1 Like

This is one thing that Vue spoiled for me. With single file components, the CSS is scoped to only apply to the HTML it’s defined with. It’s in the same file and you don’t have to worry about global name collisions.

When I use something else, i.e. React or Clojurescript with Reagent, I tend to fall back on the inline method that Max mentioned. For most things, you can generate the style object at load time so it’s basically the same as what scoped CSS does. I haven’t found anything else that has a workflow I like.

1 Like

Recently I’m thinking how to write CSS in clojurescript. I started writing a little library called mcss.
The project is not finished and I’m still not sure if it is a good thing, but I’d like to share something I found while developing mcss.

Now I’m sure that it’s possible to do following:

Generating CSS via macro, As less runtime as possible

If we using CSS variables(Not supported on some old browsers), the CSS can be generated by macros while we still have the ability to do dynamic style.

;; Definition
(defstyled my-btn :button 
  {:background-color #(get % :bg-color)})

;; Usage
[my-btn {:css {:bg-color "#999"}}]

In this case the generated CSS is:

.some_ns__my-btn{background-color: var(--some-var);}

And the function my-btn is like(simplified):

(defn my-btn [props]
  (let [css (:css props)
        some-var (#(get % :bg-color) css)]
    [:button {:style {"--some-var" some-var}}]))

There are a few benefits:

  1. The most part of library itself won’t be packaged into the application, bundle size will be smaller, because it won’t ship the CSS compiler code and the specs.

  2. the initializing become much simpler, only one insertion when application is started, which make it really fast. And this performance won’t be affected by dynamic styles. Some libraries will insert new style into dom when they met same style with new values, this will be okay in most cases, but will be slow when there are a lot of dynamic styes.

Using munged function name as CSS class

Like Vue, writing scoped CSS make it easier for me to naming CSS and manage my code structure. In ClojureScript we have namespace, so it should be easy to use namepaced symbol for CSS names. In mcss I try to use function name, taken at runtime, so the CSS name is also munged. This make CSS some kind of shorter, especially for atomic CSS I’m going to talk.

Use Dead Code Elimination on atomic CSS

I personally think the atomic CSS is a good stuff that you write little piece of styles as atomic. Then you combine multiple atomic CSS into the component style.

(defa w-100 
  {:width "100%"})

(defa vh-100
  {:height "100vh"})

(defstyled fullscreen :div 
  [w-100 vh-100])

So how about having huge amount of built-in styles if we could only package those we use? The idea is using Dead Code Elimination. If we define atomic as function, If the function is not called at least once, it won’t be packaged in advanced mode. This is really nice because we don’t have to care the built-in size anymore, we can write large library or bring all other famous pure CSS library into this.

2 Likes

I’ve been using Tachyons for the last few years and honestly the approach has left me very happy. I wrote a bit more about it in this Architecture Decision Record I wrote for the cljdoc project.

To me Tachyons brings the simplicity of functional programming to CSS.

There’s other alternatives such as TailwindCSS and BassCSS.

Disclaimer: I haven’t really investigated CSS-in-JS in seriousness.

Other posts mentioning Tachyons:

  1. Preferred grid frameworks that work with Garden
  2. Favourite CSS frameworks for reframe/clojurescript?
3 Likes

+1. I’ve been using tachyons when doing more complicated stuff for the last couple of years too.

Thanks!

I was really curious about the larger picture, and not just the details. I’ll definitely read the ADR, and I might explore the cljdoc source further!

Hello Teodor!

We are using the xy-grid developed by Zurb Foundation as our base when doing layouts - combined with sass for design purposes compiled and minified with gulp.

I highly recommend learning/writing scss/sass and dumping the traditional way of writing css and leaving that to a compiler.

In my free time I’m using Hugo and Sass when building static webpages, which I think is a great way to start your learning curve again - and is transferable knowledge if you every want to use it in other projects in the future.

Best regards, Martin

2 Likes

Thanks for all the replies, guys. It’s great to hear some real opinions, and have a way to balance all the blog posts proclaiming to have found the best way ever to do design, and showing off all the new things.

I decided to take one step back to review the basics, and decided to buy a web design course to get up to speed quickly. That doesn’t solve the question on how to do CSS, or specifically, how to efficiently use CSS to design sites that work across devices, but it should give me a bit of a foundation to work from.

I also appreciate the opinions on inlining styles to avoid conflicts – that to me seems a bit like using pure functions instead of global references, which should suit a Clojure audience :heart_eyes:

Teodor

Bootstrap 4 is not too bad, and it has a lot of “utility” classes for things like margins, borders etc etc, kind of like Tachyons. It also has some more fancy components that you can choose to use or not.

If you do end up using Bootstrap in a CLJS application, think very hard before trying to find a react wrapper for it. I put react-bootstrap in our project and it’s a huge and sprawling project. I plan to remove it as soon as is possible. Perhaps other React wrappers are better, but I’d rather keep only the CSS and build my own functionality for whatever dynamic bits I want.

Similar to tachyons, I’ve been using TailwindCss and that has quickly become my favorite way to write css!

We use Garden and recently made the switch to Bulma, which we find much preferable to the Bootstrap bloat. The main concern I have with Bulma is its poor MS Edge support (afaik, it doesn’t even try). But our projects are also very simple in terms of CSS needs: simple design, some modals and tab bars, styled tables, and buttons here and there.

@Webdev_Tory May I ask what motivated your switch to Bulma? Are you happy you made the change? Do you notice much of a difference?

Just trying to tease out a bit of the subjective judgment :slight_smile:

I have also been using tailwind for my css needs. I like the utility approach. Bulma is okay as well, but in my opinion tailwind is more pleasant to work with.

The main difference for us so far is that Bulma allows dropdowns and modals without needing to import any javascript libraries (we just wire it with Clojurescript). This freedom from javascript has been very nice. I’ll have to look into tailwind, though.

1 Like

How do people feel about material UI assuming your using react?

I think the ideas in atomic layout are good.

If you have been away that long it’s gonna be a shock, ever year things change.