Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composeable Style Sheets #131

Open
Randy-Buchholz opened this issue Aug 7, 2020 · 0 comments
Open

Composeable Style Sheets #131

Randy-Buchholz opened this issue Aug 7, 2020 · 0 comments

Comments

@Randy-Buchholz
Copy link

Composeable Style Sheets

Specify capabilities that make it easier to compose styles sheets from reusable parts and to create and manage these parts.

Concept

Constructable Style Sheets are a big step forward, especially in combination with Typed CSSOM, but are somewhat a monolithic approach. Parts of a sheet (Rules and Properties) are are conceptually identifiable, independent, and reusable entities that can be individually created, assembled, and reused in whole or part. The current approach does not directly support this , but requires these parts be child objects (at creation), created by the parents.

This concept would modify the specification to treat these parts as non-dependent objects that can be created individually, and assembled into sheets, or named and reusable fragments.

Background

A CSSRule is conceptually an identifiable, independent, and reusable entity that can exist in isolation. Currently creating a rule requires creating it through a sheet using a string representation - sheet.insertRule(ruleDefinitionString).

https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList
rules are NOT added or removed from the list directly, but instead here, only via its parent stylesheet. In fact, .insertRule() and .deleteRule() are not even methods of CSSRuleList, but only of CSSStyleSheet.

Once created, the rule can be extracted from the list, but not cleanly - there is no built-in way to uniquely identity a rule. Neither CSSRule or CSSStyleRule include an identifier property.

Properties are similar, but being more atomic have different limitations. Properties are identifiable to a degree by their target (ex, "div"), but this is not unique. Target/value pairs are the reusable/replaceable but don't support an identifier (other the entire description itself). Properties usually appear in groups. Like CSSRule, properties are created on other objects - rule.styleMap.set(target, value). The styleMap defines a set of properties. It too is conceptually identifiable, independent, and reusable. It too is limited by not being able to natively be created, identified, or manipulated independently.

Both rule and property collections have limited bulk manipulation capabilities.

Rules: https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList
but it must unfortunately be inserted into one, rule by rule, and unless combining lists, after any existing list therein is deleted, rule by rule

Composeable Style Sheets provide the capability to create, identify, and manipulate these component parts individually or in groups. These can be used to compose style sheets by assembling parts from multiple sources.
Implementations could use a pre-processing approach that feeds existing capabilities and/or alter exiting approaches.

Proposal Basics

This is still far from a proposal, but changes to the standard to support composeables would likely include things like

  • Specifying public constructors for component parts (CSSRule, etc.) - Change/Reversion
  • Specifying an identifier property for component parts - New
  • Specifying identifiable collections of components parts - New (e.g., promote internal lists to stand-alone types)
  • Specifying enhanced capabilities for assembling loose components into complete constructable sheets. - New/Change
  • Specifying a general collection object - CSSFragement - New

Argument Against

Managing parts can already be accomplished (one way) by creating "factory" sheets, creating parts and extracting them into maps. A "Sheet Builder" can encapsulate this.

This is a significant change to the specification.

Use

The general use case is the ability to create and use CSSFragment`s. A Fragment is an identifiable collection of identifiable parts (rule collection/property collections). Fragments can be used in ES to compose CSSStyleSheets and could possibly be extended into HTML/CSS to provide some of the capabilities of tools like LESS and SASS.

Thinking out loud...

ES

The syntax here is just for examples and not being suggested.

// Create (named) rules that can be reused
const rule1 = new CSSStyleRule( {name: "MyRule", target: "div"} );  
const rule2 = new CSSStyleRule( {name: "MyOtherRule", target: "div"} );  
ruleLibrary.addRules( [rule1, rule2] );  

const sheet = new CSSStyleSheet( {name: "MySheet"} );  
sheet.addRules( [  
    ruleLibrary.get( ["MyRule", "MyOtherRule"] ),  
    ruleLibrary2.get( ["R1", "R2"] )  
] );

// Create a named set of rules that can be reused
const fragment1 = new CSSFragment(  { name: "Fragment1",
  rules: [rule1, rule2]  
} );

sheet.compose( [fragment1] );

// Create a named set of properties that can be reused
const fragment2 = new CSSFragment( {
  name: "Fragement2",
  properties: [ 
    new CSSProperty( "color", "blue" ), 
    propertyLibrary.get("specialFont")
    ]  
} );

cssLib.addFragment(fragment2);

HTML/CSS

Maybe a stretch...

<script type="module">
    import * as CssLib from "/CssLib.mjs";
    const elem = document.querySeletor("#elem");
    elem.attributeStyleMap.append(CssLib.get("rule1")); // Extracts properties
</script>

// Possibly working with https://drafts.css-houdini.org/css-properties-values-api/  
//   and exposing a fragment as a properties, something like
<style>
    custom-element {
        --CssLib.baseStyles; // Common/shared properties
        color: blue;
    }
</style>

Note

I submitted something similar quite a while ago when I first looked at constructable sheets. (Hopefully this one makes better sense.) #91
And this one recently #130

My common theme is that if we have these nice objects we can use to manipulate styles wouldn't we want to bring them out and make them easier to use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant