-
Notifications
You must be signed in to change notification settings - Fork 5
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
First draft #17
First draft #17
Changes from 2 commits
cc407e3
7ab13e4
e1e5a96
01c8eb8
df6c73e
b6a6c30
2697017
2464877
69f9aa5
4dfae65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,276 @@ | ||
## An attempt to find an interoperable CSSinJS format. | ||
## Interoperable CSSinJS format. | ||
|
||
The biggest issue at scale we currently have with all the CSSinJS implementations is that they are not sharable without the runtime. | ||
The biggest issue at scale we currently have with all CSSinJS implementations is that they are not sharable without the runtime. | ||
|
||
If we could find a format that is fast an easy to parse and supports all needs of current CSSinJS implementations, it could become a de facto standard for exported CSSinJS. | ||
We can define a format that is easy to parse and supports all the needs of the current CSSinJS implementations on top of CSS. | ||
|
||
It could be similar to how CommonJS and ES3 are currently the standard for sharing JavaScript modules on npm. | ||
Package maintainers will be able to publish JavaScript files to NPM with this format inside instead of plain CSS. | ||
|
||
## First draft | ||
|
||
Format is optimized for parsing in JavaScript, not for human readability. | ||
|
||
### Markers | ||
|
||
Examples are using constant names instead of values for readability within the spec. The resulting format will use their values. | ||
|
||
```js | ||
const RULE_START = 0 | ||
const RULE_END = 1 | ||
const SELECTOR = 2 | ||
const NAME = 3 | ||
const PROPERTY = 4 | ||
const VALUE = 5 | ||
const PARENT_SELECTOR = 6 | ||
const SPACE = 7 | ||
const CONDITION = 8 | ||
``` | ||
|
||
#### RULE_START | ||
|
||
Denotes the beginning of a rule, has a rule type. | ||
|
||
`[RULE_START, RULE_TYPE]` | ||
|
||
All rule types from https://wiki.csswg.org/spec/cssom-constants | ||
|
||
``` | ||
1 STYLE_RULE CSSOM | ||
2 CHARSET_RULE CSSOM | ||
3 IMPORT_RULE CSSOM | ||
4 MEDIA_RULE CSSOM | ||
5 FONT_FACE_RULE CSSOM | ||
6 PAGE_RULE CSSOM | ||
7 KEYFRAMES_RULE css3-animations | ||
8 KEYFRAME_RULE css3-animations | ||
9 MARGIN_RULE CSSOM | ||
10 NAMESPACE_RULE CSSOM | ||
11 COUNTER_STYLE_RULE css3-lists | ||
12 SUPPORTS_RULE css3-conditional | ||
13 DOCUMENT_RULE css3-conditional | ||
14 FONT_FEATURE_VALUES_RULE css3-fonts | ||
15 VIEWPORT_RULE css-device-adapt | ||
16 REGION_STYLE_RULE proposed for css3-regions | ||
17 CUSTOM_MEDIA_RULE mediaqueries | ||
``` | ||
|
||
#### RULE_END | ||
|
||
End of a rule. | ||
|
||
#### SELECTOR | ||
|
||
Denotes a selector or selector compound. | ||
|
||
Selector compound e.g. `.foo.bar` => `[SELECTOR, '.foo', '.bar']` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do plan to handle pseudo-classes with arguments, particularly ones that take selectors as arguments like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Idea: FUNCTION constant followed by a function name and arguments
When combined with another selector:
|
||
|
||
Multiple classes e.g. `.foo .bar` => `[SELECTOR, '.foo'], [SELECTOR, '.bar']` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't right; the description down below is that you generate multiple (The terms you want, btw, are "compound selector" for things like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, so this example should be Selector list e.g. |
||
|
||
#### NAME | ||
|
||
Instead of using a selector, a rule can be identified by a name. This is a preferred way instead of using hardcoded global class names. Consumer library will generate a selector for the rule and user can access it by name. | ||
We rely on the JavaScript module scope. Name should be unique within that module scope. | ||
|
||
E.g. `[NAME, 'bar']` | ||
|
||
#### PROPERTY | ||
|
||
Denotes a property name e.g.: `[PROPERTY, 'color']`. | ||
|
||
#### VALUE | ||
|
||
Denotes a property value e.g.: `[VALUE, 'red']`. | ||
|
||
Multiple comma separated values e.g.: `red, green` => `[VALUE, 'red'], [VALUE, 'green']`. | ||
|
||
#### PARENT_SELECTOR | ||
|
||
Denotes a reference to the selector of the parent rule. Only useful for nesting. | ||
|
||
E.g.: `&:hover` => `[SELECTOR, PARENT_SELECTOR, ':hover']` | ||
|
||
#### SPACE | ||
|
||
Denotes a space. | ||
|
||
E.g.: `& .foo` => `[SELECTOR, PARENT_SELECTOR, SPACE, '.foo']` | ||
|
||
#### CONDITION | ||
|
||
Denotes conditions for conditional rules. | ||
|
||
E.g. `@media all` => `[RULE_START, 4], [CONDITION, 'all']` | ||
|
||
|
||
## Examples | ||
|
||
### Global tag selector | ||
|
||
```css | ||
body { | ||
color: red | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, 'body'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'] | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Multiple classes in one selector | ||
|
||
```css | ||
body, .foo { | ||
color: red | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, 'body'], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'] | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Multiple values | ||
|
||
```css | ||
.foo { | ||
border-color: red, green | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'border'], | ||
[VALUE, 'red'], | ||
[VALUE, 'green'], | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Fallbacks | ||
|
||
```css | ||
.foo { | ||
color: red; | ||
color: linear-gradient(to right, red 0%, green 100%); | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'linear-gradient(to right, red 0%, green 100%)'], | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Conditionals | ||
|
||
```css | ||
@media all { | ||
.foo { | ||
color: red; | ||
} | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[CONDITION, 'all'], | ||
[RULE_START], | ||
[RULE_TYPE, 1], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'], | ||
[RULE_END], | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Nesting | ||
|
||
```css | ||
.foo { | ||
color: red; | ||
&:hover { | ||
color: green; | ||
} | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'], | ||
[RULE_START, 1], | ||
[SELECTOR, PARENT_SELECTOR, ':hover'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'green'], | ||
[RULE_END], | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Nesting with a compound selector and regular selector | ||
|
||
```css | ||
.foo { | ||
color: red; | ||
&.bar.baz .bla { | ||
color: green; | ||
} | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[SELECTOR, '.foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'], | ||
[RULE_START, 1], | ||
[SELECTOR, PARENT_SELECTOR, '.bar', '.baz', SPACE, '.bla'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'green'], | ||
[RULE_END], | ||
[RULE_END] | ||
] | ||
``` | ||
|
||
### Scoping or named rules | ||
|
||
```css | ||
.foo-123456 { | ||
color: red | ||
} | ||
``` | ||
|
||
```js | ||
[ | ||
[RULE_START, 1], | ||
[NAME, 'foo'], | ||
[PROPERTY, 'color'], | ||
[VALUE, 'red'] | ||
[RULE_END] | ||
] | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're gonna want more than
SPACE
if you're going this way - you want all five of the combinators, at least. Are you expecting this to be extensible by libraries, or always limited to the set of official CSS ones?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, maybe we need a
COMBINATOR
which can have these values:' ', '>', '>>', '+', '~']
Better ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or otherwise separate constant for each combinator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the combinators amount is limited to 5, I would probably go for separate constants, because this will make the result more compact.