Closed kaelig closed 7 years ago
hi kaelig!
I'm not sure I understand correctly - baz
should be a
, not a b
?
so:
.foo {
color: red;
}
.bar {
color: blue;
}
.baz {
color: red;
}
becomes
.a {
color: red;
}
.b {
color: blue;
}
{
"foo": "a",
"bar": "b",
"baz": "a"
}
(see here) – is this not what you'd expect?
Hey!
What I was trying to say is that if you apply two class names to an element you can run into that kind of side effect. Does this make sense?
ah yeah - it only works with one class per element. the idea is that you can @include
away to your heart's content, without worrying about bloating your final CSS and without knowing about what else also @include
s the things you @include
.
so in this example, you can do
.foo {
@include red;
@include big;
}
.bar {
@include blue;
@include big;
}
.baz {
@include red;
@include big;
}
etc without the need for .big
, .red
. all the duplication and bloat should be atomised away. it passes the responsibility for knowing what else uses the same styles to the machine, and you just think about the thing your styling.
that's the idea, anyway...
Thanks, that makes sense. I wonder how this works with things such as states (or modifiers) added via JS. e.g. if a
gets toggled via JS over b
, it will not have any effect whereas a change is expected.
yeah JS with this is tricky and not solved. it's one reason we've kind of left this on the shelf a bit – it def feels better dealt with by things like CSS modules (if you have a full-stack js app at least).
that said, it shouldn't be impossible. you should be able to extrapolate the classes you'd need to apply for the modifier class in the same the you would with HTML, so if you compiled your templates for your client side js you should be able to 'know' what classes your modifier class equated to. that or you'd need to ship the map, which may or may not be a problem, depending on how big it gets. as long as you approach each class in isolation, you should be ok.
if it ever got to production, i'd always imagined component-based sass file structure, much like CSS modules, in which you could @extend
local classes, to make modifiers simple, but only @include
if the styles you needed came from elsewhere. so you could have this quite safely:
// mixins.scss
@mixin font($size: 12px) {
font-size: $size;
font-weight: normal;
font-family: sans-serif;
}
// component-1.scss
@import 'mixins.scss';
.component-1 {
@include font;
color: red;
}
.component-1--blue {
@extend .component-1;
color: blue;
}
// component-2.scss
@import 'mixins.scss';
// not allowed to @import and @extend - duplicate instead
.component-2 {
@include font;
color: red;
}
.component-2--big {
@extend .component-2;
@include font(15px);
}
in each instance you're able to discretely style the component by state (in fact you have to). you know there will be zero side affects beyond you those can reasonably see (limited to that same file by convention – and probably linting), and the CSS is tiny.
so in your js src, i guess you'd need something like
myElement.classList.remove('component-2').add('component-2--big')
and then either compile the templates in a build step using the map to something like
myElement.classList.remove('a', 'b', 'c', 'd').add('f', 'b', 'c', 'd')
or send the map out for your own function to use do something similar like
function applyAtomisedClasses(el, className, map) {
el.classList = '';
DOMTokenList.prototype.add.apply(el, map[className]);
}
applyAtomisedClasses(myElement, 'component-2', map) ;
but yeah, never actually got that far, so far, in practise 😄
Thanks, I guess that makes sense!
oop, just updated :)
Here's a use case where the order of precedence gets overwritten by atomising class names: http://www.sassmeister.com/gist/3d1a7d19c08ebfdca383b16b33b7347a
What are the patterns/guidelines that can prevent getting into these kinds of situations?