porsager/bss

Feature Request: Built-in CSS Class Composition

kevinfiol opened this issue ยท 7 comments

This is something I talked to @fuzetsu about in the Mithril.js Gitter.

I'm coming from using exclusively plain .css files and atomic CSS frameworks like Basscss. Usually, when I'd build a component (in my case, a Mithril component), I just chain a bunch of Basscss classes to style it. bss is great because I'm able to define additional component-specific styles very easily, and not have to go to a separate .css file to define 5 different atomic classes I'd probably only use once.

Here is how I'm using bss at the moment in conjunction with Basscss:

const bssClass = b`
  transition all 0.2s ease
`.$hover`
  background-color red
`;

const StyledBtn = `button.btn.btn-primary.not-rounded.${bssClass}`;

const Btn = {
    view: ({ attrs, children }) => m(StyledBtn, attrs, children)
};

Flems link

While this works totally fine for my purposes, I think it would be nice to have a built-in way to specify classes to compose, perhaps something like this:

const StyledBtn = b`
    $compose btn btn-primary not-rounded
    transition all 0.2s ease
`.$hover`
    background green
`;

Which may produce a className string such as

.btn.btn-primary.not-rounded.bdp4f3o1

for me to use with my component of choice.

What do you think?

Another not too bad option without implementing anything is:

const StyledBtn =
  'button.btn.btn-primary.not-rounded' +
  b`
    transition all 0.2s ease
  `.$hover`
    background green
  `

Assuming the issue is having the separate variables.

That said I do like the concept of $compose and (mostly because it fit in with some other stuff I was doing) I implemented in my css-in-js library.

Hey :)

Yeah, @fuzetsu beat me to it ๐Ÿ˜‹ I would advise good old string concatenation as well..

I'd love to hear what's to prefer wrt. having something like $compose instead though?

IF actually adding something like that wouldn't it be much neater just being able to chain classes inside like this:

b`
  .some.other.classes
  transition all 0.2s ease
`

That looks fine too, probably preferable. I admittedly lifted the $compose idea from our conversation in Gitter, but in hindsight, that probably makes more sense in zaftig than in bss.

Anyway, the benefits of this would be marginal in that I think it makes things a wee bit neater, and keeps all of my styling concerns 'within' bss.

@porsager wrt benefits of $compose

It's kinda of useful when not using hyperscript, in situations where it's not super easy to concat b cleanly.

<div class={'class1 class2 class3 ' + b`m 10`.class}>
</div>

Have to use .class since this is not hyperscript, and we're concatenating.

vs

<div class={b`
  $compose class1 class2 class3
  m 10
`}>
</div>

I'm considering removing it from zaftig though because I pretty much always use hyperscript, and don't often need to add other classes.

Thanks a lot for the experience feedback @fuzetsu !

With regards to needing .class I actually have a solution I just haven't gotten around to put it in yet (was waiting for bss 2.0) ;)

Behold the awesomeness ๐Ÿ˜‚

Ooh! I think I remember you sharing that somewhere. That's genius ๐Ÿ˜† Can't believe I forgot about it.

Might have to steal it ๐Ÿ‘€

Closing this as I found @fuzetsu 's solution elegant enough.