source: imaps-frontend/node_modules/stylis/README.md

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 6.0 KB
Line 
1# STYLIS
2
3[![stylis](https://stylis.js.org/assets/logo.svg)](https://github.com/thysultan/stylis.js)
4
5A Light–weight CSS Preprocessor.
6
7[![Coverage](https://coveralls.io/repos/github/thysultan/stylis.js/badge.svg?branch=master)](https://coveralls.io/github/thysultan/stylis.js)
8[![Size](https://badgen.net/bundlephobia/minzip/stylis)](https://bundlephobia.com/result?p=stylis)
9[![Licence](https://badgen.net/badge/license/MIT/blue)](https://github.com/thysultan/stylis.js/blob/master/LICENSE)
10[![NPM](https://badgen.net/npm/v/stylis)](https://www.npmjs.com/package/stylis)
11
12## Installation
13
14* Use a Direct Download: `<script src=stylis.js></script>`
15* Use a CDN: `<script src=unpkg.com/stylis></script>`
16* Use NPM: `npm install stylis --save`
17
18## Features
19
20- nesting `a { &:hover {} }`
21- selector namespacing
22- vendor prefixing (flex-box, etc...)
23- minification
24- esm module compatible
25- tree-shaking-able
26
27## Abstract Syntax Structure
28
29```js
30const declaration = {
31 value: 'color:red;',
32 type: 'decl',
33 props: 'color',
34 children: 'red',
35 line: 1, column: 1
36}
37
38const comment = {
39 value: '/*@noflip*/',
40 type: 'comm',
41 props: '/',
42 children: '@noflip',
43 line: 1, column: 1
44}
45
46const ruleset = {
47 value: 'h1,h2',
48 type: 'rule',
49 props: ['h1', 'h2'],
50 children: [/* ... */],
51 line: 1, column: 1
52}
53
54const atruleset = {
55 value: '@media (max-width:100), (min-width:100)',
56 type: '@media',
57 props: ['(max-width:100)', '(min-width:100)'],
58 children: [/* ... */],
59 line: 1, column: 1
60}
61```
62
63## Example:
64
65```js
66import {compile, serialize, stringify} from 'stylis'
67
68serialize(compile(`h1{all:unset}`), stringify)
69```
70
71### Compile
72
73```js
74compile('h1{all:unset}') === [{value: 'h1', type: 'rule', props: ['h1'], children: [/* ... */]}]
75compile('--foo:unset;') === [{value: '--foo:unset;', type: 'decl', props: '--foo', children: 'unset'}]
76```
77
78### Tokenize
79
80```js
81tokenize('h1 h2 h3 [h4 h5] fn(args) "a b c"') === ['h1', 'h2', 'h3', '[h4 h5]', 'fn', '(args)', '"a b c"']
82```
83
84### Serialize
85
86```js
87serialize(compile('h1{all:unset}'), stringify)
88```
89
90### Vendor Prefixing
91
92```js
93import {compile, serialize, stringify, middleware, prefixer } from 'stylis';
94
95serialize(compile('div{display:flex;}'), middleware([prefixer, stringify]))
96```
97
98
99## Middleware
100
101The middleware helper is a convenient helper utility, that for all intents and purposes you can do without if you intend to implement your own traversal logic. The `stringify` middleware is one such middleware that can be used in conjunction with it.
102
103Elements passed to middlewares have a `root` property that is the immediate root/parent of the current element **in the compiled output**, so it references the parent in the already expanded CSS-like structure. Elements have also `parent` property that is the immediate parent of the current element **from the input structure** (structure representing the input string).
104
105### Traversal
106
107```js
108serialize(compile('h1{all:unset}'), middleware([(element, index, children) => {
109 assert(children === element.root.children && children[index] === element.children)
110}, stringify])) === 'h1{all:unset;}'
111```
112
113The abstract syntax tree also includes an additional `return` property for more niche uses.
114
115### Prefixing
116
117```js
118serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
119 if (element.type === 'decl' && element.props === 'all' && element.children === 'unset')
120 element.return = 'color:red;' + element.value
121}, stringify])) === 'h1{color:red;all:unset;}'
122```
123
124```js
125serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
126 if (element.type === 'rule' && element.props.indexOf('h1') > -1)
127 return serialize([{...element, props: ['h2', 'h3']}], callback)
128}, stringify])) === 'h2,h3{all:unset;}h1{all:unset;}'
129```
130
131### Reading
132
133```js
134serialize(compile('h1{all:unset}'), middleware([stringify, (element, index, children) => {
135 assert(element.return === 'h1{all:unset;}')
136}])) === 'h1{all:unset;color:red;}'
137```
138
139The middlewares in [src/Middleware.js](src/Middleware.js) dive into tangible examples of how you might implement a middleware, alternatively you could also create your own middleware system as `compile` returns all the nessessary structure to fork from.
140
141## Variables
142
143CSS variables are supported but a note should be made about the exotic use of css variables. The css spec mentions the following
144
145>The allowed syntax for custom properties is extremely permissive. The <declaration-value> production matches any sequence of one or more tokens, so long as the sequence does not contain <bad-string-token>, <bad-url-token>, unmatched <)-token>, <]-token>, or <}-token>, or top-level <semicolon-token> tokens or <delim-token> tokens with a value of "!".
146
147That is to say css variables according to the spec allows: `--foo: if(x > 5) this.width = 10;` and while this value is obviously useless as a variable, and would be invalid in any normal property, it still might be read and acted on by JavaScript and this is supported by Stylis, however things become slightly undefined when we start to include the `{` and `}` productions in our use of exotic css variables.
148
149For example consider the following: `--foo: {};`
150
151While this is valid CSS and supported. It is unclear what should happen when the rule collides with the implicit block termination rule that allows i.e `h1{color:red}`(notice the omitted semicolon) to also be a valid CSS production. This results in the following contradiction in: `h1{--example: {}` is it to be treated as `h1{--foo:{;}` or `h1{--foo:{}` the later of which is an unterminated block or in the following: `h1{--foo:{} h1{color:red;}` should it be `h1 {--foo:{}h1{color:red;};` where `{}h1{color:red;` is part of the css variable `--foo` and not a new rule or should it be something else?
152
153Nevertheless Stylis still supports the exotic forms highlighted in the spec, however you should consider it as a general rule to delimit such exotic uses of variables in strings or parentheses i.e: `h1{--foo:'{'}` or `h1{--foo:({)}`.
154
155## Benchmark
156
157Stylis is at-least 2X faster than its predecesor.
158
159### License
160
161Stylis is [MIT licensed](./LICENSE).
Note: See TracBrowser for help on using the repository browser.