I’m thinking about how keep things modular without duplicating style rules and/or polluting the HTML/stache markup with a bunch of generic class name noise…
For example, a Tachyon banner looks like this:
<article class="mw7 center ph3 ph5-ns tc br2 pv5 bg-washed-green dark-green mb5">
<h1 class="fw6 f3 f2-ns lh-title mt0 mb3">
This is a tagline. For x.
</h1>
<!--- snip --->
</article>
The excessive class names are ugly and distracting (in my opinion) and so perhaps a solution could be:
<can-component tag="basic-banner">
<style type="text/less">
display: block;
</style>
<view>
<article class="{{this.class.article}}">
<h1 class="{{this.class.h1}}">
This is a tagline. For x.
</h1>
<!--- snip --->
</article>
</view>
<script type="view-model">
export default {
class: {
article: 'mw7 center ph3 ph5-ns tc br2 pv5 bg-washed-green dark-green mb5',
h1: 'fw6 f3 f2-ns lh-title mt0 mb3',
}
}
</script>
</can-component>
A mixin/extend approach would allow me to accomplish that, but IIRC a preprocessor will inline (in the resulting .css
file) duplicate style rules for every class where the mixin is used (bloating the CSS file).
Perhaps to have the best of both worlds, CSS classes would need to be stored in JS variables? I’m not sure what implications this would have on caching etc., but it’s something React projects seem to use.
How can we keep component styles self-contained, but also eliminate the mass duplication of style rules, while still being able to make project-wide changes to generic things like padding and fonts?
- Add many generic class names to markup.
pro. No duplication of style rules.
con. Loads all style rules up front.
con. HTML/stache markup becomes noisy.
- Use Less variables and mixins in component style classes.
con. Lots of style rule duplication.
pro. Doesn’t load all style rules up front.
pro. HTML/stache markup remains clean.
- Store styles in JavaScript variables that can be shared between components.
pro. No duplication of style rules.
pro. Doesn’t load all style rules up front.
pro. HTML/stache markup remains clean.
I’m imagining a new kind of language, essentially a variant of Less that gets transpiled to JavaScript:
<can-component tag="basic-banner">
<style type="text/impress">
article {
import('mw7 center ph3 ph5-ns tc br2 pv5 bg-washed-green dark-green mb5');
// if not explicitly called here, imported
// mixins get invoked with default values
}
h1 {
import('fw6 f3 f2-ns lh-title mt0 mb3 some-parametric-mixin');
some-parametric-mixin(4px);
}
</style>
<view>
<article>
<h1>
This is a tagline. For x.
</h1>
<!--- snip --->
</article>
</view>
</can-component>
This might allow things like HTTP2 push to be able to just send the 'mw7 center ph3 ph5-ns tc br2 pv5 bg-washed-green dark-green mb5'
and 'fw6 f3 f2-ns lh-title mt0 mb3 my-parametric-mixin'
class style rules on demand and avoid sending down all the unused bytes and this should be more reliable than using jsdom with a build-time tool that removes unused css like uncss.