├── .gitignore
├── .npmrc
├── .travis.yml
├── LICENSE
├── bin
├── dist.js
└── readme
│ ├── index.js
│ └── index.md
├── dist
└── gr8.css
├── index.js
├── package.json
├── readme.md
├── test.js
├── util.js
├── utils.js
└── utils
├── background.js
├── column.js
├── dev.js
├── display.js
├── flex.js
├── float.js
├── margin.js
├── misc.js
├── opacity.js
├── overflow.js
├── padding.js
├── positioning.js
├── size.js
└── type.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | package-lock.json
5 | .npmignore
6 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | node_js:
2 | - '4'
3 | - '6'
4 | - '7'
5 | sudo: false
6 | language: node_js
7 | env:
8 | - CXX=g++-4.8
9 | addons:
10 | apt:
11 | sources:
12 | - ubuntu-toolchain-r-test
13 | packages:
14 | - g++-4.8
15 | - xvfb
16 | script: npm run test
17 | install:
18 | - export DISPLAY=':99.0'
19 | - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
20 | - npm install
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Jon Gacnik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/bin/dist.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var path = require('path')
3 | var gr8 = require('..')
4 |
5 | var packageInfo = JSON.parse(fs.readFileSync(path.join(__dirname, '/../package.json'), 'utf8'))
6 |
7 | var header = '/*!\n * gr8.css • v' + packageInfo.version + '\n * github.com/jongacnik/gr8\n */\n'
8 | var css = gr8()
9 |
10 | fs.writeFile('dist/gr8.css', header + css, function (err) {
11 | if (err) {
12 | return console.log(err)
13 | }
14 |
15 | console.log('gr8 generated and saved to gr8.css')
16 | })
17 |
--------------------------------------------------------------------------------
/bin/readme/index.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var path = require('path')
3 | var gr8utils = require('../../utils')
4 |
5 | var templates = {}
6 |
7 | templates['defaults'] = JSON.stringify(gr8utils.defaults, null, 2)
8 |
9 | templates['utilityKeys'] = Object.keys(gr8utils.utils).map(function (key) {
10 | return '`' + key + '`'
11 | }).join(', ')
12 |
13 | templates['utilityIndex'] = Object.keys(gr8utils.utils).map(function (key) {
14 | return '- [' + key + '](#' + key + ')'
15 | }).join('\n')
16 |
17 | templates['utilitySections'] = Object.keys(gr8utils.utils).map(function (key) {
18 | var utils = {}
19 | utils[key] = gr8utils.utils[key]
20 | var css = gr8utils.generate(utils)
21 | return [
22 | ``,
23 | `${key}
`,
24 | '',
25 | '```css',
26 | css,
27 | '```',
28 | '',
29 | ' '
30 | ].join('\n')
31 | }).join('\n\n')
32 |
33 | var readme = fs.readFileSync(path.join(__dirname, '/index.md'), 'utf8')
34 |
35 | // d.i.y. {{ templates }}
36 | function tinyBars (str, data) {
37 | var re = /\{\{(.+)\}\}/gi
38 | return str.replace(re, function (match, val) {
39 | return data[val.trim()] || ''
40 | })
41 | }
42 |
43 | readme = tinyBars(readme, templates)
44 |
45 | fs.writeFile('readme.md', readme, function (err) {
46 | if (err) {
47 | return console.log(err)
48 | }
49 |
50 | console.log('readme generated and saved to readme.md')
51 | })
52 |
--------------------------------------------------------------------------------
/bin/readme/index.md:
--------------------------------------------------------------------------------
1 |
gr8
2 |
3 |
14 |
15 |
16 |
17 | Customizable, functional css utilities built using [**gr8-util**](https://github.com/jongacnik/gr8-util). Includes:
18 |
19 | - [**css stylesheet**](#stylesheet-usage) with default utilities
20 | - [**`gr8` function**](#javascript-usage) to generate and customize utilities within javascript
21 |
22 | ## Usage
23 |
24 | ### stylesheet usage
25 |
26 | The simplest way to use `gr8` is to include the [gr8.css](https://github.com/jongacnik/gr8/blob/master/dist/gr8.css) stylesheet in your project:
27 |
28 | ```html
29 |
30 | ```
31 |
32 | ### javascript usage
33 |
34 | Use the `gr8` function to generate utilities:
35 |
36 | ```js
37 | var gr8 = require('gr8')
38 | var css = gr8()
39 | ```
40 |
41 | [Detailed usage →](#api)
42 |
43 | ## Utilities
44 |
45 | Default utilities:
46 |
47 | {{ utilitySections }}
48 |
49 | ## API
50 |
51 | ### `css = gr8([opts])`
52 |
53 | Generate utilities and return a string of css. `opts` accepts the following values:
54 |
55 | #### Value Options
56 |
57 | - `opts.spacing` **[Mixed]** values for [margin](#margin) & [padding](#padding) utilities
58 | - `opts.fontSize` **[Mixed]** values for [font-size](#typography) utilities
59 | - `opts.lineHeight` **[Mixed]** values for [line-height](#typography) utilities
60 | - `opts.size` **[Mixed]** values for [width & height](#size) utilities
61 | - `opts.viewport` **[Mixed]** values for [viewport](#size) utilities
62 | - `opts.zIndex` **[Mixed]** values for [zIndex](#positioning) utilities
63 | - `opts.flexOrder` **[Mixed]** values for [flex-order](#flex) utilities
64 | - `opts.opacity` **[Mixed]** values for [opacity](#opacity) utilities
65 | - `opts.aspectRatio` **[Mixed]** values for [aspect ratio](#size) utilities
66 | - `opts.textColumn` **[Mixed]** values for [text columns](#typography) utilities
67 |
68 | #### Selector Options
69 |
70 | - `opts.selector` **[Function]** css selector template function
71 | - `opts.breakpoints` **[Object]** values for breakpoint utilities
72 | - `opts.breakpointSelector` **[String | Function]** selector shortcut or css selector template function
73 |
74 | #### Custom Utilities Options
75 |
76 | - `opts.utils` **[Array]** custom [gr8-util](https://github.com/jongacnik/gr8-util) utilities
77 | - `opts.exclude` **[Array]** keys of default utilities to exclude
78 |
79 | ## Value Options
80 |
81 | Value options customize numeric `gr8` utilities. They accept Numbers, Strings, Arrays, or Objects. Typically Arrays of Numbers will be used. Refer to [gr8-util](https://github.com/jongacnik/gr8-util) for details on all possible ways to format values.
82 |
83 | **Defaults:**
84 |
85 | ```js
86 | var css = gr8({
87 | spacing: [0, 1, 2, 3, 4],
88 | fontSize: [1, 1.2, 1.6, 2.4, 3.2, 6.4],
89 | lineHeight: [1, 1.5],
90 | size: [0, 100],
91 | viewport: [50, 100],
92 | zIndex: [0, 1, 2, 3, 4],
93 | flexOrder: [0, 1, 2, 3, 4],
94 | opacity: [0, 25, 50, 75, 100],
95 | aspectRatio: [25, 50, 75, 100],
96 | textColumn: [1, 2, 3, 4]
97 | })
98 | ```
99 |
100 | ## Selector Options
101 |
102 | Selector options control selectors & breakpoints.
103 |
104 | **Defaults:**
105 |
106 | ```js
107 | var css = gr8({
108 | selector: s => `.${s}`,
109 | breakpoints: {
110 | sm: 768,
111 | md: 1024,
112 | lg: 1280
113 | },
114 | breakpointSelector: 'attribute'
115 | })
116 | ```
117 |
118 | ### `opts.selector`
119 |
120 | Function expects a selector name as input and returns a css selector string as output. For example, to use an attribute selector instead of classes:
121 |
122 | ```js
123 | var css = gr8({
124 | selector: s => `[gr8~="${s}"]`
125 | })
126 | ```
127 |
128 |
129 | Output
130 |
131 | ```css
132 | [gr8~="fs1"]{font-size:1rem}
133 | [gr8~="fs1-6"]{font-size:1.6rem}
134 | /* etc... */
135 | ```
136 |
137 |
138 |
139 | ### `opts.breakpoints`
140 |
141 | Object keys are used in selector names and object values are used to define the media queries. Object values can either be integers (which results in a `min-width` media queries), or object values can be media query strings. Pass `false` to disable breakpoint utilities entirely:
142 |
143 | ```js
144 | var css = gr8({
145 | breakpoints: {
146 | small: 1024,
147 | medium: '(min-width:768px) and (max-width:1280px)',
148 | 'not-big': '(max-width:1024px)',
149 | portrait: '(orientation:portrait)'
150 | }
151 | })
152 | ```
153 |
154 |
155 | Output
156 |
157 | ```css
158 | @media (min-width:1024px) {
159 | [small~="fs1"]{font-size:1rem}
160 | /* etc... */
161 | }
162 | @media (min-width:768px) and (max-width:1280px) {
163 | [medium~="fs1"]{font-size:1rem}
164 | /* etc... */
165 | }
166 | @media (max-width:1024px) {
167 | [not-big~="fs1"]{font-size:1rem}
168 | /* etc... */
169 | }
170 | @media (orientation:portrait) {
171 | [portrait~="fs1"]{font-size:1rem}
172 | /* etc... */
173 | }
174 | ```
175 |
176 |
177 |
178 | **Note:** If you care about valid attribute selectors, prepend `data-` to your breakpoint keys.
179 |
180 | ### `opts.breakpointSelector`
181 |
182 | By default, attribute selectors are generated for breakpoint utilities (as seen above). Use prefixed classes instead by passing in the `'class'` shortcut, or provide a selector function for more granular control:
183 |
184 | #### `'class'` Shortcut
185 |
186 | ```js
187 | var css = gr8({
188 | breakpointSelector: 'class'
189 | })
190 | ```
191 |
192 |
193 | Output
194 |
195 | ```css
196 | @media (min-width:768px) {
197 | .sm-fs1{font-size:1rem}
198 | /* etc... */
199 | }
200 | @media (min-width:1024px) {
201 | .md-fs1{font-size:1rem}
202 | /* etc... */
203 | }
204 | @media (min-width:1280px) {
205 | .lg-fs1{font-size:1rem}
206 | /* etc... */
207 | }
208 | ```
209 |
210 |
211 |
212 | #### Selector Function
213 |
214 |
215 | ```js
216 | var css = gr8({
217 | breakpointSelector: key => s => `.gr8-${key}-${s}`
218 | })
219 | ```
220 |
221 |
222 | Output
223 |
224 | ```css
225 | @media (min-width:768px) {
226 | .gr8-sm-fs1{font-size:1rem}
227 | /* etc... */
228 | }
229 | @media (min-width:1024px) {
230 | .gr8-md-fs1{font-size:1rem}
231 | /* etc... */
232 | }
233 | @media (min-width:1280px) {
234 | .gr8-lg-fs1{font-size:1rem}
235 | /* etc... */
236 | }
237 | ```
238 |
239 |
240 |
241 | ## Custom Utilities Options
242 |
243 | [gr8-util](https://github.com/jongacnik/gr8-util) is a little function for generating functional css utilities. Given a plain object, concise css utilities are generated. All the utilities in `gr8` are built using this.
244 |
245 | Use the `utils` option to pass an array of `gr8-util` objects to extend the `gr8` output with custom utilities:
246 |
247 | ```js
248 | var bgcolor = {
249 | prop: {
250 | bgc: 'background-color'
251 | },
252 | vals: ['red', 'blue', 'green']
253 | }
254 |
255 | var fontcolor = {
256 | prop: {
257 | fc: 'color'
258 | },
259 | vals: ['red', 'blue', 'green']
260 | }
261 |
262 | var css = gr8({
263 | utils: [
264 | bgcolor,
265 | fontcolor
266 | ]
267 | })
268 | ```
269 |
270 |
271 | Output
272 |
273 | ```css
274 | .bgcr{background-color:red}
275 | .bgcb{background-color:blue}
276 | .bgcg{background-color:green}
277 | .fcr{color:red}
278 | .fcb{color:blue}
279 | .fcg{color:green}
280 | /* etc... */
281 |
282 | @media (min-width:768px) {
283 | [sm~="bgcr"]{background-color:red}
284 | [sm~="bgcb"]{background-color:blue}
285 | [sm~="bgcg"]{background-color:green}
286 | [sm~="fcr"]{color:red}
287 | [sm~="fcb"]{color:blue}
288 | [sm~="fcg"]{color:green}
289 | /* etc... */
290 | }
291 |
292 | @media (min-width:1024px) {
293 | [md~="bgcr"]{background-color:red}
294 | [md~="bgcb"]{background-color:blue}
295 | [md~="bgcg"]{background-color:green}
296 | [md~="fcr"]{color:red}
297 | [md~="fcb"]{color:blue}
298 | [md~="fcg"]{color:green}
299 | /* etc... */
300 | }
301 |
302 | @media (min-width:1280px) {
303 | [lg~="bgcr"]{background-color:red}
304 | [lg~="bgcb"]{background-color:blue}
305 | [lg~="bgcg"]{background-color:green}
306 | [lg~="fcr"]{color:red}
307 | [lg~="fcb"]{color:blue}
308 | [lg~="fcg"]{color:green}
309 | /* etc... */
310 | }
311 | ```
312 |
313 |
314 |
315 | **[Refer to gr8-util for further documentation on generating custom utilities.](https://github.com/jongacnik/gr8-util)**
316 |
317 | ### `opts.exclude`
318 |
319 | Use the `exclude` option to remove some of the default utilities. Accepts an array with any of the following values:
320 |
321 | {{ utilityKeys }}
322 |
323 | ## Proxies
324 |
325 | For more advanced use cases, some additional methods are proxied:
326 |
327 | ```js
328 | // direct access to gr8-util
329 | var gr8util = require('gr8/util')
330 | var css = gr8util({options})
331 | ```
332 |
333 | ```js
334 | // direct access to gr8-utils
335 | var gr8utils = require('gr8/utils')
336 | var css = gr8utils({options})
337 |
338 | // or even lower level
339 | gr8utils.generate(gr8utils.utils, gr8utils.defaults)
340 | ```
341 |
342 | ## Notes
343 |
344 | `gr8` is developed and iterated-on primarily for use within projects at [Folder Studio](http://folderstudio.com). It shares similarities with other functional css libraries like [tachyons](https://github.com/tachyons-css/tachyons) or [basscss](https://github.com/basscss/basscss), but diverges in its minimalism and customizability. `gr8` provides no colors, no borders, no font-families, etc out of the box, but instead provides ways to quickly define your own utilities for things like these using plain objects. It facilitates creating coherent design systems without imposing one by default.
345 |
346 | In any case, I hope you like it and perhaps find it useful!
347 |
348 | ## Todo
349 |
350 | - [ ] Advanced documentation
351 | - [ ] Website
352 |
353 | ## See Also
354 |
355 | - [gr8-util](https://github.com/jongacnik/gr8-util)
356 |
357 | ## License
358 |
359 | [MIT](https://github.com/jongacnik/gr8/blob/master/LICENSE)
360 |
--------------------------------------------------------------------------------
/dist/gr8.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * gr8.css • v3.1.3
3 | * github.com/jongacnik/gr8
4 | */
5 | .c1{width:8.33333%}
6 | .c2{width:16.66667%}
7 | .c3{width:25%}
8 | .c4{width:33.33333%}
9 | .c5{width:41.66667%}
10 | .c6{width:50%}
11 | .c7{width:58.33333%}
12 | .c8{width:66.66667%}
13 | .c9{width:75%}
14 | .c10{width:83.33333%}
15 | .c11{width:91.66667%}
16 | .c12{width:100%}
17 | .s1{width:100%}
18 | .s2{width:50%}
19 | .s3{width:33.33333%}
20 | .s4{width:25%}
21 | .s5{width:20%}
22 | .s6{width:16.66667%}
23 | .s7{width:14.28571%}
24 | .s8{width:12.5%}
25 | .s9{width:11.11111%}
26 | .s10{width:10%}
27 | .s11{width:9.09091%}
28 | .s12{width:8.33333%}
29 | .co0{margin-left:0}
30 | .co1{margin-left:8.33333%}
31 | .co2{margin-left:16.66667%}
32 | .co3{margin-left:25%}
33 | .co4{margin-left:33.33333%}
34 | .co5{margin-left:41.66667%}
35 | .co6{margin-left:50%}
36 | .co7{margin-left:58.33333%}
37 | .co8{margin-left:66.66667%}
38 | .co9{margin-left:75%}
39 | .co10{margin-left:83.33333%}
40 | .co11{margin-left:91.66667%}
41 | .co12{margin-left:100%}
42 | .m0{margin:0}
43 | .m1{margin:1rem}
44 | .m2{margin:2rem}
45 | .m3{margin:3rem}
46 | .m4{margin:4rem}
47 | .mt0{margin-top:0}
48 | .mt1{margin-top:1rem}
49 | .mt2{margin-top:2rem}
50 | .mt3{margin-top:3rem}
51 | .mt4{margin-top:4rem}
52 | .mr0{margin-right:0}
53 | .mr1{margin-right:1rem}
54 | .mr2{margin-right:2rem}
55 | .mr3{margin-right:3rem}
56 | .mr4{margin-right:4rem}
57 | .mb0{margin-bottom:0}
58 | .mb1{margin-bottom:1rem}
59 | .mb2{margin-bottom:2rem}
60 | .mb3{margin-bottom:3rem}
61 | .mb4{margin-bottom:4rem}
62 | .ml0{margin-left:0}
63 | .ml1{margin-left:1rem}
64 | .ml2{margin-left:2rem}
65 | .ml3{margin-left:3rem}
66 | .ml4{margin-left:4rem}
67 | .mx0{margin-left:0;margin-right:0}
68 | .mx1{margin-left:1rem;margin-right:1rem}
69 | .mx2{margin-left:2rem;margin-right:2rem}
70 | .mx3{margin-left:3rem;margin-right:3rem}
71 | .mx4{margin-left:4rem;margin-right:4rem}
72 | .my0{margin-top:0;margin-bottom:0}
73 | .my1{margin-top:1rem;margin-bottom:1rem}
74 | .my2{margin-top:2rem;margin-bottom:2rem}
75 | .my3{margin-top:3rem;margin-bottom:3rem}
76 | .my4{margin-top:4rem;margin-bottom:4rem}
77 | .p0{padding:0}
78 | .p1{padding:1rem}
79 | .p2{padding:2rem}
80 | .p3{padding:3rem}
81 | .p4{padding:4rem}
82 | .pt0{padding-top:0}
83 | .pt1{padding-top:1rem}
84 | .pt2{padding-top:2rem}
85 | .pt3{padding-top:3rem}
86 | .pt4{padding-top:4rem}
87 | .pr0{padding-right:0}
88 | .pr1{padding-right:1rem}
89 | .pr2{padding-right:2rem}
90 | .pr3{padding-right:3rem}
91 | .pr4{padding-right:4rem}
92 | .pb0{padding-bottom:0}
93 | .pb1{padding-bottom:1rem}
94 | .pb2{padding-bottom:2rem}
95 | .pb3{padding-bottom:3rem}
96 | .pb4{padding-bottom:4rem}
97 | .pl0{padding-left:0}
98 | .pl1{padding-left:1rem}
99 | .pl2{padding-left:2rem}
100 | .pl3{padding-left:3rem}
101 | .pl4{padding-left:4rem}
102 | .px0{padding-left:0;padding-right:0}
103 | .px1{padding-left:1rem;padding-right:1rem}
104 | .px2{padding-left:2rem;padding-right:2rem}
105 | .px3{padding-left:3rem;padding-right:3rem}
106 | .px4{padding-left:4rem;padding-right:4rem}
107 | .py0{padding-top:0;padding-bottom:0}
108 | .py1{padding-top:1rem;padding-bottom:1rem}
109 | .py2{padding-top:2rem;padding-bottom:2rem}
110 | .py3{padding-top:3rem;padding-bottom:3rem}
111 | .py4{padding-top:4rem;padding-bottom:4rem}
112 | .op0{opacity:0}
113 | .op25{opacity:0.25}
114 | .op50{opacity:0.5}
115 | .op75{opacity:0.75}
116 | .op100{opacity:1}
117 | .bgsc{background-size:cover}
118 | .bgsct{background-size:contain}
119 | .bgpc{background-position:center}
120 | .bgpt{background-position:top}
121 | .bgpr{background-position:right}
122 | .bgpb{background-position:bottom}
123 | .bgpl{background-position:left}
124 | .bgrn{background-repeat:no-repeat}
125 | .bgrx{background-repeat:repeat-x}
126 | .bgry{background-repeat:repeat-y}
127 | .x{display:flex}
128 | .xac{align-items:center}
129 | .xab{align-items:baseline}
130 | .xas{align-items:stretch}
131 | .xafs{align-items:flex-start}
132 | .xafe{align-items:flex-end}
133 | .xdr{flex-direction:row}
134 | .xdrr{flex-direction:row-reverse}
135 | .xdc{flex-direction:column}
136 | .xdcr{flex-direction:column-reverse}
137 | .xjc{justify-content:center}
138 | .xjb{justify-content:space-between}
139 | .xja{justify-content:space-around}
140 | .xjs{justify-content:flex-start}
141 | .xje{justify-content:flex-end}
142 | .xw{flex-wrap:wrap}
143 | .xwr{flex-wrap:wrap-reverse}
144 | .xwn{flex-wrap:nowrap}
145 | .xi{flex:initial}
146 | .xx{flex:1}
147 | .xa{flex:auto}
148 | .xn{flex:none}
149 | .xo0{order:0}
150 | .xo1{order:1}
151 | .xo2{order:2}
152 | .xo3{order:3}
153 | .xo4{order:4}
154 | .xot{order:-1}
155 | .xob{order:99}
156 | .df{display:flex}
157 | .db{display:block}
158 | .dib{display:inline-block}
159 | .di{display:inline}
160 | .dt{display:table}
161 | .dtc{display:table-cell}
162 | .dtr{display:table-row}
163 | .dn{display:none}
164 | .fl{float:left}
165 | .fr{float:right}
166 | .fn{float:none}
167 | .cf:after{content:"";display:block;clear:both}
168 | .oh{overflow:hidden}
169 | .os{overflow:scroll}
170 | .ov{overflow:visible}
171 | .oxh{overflow-x:hidden}
172 | .oxs{overflow-x:scroll}
173 | .oxv{overflow-x:visible}
174 | .oyh{overflow-y:hidden}
175 | .oys{overflow-y:scroll}
176 | .oyv{overflow-y:visible}
177 | .psa{position:absolute}
178 | .psr{position:relative}
179 | .psf{position:fixed}
180 | .pss{position:static}
181 | .t0{top:0}
182 | .r0{right:0}
183 | .b0{bottom:0}
184 | .l0{left:0}
185 | .z0{z-index:0}
186 | .z1{z-index:1}
187 | .z2{z-index:2}
188 | .z3{z-index:3}
189 | .z4{z-index:4}
190 | .w0{width:0}
191 | .w100{width:100%}
192 | .h0{height:0}
193 | .h100{height:100%}
194 | .vw50{width:50vw}
195 | .vw100{width:100vw}
196 | .vwmn50{min-width:50vw}
197 | .vwmn100{min-width:100vw}
198 | .vwmx50{max-width:50vw}
199 | .vwmx100{max-width:100vw}
200 | .vh50{height:50vh}
201 | .vh100{height:100vh}
202 | .vhmn50{min-height:50vh}
203 | .vhmn100{min-height:100vh}
204 | .vhmx50{max-height:50vh}
205 | .vhmx100{max-height:100vh}
206 | .ar25:before{padding-top:25%;content:"";display:block}
207 | .ar50:before{padding-top:50%;content:"";display:block}
208 | .ar75:before{padding-top:75%;content:"";display:block}
209 | .ar100:before{padding-top:100%;content:"";display:block}
210 | .fs1{font-size:1rem}
211 | .fs1-2{font-size:1.2rem}
212 | .fs1-6{font-size:1.6rem}
213 | .fs2-4{font-size:2.4rem}
214 | .fs3-2{font-size:3.2rem}
215 | .fs6-4{font-size:6.4rem}
216 | .lh1{line-height:1}
217 | .lh1-5{line-height:1.5}
218 | .fsn{font-style:normal}
219 | .fsi{font-style:italic}
220 | .fwn{font-weight:normal}
221 | .fwb{font-weight:bold}
222 | .tal{text-align:left}
223 | .tac{text-align:center}
224 | .tar{text-align:right}
225 | .taj{text-align:justify}
226 | .toi{text-overflow:initial}
227 | .toc{text-overflow:clip}
228 | .toe{text-overflow:ellipsis}
229 | .tdu{text-decoration:underline}
230 | .tdo{text-decoration:overline}
231 | .tdlt{text-decoration:line-through}
232 | .tdn{text-decoration:none}
233 | .ttu{text-transform:uppercase}
234 | .ttl{text-transform:lowercase}
235 | .ttc{text-transform:capitalize}
236 | .ttn{text-transform:none}
237 | .vabl{vertical-align:baseline}
238 | .vat{vertical-align:top}
239 | .vam{vertical-align:middle}
240 | .vab{vertical-align:bottom}
241 | .wsn{white-space:normal}
242 | .wsnw{white-space:nowrap}
243 | .wsp{white-space:pre}
244 | .wsi{white-space:inherit}
245 | .tc1{columns:1}
246 | .tc2{columns:2}
247 | .tc3{columns:3}
248 | .tc4{columns:4}
249 | .curp{cursor:pointer}
250 | .curd{cursor:default}
251 | .cura{cursor:alias}
252 | .curzi{cursor:zoom-in}
253 | .curzo{cursor:zoom-out}
254 | .usn{user-select:none}
255 | .usa{user-select:auto}
256 | .ust{user-select:text}
257 | .pen{pointer-events:none}
258 | .pea{pointer-events:auto}
259 | .vh{visibility:hidden}
260 | .vv{visibility:visible}
261 | .dev{outline:1px solid #912eff}
262 | .dev > * {outline:1px solid #5497ff}
263 | .dev > * > * {outline:1px solid #51feff}
264 | .dev > * > * > * {outline:1px solid #ff0000}
265 | .dev > * > * > * * {outline:1px solid #00ff00}
266 | @media (min-width:768px) {
267 | [sm~="c1"]{width:8.33333%}
268 | [sm~="c2"]{width:16.66667%}
269 | [sm~="c3"]{width:25%}
270 | [sm~="c4"]{width:33.33333%}
271 | [sm~="c5"]{width:41.66667%}
272 | [sm~="c6"]{width:50%}
273 | [sm~="c7"]{width:58.33333%}
274 | [sm~="c8"]{width:66.66667%}
275 | [sm~="c9"]{width:75%}
276 | [sm~="c10"]{width:83.33333%}
277 | [sm~="c11"]{width:91.66667%}
278 | [sm~="c12"]{width:100%}
279 | [sm~="s1"]{width:100%}
280 | [sm~="s2"]{width:50%}
281 | [sm~="s3"]{width:33.33333%}
282 | [sm~="s4"]{width:25%}
283 | [sm~="s5"]{width:20%}
284 | [sm~="s6"]{width:16.66667%}
285 | [sm~="s7"]{width:14.28571%}
286 | [sm~="s8"]{width:12.5%}
287 | [sm~="s9"]{width:11.11111%}
288 | [sm~="s10"]{width:10%}
289 | [sm~="s11"]{width:9.09091%}
290 | [sm~="s12"]{width:8.33333%}
291 | [sm~="co0"]{margin-left:0}
292 | [sm~="co1"]{margin-left:8.33333%}
293 | [sm~="co2"]{margin-left:16.66667%}
294 | [sm~="co3"]{margin-left:25%}
295 | [sm~="co4"]{margin-left:33.33333%}
296 | [sm~="co5"]{margin-left:41.66667%}
297 | [sm~="co6"]{margin-left:50%}
298 | [sm~="co7"]{margin-left:58.33333%}
299 | [sm~="co8"]{margin-left:66.66667%}
300 | [sm~="co9"]{margin-left:75%}
301 | [sm~="co10"]{margin-left:83.33333%}
302 | [sm~="co11"]{margin-left:91.66667%}
303 | [sm~="co12"]{margin-left:100%}
304 | [sm~="m0"]{margin:0}
305 | [sm~="m1"]{margin:1rem}
306 | [sm~="m2"]{margin:2rem}
307 | [sm~="m3"]{margin:3rem}
308 | [sm~="m4"]{margin:4rem}
309 | [sm~="mt0"]{margin-top:0}
310 | [sm~="mt1"]{margin-top:1rem}
311 | [sm~="mt2"]{margin-top:2rem}
312 | [sm~="mt3"]{margin-top:3rem}
313 | [sm~="mt4"]{margin-top:4rem}
314 | [sm~="mr0"]{margin-right:0}
315 | [sm~="mr1"]{margin-right:1rem}
316 | [sm~="mr2"]{margin-right:2rem}
317 | [sm~="mr3"]{margin-right:3rem}
318 | [sm~="mr4"]{margin-right:4rem}
319 | [sm~="mb0"]{margin-bottom:0}
320 | [sm~="mb1"]{margin-bottom:1rem}
321 | [sm~="mb2"]{margin-bottom:2rem}
322 | [sm~="mb3"]{margin-bottom:3rem}
323 | [sm~="mb4"]{margin-bottom:4rem}
324 | [sm~="ml0"]{margin-left:0}
325 | [sm~="ml1"]{margin-left:1rem}
326 | [sm~="ml2"]{margin-left:2rem}
327 | [sm~="ml3"]{margin-left:3rem}
328 | [sm~="ml4"]{margin-left:4rem}
329 | [sm~="mx0"]{margin-left:0;margin-right:0}
330 | [sm~="mx1"]{margin-left:1rem;margin-right:1rem}
331 | [sm~="mx2"]{margin-left:2rem;margin-right:2rem}
332 | [sm~="mx3"]{margin-left:3rem;margin-right:3rem}
333 | [sm~="mx4"]{margin-left:4rem;margin-right:4rem}
334 | [sm~="my0"]{margin-top:0;margin-bottom:0}
335 | [sm~="my1"]{margin-top:1rem;margin-bottom:1rem}
336 | [sm~="my2"]{margin-top:2rem;margin-bottom:2rem}
337 | [sm~="my3"]{margin-top:3rem;margin-bottom:3rem}
338 | [sm~="my4"]{margin-top:4rem;margin-bottom:4rem}
339 | [sm~="p0"]{padding:0}
340 | [sm~="p1"]{padding:1rem}
341 | [sm~="p2"]{padding:2rem}
342 | [sm~="p3"]{padding:3rem}
343 | [sm~="p4"]{padding:4rem}
344 | [sm~="pt0"]{padding-top:0}
345 | [sm~="pt1"]{padding-top:1rem}
346 | [sm~="pt2"]{padding-top:2rem}
347 | [sm~="pt3"]{padding-top:3rem}
348 | [sm~="pt4"]{padding-top:4rem}
349 | [sm~="pr0"]{padding-right:0}
350 | [sm~="pr1"]{padding-right:1rem}
351 | [sm~="pr2"]{padding-right:2rem}
352 | [sm~="pr3"]{padding-right:3rem}
353 | [sm~="pr4"]{padding-right:4rem}
354 | [sm~="pb0"]{padding-bottom:0}
355 | [sm~="pb1"]{padding-bottom:1rem}
356 | [sm~="pb2"]{padding-bottom:2rem}
357 | [sm~="pb3"]{padding-bottom:3rem}
358 | [sm~="pb4"]{padding-bottom:4rem}
359 | [sm~="pl0"]{padding-left:0}
360 | [sm~="pl1"]{padding-left:1rem}
361 | [sm~="pl2"]{padding-left:2rem}
362 | [sm~="pl3"]{padding-left:3rem}
363 | [sm~="pl4"]{padding-left:4rem}
364 | [sm~="px0"]{padding-left:0;padding-right:0}
365 | [sm~="px1"]{padding-left:1rem;padding-right:1rem}
366 | [sm~="px2"]{padding-left:2rem;padding-right:2rem}
367 | [sm~="px3"]{padding-left:3rem;padding-right:3rem}
368 | [sm~="px4"]{padding-left:4rem;padding-right:4rem}
369 | [sm~="py0"]{padding-top:0;padding-bottom:0}
370 | [sm~="py1"]{padding-top:1rem;padding-bottom:1rem}
371 | [sm~="py2"]{padding-top:2rem;padding-bottom:2rem}
372 | [sm~="py3"]{padding-top:3rem;padding-bottom:3rem}
373 | [sm~="py4"]{padding-top:4rem;padding-bottom:4rem}
374 | [sm~="op0"]{opacity:0}
375 | [sm~="op25"]{opacity:0.25}
376 | [sm~="op50"]{opacity:0.5}
377 | [sm~="op75"]{opacity:0.75}
378 | [sm~="op100"]{opacity:1}
379 | [sm~="bgsc"]{background-size:cover}
380 | [sm~="bgsct"]{background-size:contain}
381 | [sm~="bgpc"]{background-position:center}
382 | [sm~="bgpt"]{background-position:top}
383 | [sm~="bgpr"]{background-position:right}
384 | [sm~="bgpb"]{background-position:bottom}
385 | [sm~="bgpl"]{background-position:left}
386 | [sm~="bgrn"]{background-repeat:no-repeat}
387 | [sm~="bgrx"]{background-repeat:repeat-x}
388 | [sm~="bgry"]{background-repeat:repeat-y}
389 | [sm~="x"]{display:flex}
390 | [sm~="xac"]{align-items:center}
391 | [sm~="xab"]{align-items:baseline}
392 | [sm~="xas"]{align-items:stretch}
393 | [sm~="xafs"]{align-items:flex-start}
394 | [sm~="xafe"]{align-items:flex-end}
395 | [sm~="xdr"]{flex-direction:row}
396 | [sm~="xdrr"]{flex-direction:row-reverse}
397 | [sm~="xdc"]{flex-direction:column}
398 | [sm~="xdcr"]{flex-direction:column-reverse}
399 | [sm~="xjc"]{justify-content:center}
400 | [sm~="xjb"]{justify-content:space-between}
401 | [sm~="xja"]{justify-content:space-around}
402 | [sm~="xjs"]{justify-content:flex-start}
403 | [sm~="xje"]{justify-content:flex-end}
404 | [sm~="xw"]{flex-wrap:wrap}
405 | [sm~="xwr"]{flex-wrap:wrap-reverse}
406 | [sm~="xwn"]{flex-wrap:nowrap}
407 | [sm~="xi"]{flex:initial}
408 | [sm~="xx"]{flex:1}
409 | [sm~="xa"]{flex:auto}
410 | [sm~="xn"]{flex:none}
411 | [sm~="xo0"]{order:0}
412 | [sm~="xo1"]{order:1}
413 | [sm~="xo2"]{order:2}
414 | [sm~="xo3"]{order:3}
415 | [sm~="xo4"]{order:4}
416 | [sm~="xot"]{order:-1}
417 | [sm~="xob"]{order:99}
418 | [sm~="df"]{display:flex}
419 | [sm~="db"]{display:block}
420 | [sm~="dib"]{display:inline-block}
421 | [sm~="di"]{display:inline}
422 | [sm~="dt"]{display:table}
423 | [sm~="dtc"]{display:table-cell}
424 | [sm~="dtr"]{display:table-row}
425 | [sm~="dn"]{display:none}
426 | [sm~="fl"]{float:left}
427 | [sm~="fr"]{float:right}
428 | [sm~="fn"]{float:none}
429 | [sm~="cf"]:after{content:"";display:block;clear:both}
430 | [sm~="oh"]{overflow:hidden}
431 | [sm~="os"]{overflow:scroll}
432 | [sm~="ov"]{overflow:visible}
433 | [sm~="oxh"]{overflow-x:hidden}
434 | [sm~="oxs"]{overflow-x:scroll}
435 | [sm~="oxv"]{overflow-x:visible}
436 | [sm~="oyh"]{overflow-y:hidden}
437 | [sm~="oys"]{overflow-y:scroll}
438 | [sm~="oyv"]{overflow-y:visible}
439 | [sm~="psa"]{position:absolute}
440 | [sm~="psr"]{position:relative}
441 | [sm~="psf"]{position:fixed}
442 | [sm~="pss"]{position:static}
443 | [sm~="t0"]{top:0}
444 | [sm~="r0"]{right:0}
445 | [sm~="b0"]{bottom:0}
446 | [sm~="l0"]{left:0}
447 | [sm~="z0"]{z-index:0}
448 | [sm~="z1"]{z-index:1}
449 | [sm~="z2"]{z-index:2}
450 | [sm~="z3"]{z-index:3}
451 | [sm~="z4"]{z-index:4}
452 | [sm~="w0"]{width:0}
453 | [sm~="w100"]{width:100%}
454 | [sm~="h0"]{height:0}
455 | [sm~="h100"]{height:100%}
456 | [sm~="vw50"]{width:50vw}
457 | [sm~="vw100"]{width:100vw}
458 | [sm~="vwmn50"]{min-width:50vw}
459 | [sm~="vwmn100"]{min-width:100vw}
460 | [sm~="vwmx50"]{max-width:50vw}
461 | [sm~="vwmx100"]{max-width:100vw}
462 | [sm~="vh50"]{height:50vh}
463 | [sm~="vh100"]{height:100vh}
464 | [sm~="vhmn50"]{min-height:50vh}
465 | [sm~="vhmn100"]{min-height:100vh}
466 | [sm~="vhmx50"]{max-height:50vh}
467 | [sm~="vhmx100"]{max-height:100vh}
468 | [sm~="ar25"]:before{padding-top:25%;content:"";display:block}
469 | [sm~="ar50"]:before{padding-top:50%;content:"";display:block}
470 | [sm~="ar75"]:before{padding-top:75%;content:"";display:block}
471 | [sm~="ar100"]:before{padding-top:100%;content:"";display:block}
472 | [sm~="fs1"]{font-size:1rem}
473 | [sm~="fs1-2"]{font-size:1.2rem}
474 | [sm~="fs1-6"]{font-size:1.6rem}
475 | [sm~="fs2-4"]{font-size:2.4rem}
476 | [sm~="fs3-2"]{font-size:3.2rem}
477 | [sm~="fs6-4"]{font-size:6.4rem}
478 | [sm~="lh1"]{line-height:1}
479 | [sm~="lh1-5"]{line-height:1.5}
480 | [sm~="fsn"]{font-style:normal}
481 | [sm~="fsi"]{font-style:italic}
482 | [sm~="fwn"]{font-weight:normal}
483 | [sm~="fwb"]{font-weight:bold}
484 | [sm~="tal"]{text-align:left}
485 | [sm~="tac"]{text-align:center}
486 | [sm~="tar"]{text-align:right}
487 | [sm~="taj"]{text-align:justify}
488 | [sm~="toi"]{text-overflow:initial}
489 | [sm~="toc"]{text-overflow:clip}
490 | [sm~="toe"]{text-overflow:ellipsis}
491 | [sm~="tdu"]{text-decoration:underline}
492 | [sm~="tdo"]{text-decoration:overline}
493 | [sm~="tdlt"]{text-decoration:line-through}
494 | [sm~="tdn"]{text-decoration:none}
495 | [sm~="ttu"]{text-transform:uppercase}
496 | [sm~="ttl"]{text-transform:lowercase}
497 | [sm~="ttc"]{text-transform:capitalize}
498 | [sm~="ttn"]{text-transform:none}
499 | [sm~="vabl"]{vertical-align:baseline}
500 | [sm~="vat"]{vertical-align:top}
501 | [sm~="vam"]{vertical-align:middle}
502 | [sm~="vab"]{vertical-align:bottom}
503 | [sm~="wsn"]{white-space:normal}
504 | [sm~="wsnw"]{white-space:nowrap}
505 | [sm~="wsp"]{white-space:pre}
506 | [sm~="wsi"]{white-space:inherit}
507 | [sm~="tc1"]{columns:1}
508 | [sm~="tc2"]{columns:2}
509 | [sm~="tc3"]{columns:3}
510 | [sm~="tc4"]{columns:4}
511 | [sm~="curp"]{cursor:pointer}
512 | [sm~="curd"]{cursor:default}
513 | [sm~="cura"]{cursor:alias}
514 | [sm~="curzi"]{cursor:zoom-in}
515 | [sm~="curzo"]{cursor:zoom-out}
516 | [sm~="usn"]{user-select:none}
517 | [sm~="usa"]{user-select:auto}
518 | [sm~="ust"]{user-select:text}
519 | [sm~="pen"]{pointer-events:none}
520 | [sm~="pea"]{pointer-events:auto}
521 | [sm~="vh"]{visibility:hidden}
522 | [sm~="vv"]{visibility:visible}
523 | [sm~="dev"]{outline:1px solid #912eff}
524 | [sm~="dev"] > * {outline:1px solid #5497ff}
525 | [sm~="dev"] > * > * {outline:1px solid #51feff}
526 | [sm~="dev"] > * > * > * {outline:1px solid #ff0000}
527 | [sm~="dev"] > * > * > * * {outline:1px solid #00ff00}
528 | }
529 | @media (min-width:1024px) {
530 | [md~="c1"]{width:8.33333%}
531 | [md~="c2"]{width:16.66667%}
532 | [md~="c3"]{width:25%}
533 | [md~="c4"]{width:33.33333%}
534 | [md~="c5"]{width:41.66667%}
535 | [md~="c6"]{width:50%}
536 | [md~="c7"]{width:58.33333%}
537 | [md~="c8"]{width:66.66667%}
538 | [md~="c9"]{width:75%}
539 | [md~="c10"]{width:83.33333%}
540 | [md~="c11"]{width:91.66667%}
541 | [md~="c12"]{width:100%}
542 | [md~="s1"]{width:100%}
543 | [md~="s2"]{width:50%}
544 | [md~="s3"]{width:33.33333%}
545 | [md~="s4"]{width:25%}
546 | [md~="s5"]{width:20%}
547 | [md~="s6"]{width:16.66667%}
548 | [md~="s7"]{width:14.28571%}
549 | [md~="s8"]{width:12.5%}
550 | [md~="s9"]{width:11.11111%}
551 | [md~="s10"]{width:10%}
552 | [md~="s11"]{width:9.09091%}
553 | [md~="s12"]{width:8.33333%}
554 | [md~="co0"]{margin-left:0}
555 | [md~="co1"]{margin-left:8.33333%}
556 | [md~="co2"]{margin-left:16.66667%}
557 | [md~="co3"]{margin-left:25%}
558 | [md~="co4"]{margin-left:33.33333%}
559 | [md~="co5"]{margin-left:41.66667%}
560 | [md~="co6"]{margin-left:50%}
561 | [md~="co7"]{margin-left:58.33333%}
562 | [md~="co8"]{margin-left:66.66667%}
563 | [md~="co9"]{margin-left:75%}
564 | [md~="co10"]{margin-left:83.33333%}
565 | [md~="co11"]{margin-left:91.66667%}
566 | [md~="co12"]{margin-left:100%}
567 | [md~="m0"]{margin:0}
568 | [md~="m1"]{margin:1rem}
569 | [md~="m2"]{margin:2rem}
570 | [md~="m3"]{margin:3rem}
571 | [md~="m4"]{margin:4rem}
572 | [md~="mt0"]{margin-top:0}
573 | [md~="mt1"]{margin-top:1rem}
574 | [md~="mt2"]{margin-top:2rem}
575 | [md~="mt3"]{margin-top:3rem}
576 | [md~="mt4"]{margin-top:4rem}
577 | [md~="mr0"]{margin-right:0}
578 | [md~="mr1"]{margin-right:1rem}
579 | [md~="mr2"]{margin-right:2rem}
580 | [md~="mr3"]{margin-right:3rem}
581 | [md~="mr4"]{margin-right:4rem}
582 | [md~="mb0"]{margin-bottom:0}
583 | [md~="mb1"]{margin-bottom:1rem}
584 | [md~="mb2"]{margin-bottom:2rem}
585 | [md~="mb3"]{margin-bottom:3rem}
586 | [md~="mb4"]{margin-bottom:4rem}
587 | [md~="ml0"]{margin-left:0}
588 | [md~="ml1"]{margin-left:1rem}
589 | [md~="ml2"]{margin-left:2rem}
590 | [md~="ml3"]{margin-left:3rem}
591 | [md~="ml4"]{margin-left:4rem}
592 | [md~="mx0"]{margin-left:0;margin-right:0}
593 | [md~="mx1"]{margin-left:1rem;margin-right:1rem}
594 | [md~="mx2"]{margin-left:2rem;margin-right:2rem}
595 | [md~="mx3"]{margin-left:3rem;margin-right:3rem}
596 | [md~="mx4"]{margin-left:4rem;margin-right:4rem}
597 | [md~="my0"]{margin-top:0;margin-bottom:0}
598 | [md~="my1"]{margin-top:1rem;margin-bottom:1rem}
599 | [md~="my2"]{margin-top:2rem;margin-bottom:2rem}
600 | [md~="my3"]{margin-top:3rem;margin-bottom:3rem}
601 | [md~="my4"]{margin-top:4rem;margin-bottom:4rem}
602 | [md~="p0"]{padding:0}
603 | [md~="p1"]{padding:1rem}
604 | [md~="p2"]{padding:2rem}
605 | [md~="p3"]{padding:3rem}
606 | [md~="p4"]{padding:4rem}
607 | [md~="pt0"]{padding-top:0}
608 | [md~="pt1"]{padding-top:1rem}
609 | [md~="pt2"]{padding-top:2rem}
610 | [md~="pt3"]{padding-top:3rem}
611 | [md~="pt4"]{padding-top:4rem}
612 | [md~="pr0"]{padding-right:0}
613 | [md~="pr1"]{padding-right:1rem}
614 | [md~="pr2"]{padding-right:2rem}
615 | [md~="pr3"]{padding-right:3rem}
616 | [md~="pr4"]{padding-right:4rem}
617 | [md~="pb0"]{padding-bottom:0}
618 | [md~="pb1"]{padding-bottom:1rem}
619 | [md~="pb2"]{padding-bottom:2rem}
620 | [md~="pb3"]{padding-bottom:3rem}
621 | [md~="pb4"]{padding-bottom:4rem}
622 | [md~="pl0"]{padding-left:0}
623 | [md~="pl1"]{padding-left:1rem}
624 | [md~="pl2"]{padding-left:2rem}
625 | [md~="pl3"]{padding-left:3rem}
626 | [md~="pl4"]{padding-left:4rem}
627 | [md~="px0"]{padding-left:0;padding-right:0}
628 | [md~="px1"]{padding-left:1rem;padding-right:1rem}
629 | [md~="px2"]{padding-left:2rem;padding-right:2rem}
630 | [md~="px3"]{padding-left:3rem;padding-right:3rem}
631 | [md~="px4"]{padding-left:4rem;padding-right:4rem}
632 | [md~="py0"]{padding-top:0;padding-bottom:0}
633 | [md~="py1"]{padding-top:1rem;padding-bottom:1rem}
634 | [md~="py2"]{padding-top:2rem;padding-bottom:2rem}
635 | [md~="py3"]{padding-top:3rem;padding-bottom:3rem}
636 | [md~="py4"]{padding-top:4rem;padding-bottom:4rem}
637 | [md~="op0"]{opacity:0}
638 | [md~="op25"]{opacity:0.25}
639 | [md~="op50"]{opacity:0.5}
640 | [md~="op75"]{opacity:0.75}
641 | [md~="op100"]{opacity:1}
642 | [md~="bgsc"]{background-size:cover}
643 | [md~="bgsct"]{background-size:contain}
644 | [md~="bgpc"]{background-position:center}
645 | [md~="bgpt"]{background-position:top}
646 | [md~="bgpr"]{background-position:right}
647 | [md~="bgpb"]{background-position:bottom}
648 | [md~="bgpl"]{background-position:left}
649 | [md~="bgrn"]{background-repeat:no-repeat}
650 | [md~="bgrx"]{background-repeat:repeat-x}
651 | [md~="bgry"]{background-repeat:repeat-y}
652 | [md~="x"]{display:flex}
653 | [md~="xac"]{align-items:center}
654 | [md~="xab"]{align-items:baseline}
655 | [md~="xas"]{align-items:stretch}
656 | [md~="xafs"]{align-items:flex-start}
657 | [md~="xafe"]{align-items:flex-end}
658 | [md~="xdr"]{flex-direction:row}
659 | [md~="xdrr"]{flex-direction:row-reverse}
660 | [md~="xdc"]{flex-direction:column}
661 | [md~="xdcr"]{flex-direction:column-reverse}
662 | [md~="xjc"]{justify-content:center}
663 | [md~="xjb"]{justify-content:space-between}
664 | [md~="xja"]{justify-content:space-around}
665 | [md~="xjs"]{justify-content:flex-start}
666 | [md~="xje"]{justify-content:flex-end}
667 | [md~="xw"]{flex-wrap:wrap}
668 | [md~="xwr"]{flex-wrap:wrap-reverse}
669 | [md~="xwn"]{flex-wrap:nowrap}
670 | [md~="xi"]{flex:initial}
671 | [md~="xx"]{flex:1}
672 | [md~="xa"]{flex:auto}
673 | [md~="xn"]{flex:none}
674 | [md~="xo0"]{order:0}
675 | [md~="xo1"]{order:1}
676 | [md~="xo2"]{order:2}
677 | [md~="xo3"]{order:3}
678 | [md~="xo4"]{order:4}
679 | [md~="xot"]{order:-1}
680 | [md~="xob"]{order:99}
681 | [md~="df"]{display:flex}
682 | [md~="db"]{display:block}
683 | [md~="dib"]{display:inline-block}
684 | [md~="di"]{display:inline}
685 | [md~="dt"]{display:table}
686 | [md~="dtc"]{display:table-cell}
687 | [md~="dtr"]{display:table-row}
688 | [md~="dn"]{display:none}
689 | [md~="fl"]{float:left}
690 | [md~="fr"]{float:right}
691 | [md~="fn"]{float:none}
692 | [md~="cf"]:after{content:"";display:block;clear:both}
693 | [md~="oh"]{overflow:hidden}
694 | [md~="os"]{overflow:scroll}
695 | [md~="ov"]{overflow:visible}
696 | [md~="oxh"]{overflow-x:hidden}
697 | [md~="oxs"]{overflow-x:scroll}
698 | [md~="oxv"]{overflow-x:visible}
699 | [md~="oyh"]{overflow-y:hidden}
700 | [md~="oys"]{overflow-y:scroll}
701 | [md~="oyv"]{overflow-y:visible}
702 | [md~="psa"]{position:absolute}
703 | [md~="psr"]{position:relative}
704 | [md~="psf"]{position:fixed}
705 | [md~="pss"]{position:static}
706 | [md~="t0"]{top:0}
707 | [md~="r0"]{right:0}
708 | [md~="b0"]{bottom:0}
709 | [md~="l0"]{left:0}
710 | [md~="z0"]{z-index:0}
711 | [md~="z1"]{z-index:1}
712 | [md~="z2"]{z-index:2}
713 | [md~="z3"]{z-index:3}
714 | [md~="z4"]{z-index:4}
715 | [md~="w0"]{width:0}
716 | [md~="w100"]{width:100%}
717 | [md~="h0"]{height:0}
718 | [md~="h100"]{height:100%}
719 | [md~="vw50"]{width:50vw}
720 | [md~="vw100"]{width:100vw}
721 | [md~="vwmn50"]{min-width:50vw}
722 | [md~="vwmn100"]{min-width:100vw}
723 | [md~="vwmx50"]{max-width:50vw}
724 | [md~="vwmx100"]{max-width:100vw}
725 | [md~="vh50"]{height:50vh}
726 | [md~="vh100"]{height:100vh}
727 | [md~="vhmn50"]{min-height:50vh}
728 | [md~="vhmn100"]{min-height:100vh}
729 | [md~="vhmx50"]{max-height:50vh}
730 | [md~="vhmx100"]{max-height:100vh}
731 | [md~="ar25"]:before{padding-top:25%;content:"";display:block}
732 | [md~="ar50"]:before{padding-top:50%;content:"";display:block}
733 | [md~="ar75"]:before{padding-top:75%;content:"";display:block}
734 | [md~="ar100"]:before{padding-top:100%;content:"";display:block}
735 | [md~="fs1"]{font-size:1rem}
736 | [md~="fs1-2"]{font-size:1.2rem}
737 | [md~="fs1-6"]{font-size:1.6rem}
738 | [md~="fs2-4"]{font-size:2.4rem}
739 | [md~="fs3-2"]{font-size:3.2rem}
740 | [md~="fs6-4"]{font-size:6.4rem}
741 | [md~="lh1"]{line-height:1}
742 | [md~="lh1-5"]{line-height:1.5}
743 | [md~="fsn"]{font-style:normal}
744 | [md~="fsi"]{font-style:italic}
745 | [md~="fwn"]{font-weight:normal}
746 | [md~="fwb"]{font-weight:bold}
747 | [md~="tal"]{text-align:left}
748 | [md~="tac"]{text-align:center}
749 | [md~="tar"]{text-align:right}
750 | [md~="taj"]{text-align:justify}
751 | [md~="toi"]{text-overflow:initial}
752 | [md~="toc"]{text-overflow:clip}
753 | [md~="toe"]{text-overflow:ellipsis}
754 | [md~="tdu"]{text-decoration:underline}
755 | [md~="tdo"]{text-decoration:overline}
756 | [md~="tdlt"]{text-decoration:line-through}
757 | [md~="tdn"]{text-decoration:none}
758 | [md~="ttu"]{text-transform:uppercase}
759 | [md~="ttl"]{text-transform:lowercase}
760 | [md~="ttc"]{text-transform:capitalize}
761 | [md~="ttn"]{text-transform:none}
762 | [md~="vabl"]{vertical-align:baseline}
763 | [md~="vat"]{vertical-align:top}
764 | [md~="vam"]{vertical-align:middle}
765 | [md~="vab"]{vertical-align:bottom}
766 | [md~="wsn"]{white-space:normal}
767 | [md~="wsnw"]{white-space:nowrap}
768 | [md~="wsp"]{white-space:pre}
769 | [md~="wsi"]{white-space:inherit}
770 | [md~="tc1"]{columns:1}
771 | [md~="tc2"]{columns:2}
772 | [md~="tc3"]{columns:3}
773 | [md~="tc4"]{columns:4}
774 | [md~="curp"]{cursor:pointer}
775 | [md~="curd"]{cursor:default}
776 | [md~="cura"]{cursor:alias}
777 | [md~="curzi"]{cursor:zoom-in}
778 | [md~="curzo"]{cursor:zoom-out}
779 | [md~="usn"]{user-select:none}
780 | [md~="usa"]{user-select:auto}
781 | [md~="ust"]{user-select:text}
782 | [md~="pen"]{pointer-events:none}
783 | [md~="pea"]{pointer-events:auto}
784 | [md~="vh"]{visibility:hidden}
785 | [md~="vv"]{visibility:visible}
786 | [md~="dev"]{outline:1px solid #912eff}
787 | [md~="dev"] > * {outline:1px solid #5497ff}
788 | [md~="dev"] > * > * {outline:1px solid #51feff}
789 | [md~="dev"] > * > * > * {outline:1px solid #ff0000}
790 | [md~="dev"] > * > * > * * {outline:1px solid #00ff00}
791 | }
792 | @media (min-width:1280px) {
793 | [lg~="c1"]{width:8.33333%}
794 | [lg~="c2"]{width:16.66667%}
795 | [lg~="c3"]{width:25%}
796 | [lg~="c4"]{width:33.33333%}
797 | [lg~="c5"]{width:41.66667%}
798 | [lg~="c6"]{width:50%}
799 | [lg~="c7"]{width:58.33333%}
800 | [lg~="c8"]{width:66.66667%}
801 | [lg~="c9"]{width:75%}
802 | [lg~="c10"]{width:83.33333%}
803 | [lg~="c11"]{width:91.66667%}
804 | [lg~="c12"]{width:100%}
805 | [lg~="s1"]{width:100%}
806 | [lg~="s2"]{width:50%}
807 | [lg~="s3"]{width:33.33333%}
808 | [lg~="s4"]{width:25%}
809 | [lg~="s5"]{width:20%}
810 | [lg~="s6"]{width:16.66667%}
811 | [lg~="s7"]{width:14.28571%}
812 | [lg~="s8"]{width:12.5%}
813 | [lg~="s9"]{width:11.11111%}
814 | [lg~="s10"]{width:10%}
815 | [lg~="s11"]{width:9.09091%}
816 | [lg~="s12"]{width:8.33333%}
817 | [lg~="co0"]{margin-left:0}
818 | [lg~="co1"]{margin-left:8.33333%}
819 | [lg~="co2"]{margin-left:16.66667%}
820 | [lg~="co3"]{margin-left:25%}
821 | [lg~="co4"]{margin-left:33.33333%}
822 | [lg~="co5"]{margin-left:41.66667%}
823 | [lg~="co6"]{margin-left:50%}
824 | [lg~="co7"]{margin-left:58.33333%}
825 | [lg~="co8"]{margin-left:66.66667%}
826 | [lg~="co9"]{margin-left:75%}
827 | [lg~="co10"]{margin-left:83.33333%}
828 | [lg~="co11"]{margin-left:91.66667%}
829 | [lg~="co12"]{margin-left:100%}
830 | [lg~="m0"]{margin:0}
831 | [lg~="m1"]{margin:1rem}
832 | [lg~="m2"]{margin:2rem}
833 | [lg~="m3"]{margin:3rem}
834 | [lg~="m4"]{margin:4rem}
835 | [lg~="mt0"]{margin-top:0}
836 | [lg~="mt1"]{margin-top:1rem}
837 | [lg~="mt2"]{margin-top:2rem}
838 | [lg~="mt3"]{margin-top:3rem}
839 | [lg~="mt4"]{margin-top:4rem}
840 | [lg~="mr0"]{margin-right:0}
841 | [lg~="mr1"]{margin-right:1rem}
842 | [lg~="mr2"]{margin-right:2rem}
843 | [lg~="mr3"]{margin-right:3rem}
844 | [lg~="mr4"]{margin-right:4rem}
845 | [lg~="mb0"]{margin-bottom:0}
846 | [lg~="mb1"]{margin-bottom:1rem}
847 | [lg~="mb2"]{margin-bottom:2rem}
848 | [lg~="mb3"]{margin-bottom:3rem}
849 | [lg~="mb4"]{margin-bottom:4rem}
850 | [lg~="ml0"]{margin-left:0}
851 | [lg~="ml1"]{margin-left:1rem}
852 | [lg~="ml2"]{margin-left:2rem}
853 | [lg~="ml3"]{margin-left:3rem}
854 | [lg~="ml4"]{margin-left:4rem}
855 | [lg~="mx0"]{margin-left:0;margin-right:0}
856 | [lg~="mx1"]{margin-left:1rem;margin-right:1rem}
857 | [lg~="mx2"]{margin-left:2rem;margin-right:2rem}
858 | [lg~="mx3"]{margin-left:3rem;margin-right:3rem}
859 | [lg~="mx4"]{margin-left:4rem;margin-right:4rem}
860 | [lg~="my0"]{margin-top:0;margin-bottom:0}
861 | [lg~="my1"]{margin-top:1rem;margin-bottom:1rem}
862 | [lg~="my2"]{margin-top:2rem;margin-bottom:2rem}
863 | [lg~="my3"]{margin-top:3rem;margin-bottom:3rem}
864 | [lg~="my4"]{margin-top:4rem;margin-bottom:4rem}
865 | [lg~="p0"]{padding:0}
866 | [lg~="p1"]{padding:1rem}
867 | [lg~="p2"]{padding:2rem}
868 | [lg~="p3"]{padding:3rem}
869 | [lg~="p4"]{padding:4rem}
870 | [lg~="pt0"]{padding-top:0}
871 | [lg~="pt1"]{padding-top:1rem}
872 | [lg~="pt2"]{padding-top:2rem}
873 | [lg~="pt3"]{padding-top:3rem}
874 | [lg~="pt4"]{padding-top:4rem}
875 | [lg~="pr0"]{padding-right:0}
876 | [lg~="pr1"]{padding-right:1rem}
877 | [lg~="pr2"]{padding-right:2rem}
878 | [lg~="pr3"]{padding-right:3rem}
879 | [lg~="pr4"]{padding-right:4rem}
880 | [lg~="pb0"]{padding-bottom:0}
881 | [lg~="pb1"]{padding-bottom:1rem}
882 | [lg~="pb2"]{padding-bottom:2rem}
883 | [lg~="pb3"]{padding-bottom:3rem}
884 | [lg~="pb4"]{padding-bottom:4rem}
885 | [lg~="pl0"]{padding-left:0}
886 | [lg~="pl1"]{padding-left:1rem}
887 | [lg~="pl2"]{padding-left:2rem}
888 | [lg~="pl3"]{padding-left:3rem}
889 | [lg~="pl4"]{padding-left:4rem}
890 | [lg~="px0"]{padding-left:0;padding-right:0}
891 | [lg~="px1"]{padding-left:1rem;padding-right:1rem}
892 | [lg~="px2"]{padding-left:2rem;padding-right:2rem}
893 | [lg~="px3"]{padding-left:3rem;padding-right:3rem}
894 | [lg~="px4"]{padding-left:4rem;padding-right:4rem}
895 | [lg~="py0"]{padding-top:0;padding-bottom:0}
896 | [lg~="py1"]{padding-top:1rem;padding-bottom:1rem}
897 | [lg~="py2"]{padding-top:2rem;padding-bottom:2rem}
898 | [lg~="py3"]{padding-top:3rem;padding-bottom:3rem}
899 | [lg~="py4"]{padding-top:4rem;padding-bottom:4rem}
900 | [lg~="op0"]{opacity:0}
901 | [lg~="op25"]{opacity:0.25}
902 | [lg~="op50"]{opacity:0.5}
903 | [lg~="op75"]{opacity:0.75}
904 | [lg~="op100"]{opacity:1}
905 | [lg~="bgsc"]{background-size:cover}
906 | [lg~="bgsct"]{background-size:contain}
907 | [lg~="bgpc"]{background-position:center}
908 | [lg~="bgpt"]{background-position:top}
909 | [lg~="bgpr"]{background-position:right}
910 | [lg~="bgpb"]{background-position:bottom}
911 | [lg~="bgpl"]{background-position:left}
912 | [lg~="bgrn"]{background-repeat:no-repeat}
913 | [lg~="bgrx"]{background-repeat:repeat-x}
914 | [lg~="bgry"]{background-repeat:repeat-y}
915 | [lg~="x"]{display:flex}
916 | [lg~="xac"]{align-items:center}
917 | [lg~="xab"]{align-items:baseline}
918 | [lg~="xas"]{align-items:stretch}
919 | [lg~="xafs"]{align-items:flex-start}
920 | [lg~="xafe"]{align-items:flex-end}
921 | [lg~="xdr"]{flex-direction:row}
922 | [lg~="xdrr"]{flex-direction:row-reverse}
923 | [lg~="xdc"]{flex-direction:column}
924 | [lg~="xdcr"]{flex-direction:column-reverse}
925 | [lg~="xjc"]{justify-content:center}
926 | [lg~="xjb"]{justify-content:space-between}
927 | [lg~="xja"]{justify-content:space-around}
928 | [lg~="xjs"]{justify-content:flex-start}
929 | [lg~="xje"]{justify-content:flex-end}
930 | [lg~="xw"]{flex-wrap:wrap}
931 | [lg~="xwr"]{flex-wrap:wrap-reverse}
932 | [lg~="xwn"]{flex-wrap:nowrap}
933 | [lg~="xi"]{flex:initial}
934 | [lg~="xx"]{flex:1}
935 | [lg~="xa"]{flex:auto}
936 | [lg~="xn"]{flex:none}
937 | [lg~="xo0"]{order:0}
938 | [lg~="xo1"]{order:1}
939 | [lg~="xo2"]{order:2}
940 | [lg~="xo3"]{order:3}
941 | [lg~="xo4"]{order:4}
942 | [lg~="xot"]{order:-1}
943 | [lg~="xob"]{order:99}
944 | [lg~="df"]{display:flex}
945 | [lg~="db"]{display:block}
946 | [lg~="dib"]{display:inline-block}
947 | [lg~="di"]{display:inline}
948 | [lg~="dt"]{display:table}
949 | [lg~="dtc"]{display:table-cell}
950 | [lg~="dtr"]{display:table-row}
951 | [lg~="dn"]{display:none}
952 | [lg~="fl"]{float:left}
953 | [lg~="fr"]{float:right}
954 | [lg~="fn"]{float:none}
955 | [lg~="cf"]:after{content:"";display:block;clear:both}
956 | [lg~="oh"]{overflow:hidden}
957 | [lg~="os"]{overflow:scroll}
958 | [lg~="ov"]{overflow:visible}
959 | [lg~="oxh"]{overflow-x:hidden}
960 | [lg~="oxs"]{overflow-x:scroll}
961 | [lg~="oxv"]{overflow-x:visible}
962 | [lg~="oyh"]{overflow-y:hidden}
963 | [lg~="oys"]{overflow-y:scroll}
964 | [lg~="oyv"]{overflow-y:visible}
965 | [lg~="psa"]{position:absolute}
966 | [lg~="psr"]{position:relative}
967 | [lg~="psf"]{position:fixed}
968 | [lg~="pss"]{position:static}
969 | [lg~="t0"]{top:0}
970 | [lg~="r0"]{right:0}
971 | [lg~="b0"]{bottom:0}
972 | [lg~="l0"]{left:0}
973 | [lg~="z0"]{z-index:0}
974 | [lg~="z1"]{z-index:1}
975 | [lg~="z2"]{z-index:2}
976 | [lg~="z3"]{z-index:3}
977 | [lg~="z4"]{z-index:4}
978 | [lg~="w0"]{width:0}
979 | [lg~="w100"]{width:100%}
980 | [lg~="h0"]{height:0}
981 | [lg~="h100"]{height:100%}
982 | [lg~="vw50"]{width:50vw}
983 | [lg~="vw100"]{width:100vw}
984 | [lg~="vwmn50"]{min-width:50vw}
985 | [lg~="vwmn100"]{min-width:100vw}
986 | [lg~="vwmx50"]{max-width:50vw}
987 | [lg~="vwmx100"]{max-width:100vw}
988 | [lg~="vh50"]{height:50vh}
989 | [lg~="vh100"]{height:100vh}
990 | [lg~="vhmn50"]{min-height:50vh}
991 | [lg~="vhmn100"]{min-height:100vh}
992 | [lg~="vhmx50"]{max-height:50vh}
993 | [lg~="vhmx100"]{max-height:100vh}
994 | [lg~="ar25"]:before{padding-top:25%;content:"";display:block}
995 | [lg~="ar50"]:before{padding-top:50%;content:"";display:block}
996 | [lg~="ar75"]:before{padding-top:75%;content:"";display:block}
997 | [lg~="ar100"]:before{padding-top:100%;content:"";display:block}
998 | [lg~="fs1"]{font-size:1rem}
999 | [lg~="fs1-2"]{font-size:1.2rem}
1000 | [lg~="fs1-6"]{font-size:1.6rem}
1001 | [lg~="fs2-4"]{font-size:2.4rem}
1002 | [lg~="fs3-2"]{font-size:3.2rem}
1003 | [lg~="fs6-4"]{font-size:6.4rem}
1004 | [lg~="lh1"]{line-height:1}
1005 | [lg~="lh1-5"]{line-height:1.5}
1006 | [lg~="fsn"]{font-style:normal}
1007 | [lg~="fsi"]{font-style:italic}
1008 | [lg~="fwn"]{font-weight:normal}
1009 | [lg~="fwb"]{font-weight:bold}
1010 | [lg~="tal"]{text-align:left}
1011 | [lg~="tac"]{text-align:center}
1012 | [lg~="tar"]{text-align:right}
1013 | [lg~="taj"]{text-align:justify}
1014 | [lg~="toi"]{text-overflow:initial}
1015 | [lg~="toc"]{text-overflow:clip}
1016 | [lg~="toe"]{text-overflow:ellipsis}
1017 | [lg~="tdu"]{text-decoration:underline}
1018 | [lg~="tdo"]{text-decoration:overline}
1019 | [lg~="tdlt"]{text-decoration:line-through}
1020 | [lg~="tdn"]{text-decoration:none}
1021 | [lg~="ttu"]{text-transform:uppercase}
1022 | [lg~="ttl"]{text-transform:lowercase}
1023 | [lg~="ttc"]{text-transform:capitalize}
1024 | [lg~="ttn"]{text-transform:none}
1025 | [lg~="vabl"]{vertical-align:baseline}
1026 | [lg~="vat"]{vertical-align:top}
1027 | [lg~="vam"]{vertical-align:middle}
1028 | [lg~="vab"]{vertical-align:bottom}
1029 | [lg~="wsn"]{white-space:normal}
1030 | [lg~="wsnw"]{white-space:nowrap}
1031 | [lg~="wsp"]{white-space:pre}
1032 | [lg~="wsi"]{white-space:inherit}
1033 | [lg~="tc1"]{columns:1}
1034 | [lg~="tc2"]{columns:2}
1035 | [lg~="tc3"]{columns:3}
1036 | [lg~="tc4"]{columns:4}
1037 | [lg~="curp"]{cursor:pointer}
1038 | [lg~="curd"]{cursor:default}
1039 | [lg~="cura"]{cursor:alias}
1040 | [lg~="curzi"]{cursor:zoom-in}
1041 | [lg~="curzo"]{cursor:zoom-out}
1042 | [lg~="usn"]{user-select:none}
1043 | [lg~="usa"]{user-select:auto}
1044 | [lg~="ust"]{user-select:text}
1045 | [lg~="pen"]{pointer-events:none}
1046 | [lg~="pea"]{pointer-events:auto}
1047 | [lg~="vh"]{visibility:hidden}
1048 | [lg~="vv"]{visibility:visible}
1049 | [lg~="dev"]{outline:1px solid #912eff}
1050 | [lg~="dev"] > * {outline:1px solid #5497ff}
1051 | [lg~="dev"] > * > * {outline:1px solid #51feff}
1052 | [lg~="dev"] > * > * > * {outline:1px solid #ff0000}
1053 | [lg~="dev"] > * > * > * * {outline:1px solid #00ff00}
1054 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var x = require('xtend')
2 | var gr8util = require('gr8-util')
3 | var gr8utils = require('./utils')
4 |
5 | module.exports = gr8
6 |
7 | var defaults = {
8 | breakpoints: {
9 | sm: 768,
10 | md: 1024,
11 | lg: 1280
12 | },
13 | breakpointSelector: 'attribute',
14 | utils: [],
15 | exclude: []
16 | }
17 |
18 | function gr8 (options) {
19 | options = x(defaults, options)
20 |
21 | var cssString = ''
22 |
23 | cssString += defaultUtils(options)
24 | cssString += customUtils(options.utils)
25 |
26 | Object.keys(options.breakpoints).forEach(function (key) {
27 | var selector = breakpointSelectorShortcut(options.breakpointSelector)(key)
28 | cssString += `\n@media ${breakpointShortcut(options.breakpoints[key])} {\n`
29 | cssString += defaultUtils(options, { selector: selector })
30 | cssString += customUtils(options.utils, { selector: selector })
31 | cssString += '\n}'
32 | })
33 |
34 | return cssString
35 | }
36 |
37 | function defaultUtils (defaults, options) {
38 | options = options || {}
39 | return gr8utils(x(defaults, options))
40 | }
41 |
42 | function customUtils (utils, options) {
43 | options = options || {}
44 | return utils.map(function (util) {
45 | return gr8util(x(util, options))
46 | }).join('\n')
47 | }
48 |
49 | function breakpointShortcut (value) {
50 | return Number.isInteger(value)
51 | ? `(min-width:${value}px)`
52 | : value
53 | }
54 |
55 | function breakpointSelectorShortcut (selector) {
56 | return selector === 'attribute'
57 | ? key => s => `[${key}~="${s}"]`
58 | : selector === 'class'
59 | ? key => s => `.${key}-${s}`
60 | : selector
61 | }
62 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gr8",
3 | "version": "3.1.5",
4 | "description": "Functional css utilities",
5 | "main": "index.js",
6 | "style": "dist/gr8.css",
7 | "devDependencies": {
8 | "colortape": "^0.1.2",
9 | "onchange": "^6.0.0",
10 | "standard": "^11.0.0",
11 | "tape": "^5.0.0"
12 | },
13 | "scripts": {
14 | "test": "standard --fix && node test.js | colortape",
15 | "build-css": "node bin/dist.js",
16 | "build-readme": "node bin/readme/index.js",
17 | "watch-readme": "onchange 'bin/readme/' -- npm run build-readme",
18 | "dist": "npm run test && npm run build-css && npm run build-readme"
19 | },
20 | "standard": {
21 | "ignore": [
22 | "postcss.js"
23 | ]
24 | },
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/jongacnik/gr8.git"
28 | },
29 | "keywords": [
30 | "functional",
31 | "css",
32 | "utilities"
33 | ],
34 | "author": "Jon Gacnik (http://jongacnik.com)",
35 | "license": "MIT",
36 | "homepage": "https://github.com/jongacnik/gr8#readme",
37 | "dependencies": {
38 | "gr8-util": "^1.3.0",
39 | "object-values": "^2.0.0",
40 | "xtend": "^4.0.1"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | gr8
2 |
3 |
14 |
15 |
16 |
17 | Customizable, functional css utilities built using [**gr8-util**](https://github.com/jongacnik/gr8-util). Includes:
18 |
19 | - [**css stylesheet**](#stylesheet-usage) with default utilities
20 | - [**`gr8` function**](#javascript-usage) to generate and customize utilities within javascript
21 |
22 | ## Usage
23 |
24 | ### stylesheet usage
25 |
26 | The simplest way to use `gr8` is to include the [gr8.css](https://github.com/jongacnik/gr8/blob/master/dist/gr8.css) stylesheet in your project:
27 |
28 | ```html
29 |
30 | ```
31 |
32 | ### javascript usage
33 |
34 | Use the `gr8` function to generate utilities:
35 |
36 | ```js
37 | var gr8 = require('gr8')
38 | var css = gr8()
39 | ```
40 |
41 | [Detailed usage →](#api)
42 |
43 | ## Utilities
44 |
45 | Default utilities:
46 |
47 |
48 | column
49 |
50 | ```css
51 | .c1{width:8.33333%}
52 | .c2{width:16.66667%}
53 | .c3{width:25%}
54 | .c4{width:33.33333%}
55 | .c5{width:41.66667%}
56 | .c6{width:50%}
57 | .c7{width:58.33333%}
58 | .c8{width:66.66667%}
59 | .c9{width:75%}
60 | .c10{width:83.33333%}
61 | .c11{width:91.66667%}
62 | .c12{width:100%}
63 | .s1{width:100%}
64 | .s2{width:50%}
65 | .s3{width:33.33333%}
66 | .s4{width:25%}
67 | .s5{width:20%}
68 | .s6{width:16.66667%}
69 | .s7{width:14.28571%}
70 | .s8{width:12.5%}
71 | .s9{width:11.11111%}
72 | .s10{width:10%}
73 | .s11{width:9.09091%}
74 | .s12{width:8.33333%}
75 | .co0{margin-left:0}
76 | .co1{margin-left:8.33333%}
77 | .co2{margin-left:16.66667%}
78 | .co3{margin-left:25%}
79 | .co4{margin-left:33.33333%}
80 | .co5{margin-left:41.66667%}
81 | .co6{margin-left:50%}
82 | .co7{margin-left:58.33333%}
83 | .co8{margin-left:66.66667%}
84 | .co9{margin-left:75%}
85 | .co10{margin-left:83.33333%}
86 | .co11{margin-left:91.66667%}
87 | .co12{margin-left:100%}
88 | ```
89 |
90 |
91 |
92 |
93 | margin
94 |
95 | ```css
96 | .m0{margin:0}
97 | .m1{margin:1rem}
98 | .m2{margin:2rem}
99 | .m3{margin:3rem}
100 | .m4{margin:4rem}
101 | .mt0{margin-top:0}
102 | .mt1{margin-top:1rem}
103 | .mt2{margin-top:2rem}
104 | .mt3{margin-top:3rem}
105 | .mt4{margin-top:4rem}
106 | .mr0{margin-right:0}
107 | .mr1{margin-right:1rem}
108 | .mr2{margin-right:2rem}
109 | .mr3{margin-right:3rem}
110 | .mr4{margin-right:4rem}
111 | .mb0{margin-bottom:0}
112 | .mb1{margin-bottom:1rem}
113 | .mb2{margin-bottom:2rem}
114 | .mb3{margin-bottom:3rem}
115 | .mb4{margin-bottom:4rem}
116 | .ml0{margin-left:0}
117 | .ml1{margin-left:1rem}
118 | .ml2{margin-left:2rem}
119 | .ml3{margin-left:3rem}
120 | .ml4{margin-left:4rem}
121 | .mx0{margin-left:0;margin-right:0}
122 | .mx1{margin-left:1rem;margin-right:1rem}
123 | .mx2{margin-left:2rem;margin-right:2rem}
124 | .mx3{margin-left:3rem;margin-right:3rem}
125 | .mx4{margin-left:4rem;margin-right:4rem}
126 | .my0{margin-top:0;margin-bottom:0}
127 | .my1{margin-top:1rem;margin-bottom:1rem}
128 | .my2{margin-top:2rem;margin-bottom:2rem}
129 | .my3{margin-top:3rem;margin-bottom:3rem}
130 | .my4{margin-top:4rem;margin-bottom:4rem}
131 | ```
132 |
133 |
134 |
135 |
136 | padding
137 |
138 | ```css
139 | .p0{padding:0}
140 | .p1{padding:1rem}
141 | .p2{padding:2rem}
142 | .p3{padding:3rem}
143 | .p4{padding:4rem}
144 | .pt0{padding-top:0}
145 | .pt1{padding-top:1rem}
146 | .pt2{padding-top:2rem}
147 | .pt3{padding-top:3rem}
148 | .pt4{padding-top:4rem}
149 | .pr0{padding-right:0}
150 | .pr1{padding-right:1rem}
151 | .pr2{padding-right:2rem}
152 | .pr3{padding-right:3rem}
153 | .pr4{padding-right:4rem}
154 | .pb0{padding-bottom:0}
155 | .pb1{padding-bottom:1rem}
156 | .pb2{padding-bottom:2rem}
157 | .pb3{padding-bottom:3rem}
158 | .pb4{padding-bottom:4rem}
159 | .pl0{padding-left:0}
160 | .pl1{padding-left:1rem}
161 | .pl2{padding-left:2rem}
162 | .pl3{padding-left:3rem}
163 | .pl4{padding-left:4rem}
164 | .px0{padding-left:0;padding-right:0}
165 | .px1{padding-left:1rem;padding-right:1rem}
166 | .px2{padding-left:2rem;padding-right:2rem}
167 | .px3{padding-left:3rem;padding-right:3rem}
168 | .px4{padding-left:4rem;padding-right:4rem}
169 | .py0{padding-top:0;padding-bottom:0}
170 | .py1{padding-top:1rem;padding-bottom:1rem}
171 | .py2{padding-top:2rem;padding-bottom:2rem}
172 | .py3{padding-top:3rem;padding-bottom:3rem}
173 | .py4{padding-top:4rem;padding-bottom:4rem}
174 | ```
175 |
176 |
177 |
178 |
179 | opacity
180 |
181 | ```css
182 | .op0{opacity:0}
183 | .op25{opacity:0.25}
184 | .op50{opacity:0.5}
185 | .op75{opacity:0.75}
186 | .op100{opacity:1}
187 | ```
188 |
189 |
190 |
191 |
192 | background
193 |
194 | ```css
195 | .bgsc{background-size:cover}
196 | .bgsct{background-size:contain}
197 | .bgpc{background-position:center}
198 | .bgpt{background-position:top}
199 | .bgpr{background-position:right}
200 | .bgpb{background-position:bottom}
201 | .bgpl{background-position:left}
202 | .bgrn{background-repeat:no-repeat}
203 | .bgrx{background-repeat:repeat-x}
204 | .bgry{background-repeat:repeat-y}
205 | ```
206 |
207 |
208 |
209 |
210 | flex
211 |
212 | ```css
213 | .x{display:flex}
214 | .xac{align-items:center}
215 | .xab{align-items:baseline}
216 | .xas{align-items:stretch}
217 | .xafs{align-items:flex-start}
218 | .xafe{align-items:flex-end}
219 | .xdr{flex-direction:row}
220 | .xdrr{flex-direction:row-reverse}
221 | .xdc{flex-direction:column}
222 | .xdcr{flex-direction:column-reverse}
223 | .xjc{justify-content:center}
224 | .xjb{justify-content:space-between}
225 | .xja{justify-content:space-around}
226 | .xjs{justify-content:flex-start}
227 | .xje{justify-content:flex-end}
228 | .xw{flex-wrap:wrap}
229 | .xwr{flex-wrap:wrap-reverse}
230 | .xwn{flex-wrap:nowrap}
231 | .xi{flex:initial}
232 | .xx{flex:1}
233 | .xa{flex:auto}
234 | .xn{flex:none}
235 | .xo0{order:0}
236 | .xo1{order:1}
237 | .xo2{order:2}
238 | .xo3{order:3}
239 | .xo4{order:4}
240 | .xot{order:-1}
241 | .xob{order:99}
242 | ```
243 |
244 |
245 |
246 |
247 | display
248 |
249 | ```css
250 | .df{display:flex}
251 | .db{display:block}
252 | .dib{display:inline-block}
253 | .di{display:inline}
254 | .dt{display:table}
255 | .dtc{display:table-cell}
256 | .dtr{display:table-row}
257 | .dn{display:none}
258 | ```
259 |
260 |
261 |
262 |
263 | float
264 |
265 | ```css
266 | .fl{float:left}
267 | .fr{float:right}
268 | .fn{float:none}
269 | .cf:after{content:"";display:block;clear:both}
270 | ```
271 |
272 |
273 |
274 |
275 | overflow
276 |
277 | ```css
278 | .oh{overflow:hidden}
279 | .os{overflow:scroll}
280 | .ov{overflow:visible}
281 | .oxh{overflow-x:hidden}
282 | .oxs{overflow-x:scroll}
283 | .oxv{overflow-x:visible}
284 | .oyh{overflow-y:hidden}
285 | .oys{overflow-y:scroll}
286 | .oyv{overflow-y:visible}
287 | ```
288 |
289 |
290 |
291 |
292 | positioning
293 |
294 | ```css
295 | .psa{position:absolute}
296 | .psr{position:relative}
297 | .psf{position:fixed}
298 | .pss{position:static}
299 | .t0{top:0}
300 | .r0{right:0}
301 | .b0{bottom:0}
302 | .l0{left:0}
303 | .z0{z-index:0}
304 | .z1{z-index:1}
305 | .z2{z-index:2}
306 | .z3{z-index:3}
307 | .z4{z-index:4}
308 | ```
309 |
310 |
311 |
312 |
313 | size
314 |
315 | ```css
316 | .w0{width:0}
317 | .w100{width:100%}
318 | .h0{height:0}
319 | .h100{height:100%}
320 | .vw50{width:50vw}
321 | .vw100{width:100vw}
322 | .vwmn50{min-width:50vw}
323 | .vwmn100{min-width:100vw}
324 | .vwmx50{max-width:50vw}
325 | .vwmx100{max-width:100vw}
326 | .vh50{height:50vh}
327 | .vh100{height:100vh}
328 | .vhmn50{min-height:50vh}
329 | .vhmn100{min-height:100vh}
330 | .vhmx50{max-height:50vh}
331 | .vhmx100{max-height:100vh}
332 | .ar25:before{padding-top:25%;content:"";display:block}
333 | .ar50:before{padding-top:50%;content:"";display:block}
334 | .ar75:before{padding-top:75%;content:"";display:block}
335 | .ar100:before{padding-top:100%;content:"";display:block}
336 | ```
337 |
338 |
339 |
340 |
341 | typography
342 |
343 | ```css
344 | .fs1{font-size:1rem}
345 | .fs1-2{font-size:1.2rem}
346 | .fs1-6{font-size:1.6rem}
347 | .fs2-4{font-size:2.4rem}
348 | .fs3-2{font-size:3.2rem}
349 | .fs6-4{font-size:6.4rem}
350 | .lh1{line-height:1}
351 | .lh1-5{line-height:1.5}
352 | .fsn{font-style:normal}
353 | .fsi{font-style:italic}
354 | .fwn{font-weight:normal}
355 | .fwb{font-weight:bold}
356 | .tal{text-align:left}
357 | .tac{text-align:center}
358 | .tar{text-align:right}
359 | .taj{text-align:justify}
360 | .toi{text-overflow:initial}
361 | .toc{text-overflow:clip}
362 | .toe{text-overflow:ellipsis}
363 | .tdu{text-decoration:underline}
364 | .tdo{text-decoration:overline}
365 | .tdlt{text-decoration:line-through}
366 | .tdn{text-decoration:none}
367 | .ttu{text-transform:uppercase}
368 | .ttl{text-transform:lowercase}
369 | .ttc{text-transform:capitalize}
370 | .ttn{text-transform:none}
371 | .vabl{vertical-align:baseline}
372 | .vat{vertical-align:top}
373 | .vam{vertical-align:middle}
374 | .vab{vertical-align:bottom}
375 | .wsn{white-space:normal}
376 | .wsnw{white-space:nowrap}
377 | .wsp{white-space:pre}
378 | .wsi{white-space:inherit}
379 | .tc1{columns:1}
380 | .tc2{columns:2}
381 | .tc3{columns:3}
382 | .tc4{columns:4}
383 | ```
384 |
385 |
386 |
387 |
388 | miscellaneous
389 |
390 | ```css
391 | .curp{cursor:pointer}
392 | .curd{cursor:default}
393 | .cura{cursor:alias}
394 | .curzi{cursor:zoom-in}
395 | .curzo{cursor:zoom-out}
396 | .usn{user-select:none}
397 | .usa{user-select:auto}
398 | .ust{user-select:text}
399 | .pen{pointer-events:none}
400 | .pea{pointer-events:auto}
401 | .vh{visibility:hidden}
402 | .vv{visibility:visible}
403 | ```
404 |
405 |
406 |
407 |
408 | development
409 |
410 | ```css
411 | .dev{outline:1px solid #912eff}
412 | .dev > * {outline:1px solid #5497ff}
413 | .dev > * > * {outline:1px solid #51feff}
414 | .dev > * > * > * {outline:1px solid #ff0000}
415 | .dev > * > * > * * {outline:1px solid #00ff00}
416 | ```
417 |
418 |
419 |
420 | ## API
421 |
422 | ### `css = gr8([opts])`
423 |
424 | Generate utilities and return a string of css. `opts` accepts the following values:
425 |
426 | #### Value Options
427 |
428 | - `opts.spacing` **[Mixed]** values for [margin](#margin) & [padding](#padding) utilities
429 | - `opts.fontSize` **[Mixed]** values for [font-size](#typography) utilities
430 | - `opts.lineHeight` **[Mixed]** values for [line-height](#typography) utilities
431 | - `opts.size` **[Mixed]** values for [width & height](#size) utilities
432 | - `opts.viewport` **[Mixed]** values for [viewport](#size) utilities
433 | - `opts.zIndex` **[Mixed]** values for [zIndex](#positioning) utilities
434 | - `opts.flexOrder` **[Mixed]** values for [flex-order](#flex) utilities
435 | - `opts.opacity` **[Mixed]** values for [opacity](#opacity) utilities
436 | - `opts.aspectRatio` **[Mixed]** values for [aspect ratio](#size) utilities
437 | - `opts.textColumn` **[Mixed]** values for [text columns](#typography) utilities
438 |
439 | #### Selector Options
440 |
441 | - `opts.selector` **[Function]** css selector template function
442 | - `opts.breakpoints` **[Object]** values for breakpoint utilities
443 | - `opts.breakpointSelector` **[String | Function]** selector shortcut or css selector template function
444 |
445 | #### Custom Utilities Options
446 |
447 | - `opts.utils` **[Array]** custom [gr8-util](https://github.com/jongacnik/gr8-util) utilities
448 | - `opts.exclude` **[Array]** keys of default utilities to exclude
449 |
450 | ## Value Options
451 |
452 | Value options customize numeric `gr8` utilities. They accept Numbers, Strings, Arrays, or Objects. Typically Arrays of Numbers will be used. Refer to [gr8-util](https://github.com/jongacnik/gr8-util) for details on all possible ways to format values.
453 |
454 | **Defaults:**
455 |
456 | ```js
457 | var css = gr8({
458 | spacing: [0, 1, 2, 3, 4],
459 | fontSize: [1, 1.2, 1.6, 2.4, 3.2, 6.4],
460 | lineHeight: [1, 1.5],
461 | size: [0, 100],
462 | viewport: [50, 100],
463 | zIndex: [0, 1, 2, 3, 4],
464 | flexOrder: [0, 1, 2, 3, 4],
465 | opacity: [0, 25, 50, 75, 100],
466 | aspectRatio: [25, 50, 75, 100],
467 | textColumn: [1, 2, 3, 4]
468 | })
469 | ```
470 |
471 | ## Selector Options
472 |
473 | Selector options control selectors & breakpoints.
474 |
475 | **Defaults:**
476 |
477 | ```js
478 | var css = gr8({
479 | selector: s => `.${s}`,
480 | breakpoints: {
481 | sm: 768,
482 | md: 1024,
483 | lg: 1280
484 | },
485 | breakpointSelector: 'attribute'
486 | })
487 | ```
488 |
489 | ### `opts.selector`
490 |
491 | Function expects a selector name as input and returns a css selector string as output. For example, to use an attribute selector instead of classes:
492 |
493 | ```js
494 | var css = gr8({
495 | selector: s => `[gr8~="${s}"]`
496 | })
497 | ```
498 |
499 |
500 | Output
501 |
502 | ```css
503 | [gr8~="fs1"]{font-size:1rem}
504 | [gr8~="fs1-6"]{font-size:1.6rem}
505 | /* etc... */
506 | ```
507 |
508 |
509 |
510 | ### `opts.breakpoints`
511 |
512 | Object keys are used in selector names and object values are used to define the media queries. Object values can either be integers (which results in a `min-width` media queries), or object values can be media query strings. Pass `false` to disable breakpoint utilities entirely:
513 |
514 | ```js
515 | var css = gr8({
516 | breakpoints: {
517 | small: 1024,
518 | medium: '(min-width:768px) and (max-width:1280px)',
519 | 'not-big': '(max-width:1024px)',
520 | portrait: '(orientation:portrait)'
521 | }
522 | })
523 | ```
524 |
525 |
526 | Output
527 |
528 | ```css
529 | @media (min-width:1024px) {
530 | [small~="fs1"]{font-size:1rem}
531 | /* etc... */
532 | }
533 | @media (min-width:768px) and (max-width:1280px) {
534 | [medium~="fs1"]{font-size:1rem}
535 | /* etc... */
536 | }
537 | @media (max-width:1024px) {
538 | [not-big~="fs1"]{font-size:1rem}
539 | /* etc... */
540 | }
541 | @media (orientation:portrait) {
542 | [portrait~="fs1"]{font-size:1rem}
543 | /* etc... */
544 | }
545 | ```
546 |
547 |
548 |
549 | **Note:** If you care about valid attribute selectors, prepend `data-` to your breakpoint keys.
550 |
551 | ### `opts.breakpointSelector`
552 |
553 | By default, attribute selectors are generated for breakpoint utilities (as seen above). Use prefixed classes instead by passing in the `'class'` shortcut, or provide a selector function for more granular control:
554 |
555 | #### `'class'` Shortcut
556 |
557 | ```js
558 | var css = gr8({
559 | breakpointSelector: 'class'
560 | })
561 | ```
562 |
563 |
564 | Output
565 |
566 | ```css
567 | @media (min-width:768px) {
568 | .sm-fs1{font-size:1rem}
569 | /* etc... */
570 | }
571 | @media (min-width:1024px) {
572 | .md-fs1{font-size:1rem}
573 | /* etc... */
574 | }
575 | @media (min-width:1280px) {
576 | .lg-fs1{font-size:1rem}
577 | /* etc... */
578 | }
579 | ```
580 |
581 |
582 |
583 | #### Selector Function
584 |
585 |
586 | ```js
587 | var css = gr8({
588 | breakpointSelector: key => s => `.gr8-${key}-${s}`
589 | })
590 | ```
591 |
592 |
593 | Output
594 |
595 | ```css
596 | @media (min-width:768px) {
597 | .gr8-sm-fs1{font-size:1rem}
598 | /* etc... */
599 | }
600 | @media (min-width:1024px) {
601 | .gr8-md-fs1{font-size:1rem}
602 | /* etc... */
603 | }
604 | @media (min-width:1280px) {
605 | .gr8-lg-fs1{font-size:1rem}
606 | /* etc... */
607 | }
608 | ```
609 |
610 |
611 |
612 | ## Custom Utilities Options
613 |
614 | [gr8-util](https://github.com/jongacnik/gr8-util) is a little function for generating functional css utilities. Given a plain object, concise css utilities are generated. All the utilities in `gr8` are built using this.
615 |
616 | Use the `utils` option to pass an array of `gr8-util` objects to extend the `gr8` output with custom utilities:
617 |
618 | ```js
619 | var bgcolor = {
620 | prop: {
621 | bgc: 'background-color'
622 | },
623 | vals: ['red', 'blue', 'green']
624 | }
625 |
626 | var fontcolor = {
627 | prop: {
628 | fc: 'color'
629 | },
630 | vals: ['red', 'blue', 'green']
631 | }
632 |
633 | var css = gr8({
634 | utils: [
635 | bgcolor,
636 | fontcolor
637 | ]
638 | })
639 | ```
640 |
641 |
642 | Output
643 |
644 | ```css
645 | .bgcr{background-color:red}
646 | .bgcb{background-color:blue}
647 | .bgcg{background-color:green}
648 | .fcr{color:red}
649 | .fcb{color:blue}
650 | .fcg{color:green}
651 | /* etc... */
652 |
653 | @media (min-width:768px) {
654 | [sm~="bgcr"]{background-color:red}
655 | [sm~="bgcb"]{background-color:blue}
656 | [sm~="bgcg"]{background-color:green}
657 | [sm~="fcr"]{color:red}
658 | [sm~="fcb"]{color:blue}
659 | [sm~="fcg"]{color:green}
660 | /* etc... */
661 | }
662 |
663 | @media (min-width:1024px) {
664 | [md~="bgcr"]{background-color:red}
665 | [md~="bgcb"]{background-color:blue}
666 | [md~="bgcg"]{background-color:green}
667 | [md~="fcr"]{color:red}
668 | [md~="fcb"]{color:blue}
669 | [md~="fcg"]{color:green}
670 | /* etc... */
671 | }
672 |
673 | @media (min-width:1280px) {
674 | [lg~="bgcr"]{background-color:red}
675 | [lg~="bgcb"]{background-color:blue}
676 | [lg~="bgcg"]{background-color:green}
677 | [lg~="fcr"]{color:red}
678 | [lg~="fcb"]{color:blue}
679 | [lg~="fcg"]{color:green}
680 | /* etc... */
681 | }
682 | ```
683 |
684 |
685 |
686 | **[Refer to gr8-util for further documentation on generating custom utilities.](https://github.com/jongacnik/gr8-util)**
687 |
688 | ### `opts.exclude`
689 |
690 | Use the `exclude` option to remove some of the default utilities. Accepts an array with any of the following values:
691 |
692 | `column`, `margin`, `padding`, `opacity`, `background`, `flex`, `display`, `float`, `overflow`, `positioning`, `size`, `typography`, `miscellaneous`, `development`
693 |
694 | ## Proxies
695 |
696 | For more advanced use cases, some additional methods are proxied:
697 |
698 | ```js
699 | // direct access to gr8-util
700 | var gr8util = require('gr8/util')
701 | var css = gr8util({options})
702 | ```
703 |
704 | ```js
705 | // direct access to gr8-utils
706 | var gr8utils = require('gr8/utils')
707 | var css = gr8utils({options})
708 |
709 | // or even lower level
710 | gr8utils.generate(gr8utils.utils, gr8utils.defaults)
711 | ```
712 |
713 | ## Notes
714 |
715 | `gr8` is developed and iterated-on primarily for use within projects at [Folder Studio](http://folderstudio.com). It shares similarities with other functional css libraries like [tachyons](https://github.com/tachyons-css/tachyons) or [basscss](https://github.com/basscss/basscss), but diverges in its minimalism and customizability. `gr8` provides no colors, no borders, no font-families, etc out of the box, but instead provides ways to quickly define your own utilities for things like these using plain objects. It facilitates creating coherent design systems without imposing one by default.
716 |
717 | In any case, I hope you like it and perhaps find it useful!
718 |
719 | ## Todo
720 |
721 | - [ ] Advanced documentation
722 | - [ ] Website
723 |
724 | ## See Also
725 |
726 | - [gr8-util](https://github.com/jongacnik/gr8-util)
727 |
728 | ## License
729 |
730 | [MIT](https://github.com/jongacnik/gr8/blob/master/LICENSE)
731 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | var test = require('tape')
2 | var gr8 = require('.')
3 |
4 | test('output', function (t) {
5 | t.ok(typeof gr8() === 'string', 'outputs string')
6 | t.end()
7 | })
8 |
9 | test('selector', function (t) {
10 | var css = gr8({
11 | selector: s => `.gr8-${s}`
12 | })
13 | t.ok(css.indexOf('.gr8-') >= 0, 'supports custom selector')
14 | t.end()
15 | })
16 |
17 | test('disable breakpoints', function (t) {
18 | var css = gr8({
19 | breakpoints: false
20 | })
21 | t.ok(css.indexOf('@media') < 0, 'supports disabling breakpoints')
22 | t.end()
23 | })
24 |
25 | test('breakpoint selector', function (t) {
26 | var cssA = gr8({
27 | breakpointSelector: 'attribute'
28 | })
29 | t.ok(cssA.indexOf('[sm~=') >= 0, 'supports attribute breakpoint selector shortcut')
30 |
31 | var cssB = gr8({
32 | breakpointSelector: 'class'
33 | })
34 | t.ok(cssB.indexOf('.sm-') >= 0, 'supports class breakpoint selector shortcut')
35 |
36 | var cssC = gr8({
37 | breakpointSelector: key => s => `.gr8 [${key}~="${s}"]`
38 | })
39 | t.ok(cssC.indexOf('.gr8 [sm~=') >= 0, 'supports custom breakpoint selector')
40 |
41 | t.end()
42 | })
43 |
44 | test('custom breakpoints', function (t) {
45 | var css = gr8({
46 | breakpoints: {
47 | a: '(max-width:768px)',
48 | b: 1024,
49 | c: '(orientation:landscape)'
50 | }
51 | })
52 |
53 | t.ok(css.indexOf('@media (max-width:768px)') >= 0, 'supports custom breakpoints A')
54 | t.ok(css.indexOf('@media (min-width:1024px)') >= 0, 'supports custom breakpoints B')
55 | t.ok(css.indexOf('@media (orientation:landscape)') >= 0, 'supports custom breakpoints C')
56 |
57 | t.end()
58 | })
59 |
60 | test('unit', function (t) {
61 | var css = gr8({
62 | unit: 'px'
63 | })
64 |
65 | t.ok(css.indexOf('.fs6-4{font-size:6.4px}') >= 0, 'supports unit option')
66 | t.end()
67 | })
68 |
69 | test('values', function (t) {
70 | var css = gr8({
71 | spacing: [99],
72 | fontSize: [99],
73 | lineHeight: [99],
74 | size: [99],
75 | viewport: [99],
76 | zIndex: [99],
77 | flexOrder: [99],
78 | opacity: [99],
79 | aspectRatio: [99],
80 | textColumn: [99]
81 | })
82 |
83 | var hasAll = css.indexOf('.p99') >= 0 &&
84 | css.indexOf('.fs99') >= 0 &&
85 | css.indexOf('.lh99') >= 0 &&
86 | css.indexOf('.w99') >= 0 &&
87 | css.indexOf('.vw99') >= 0 &&
88 | css.indexOf('.z99') >= 0 &&
89 | css.indexOf('.xo99') >= 0 &&
90 | css.indexOf('.op99') >= 0 &&
91 | css.indexOf('.ar99') >= 0 &&
92 | css.indexOf('.tc99') >= 0
93 |
94 | t.ok(hasAll, 'custom values succesfully passed to gr8-util')
95 | t.end()
96 | })
97 |
98 | test('custom util', function (t) {
99 | var css = gr8({
100 | utils: [
101 | {
102 | prop: 'foo',
103 | vals: 'bar'
104 | }
105 | ]
106 | })
107 |
108 | t.ok(css.indexOf('.fb{foo:bar}') >= 0, 'custom utils succesfully generated')
109 | t.ok(css.indexOf('[sm~="fb"]{foo:bar}') >= 0, 'custom utils succesfully generated per breakpoint')
110 |
111 | t.end()
112 | })
113 |
114 | test('custom raw util', function (t) {
115 | var css = gr8({
116 | utils: [
117 | {
118 | raw: {
119 | 'trans-center-x': 'left:50%;transform:translateX(-50%)',
120 | 'trans-center-y': 'top:50%;transform:translateY(-50%)'
121 | }
122 | }
123 | ]
124 | })
125 |
126 | t.ok(css.indexOf('.trans-center-x{left:50%;transform:translateX(-50%)}') >= 0, 'custom raw utils succesfully generated')
127 | t.ok(css.indexOf('[sm~="trans-center-x"]{left:50%;transform:translateX(-50%)}') >= 0, 'custom raw utils succesfully generated per breakpoint')
128 |
129 | t.end()
130 | })
131 |
--------------------------------------------------------------------------------
/util.js:
--------------------------------------------------------------------------------
1 | module.exports = require('gr8-util')
2 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | var x = require('xtend')
2 | var gr8util = require('gr8-util')
3 | var objectValues = require('object-values')
4 |
5 | module.exports = gr8utils
6 |
7 | var defaults = {
8 | spacing: [0, 1, 2, 3, 4],
9 | fontSize: [1, 1.2, 1.6, 2.4, 3.2, 6.4],
10 | lineHeight: [1, 1.5],
11 | size: [0, 100],
12 | viewport: [50, 100],
13 | zIndex: [0, 1, 2, 3, 4],
14 | flexOrder: [0, 1, 2, 3, 4],
15 | opacity: [0, 25, 50, 75, 100],
16 | aspectRatio: [25, 50, 75, 100],
17 | textColumn: [1, 2, 3, 4],
18 | unit: 'rem'
19 | }
20 |
21 | var utils = {
22 | column: require('./utils/column'),
23 | margin: require('./utils/margin'),
24 | padding: require('./utils/padding'),
25 | opacity: require('./utils/opacity'),
26 | background: require('./utils/background'),
27 | flex: require('./utils/flex'),
28 | display: require('./utils/display'),
29 | float: require('./utils/float'),
30 | overflow: require('./utils/overflow'),
31 | positioning: require('./utils/positioning'),
32 | size: require('./utils/size'),
33 | typography: require('./utils/type'),
34 | miscellaneous: require('./utils/misc'),
35 | development: require('./utils/dev')
36 | }
37 |
38 | function gr8utils (options) {
39 | return generate(filter(utils, options.exclude), options)
40 | }
41 |
42 | // public
43 | gr8utils.defaults = defaults
44 | gr8utils.utils = utils
45 | gr8utils.generate = generate
46 |
47 | function filter (utils, keys) {
48 | if (!Array.isArray(keys)) return utils
49 | var allKeys = Object.keys(utils)
50 | keys.forEach(function (key) {
51 | var isMatch = allKeys.indexOf(key) >= 0
52 | if (isMatch) {
53 | delete utils[key]
54 | }
55 | })
56 | return utils
57 | }
58 |
59 | function generate (utils, options) {
60 | options = x(defaults, options)
61 | return objectValues(utils).map(function (util) {
62 | return generateEach(objectValues(util), options)
63 | }).join('\n')
64 | }
65 |
66 | function generateEach (utils, options) {
67 | return utils.map(function (util) {
68 | if (typeof util === 'function') {
69 | util = util(options)
70 | }
71 |
72 | if (typeof util === 'string') {
73 | return util
74 | } else {
75 | util.selector = options.selector
76 | return gr8util(util)
77 | }
78 | }).join('\n')
79 | }
80 |
--------------------------------------------------------------------------------
/utils/background.js:
--------------------------------------------------------------------------------
1 | exports.size = {
2 | prop: {
3 | bgs: 'background-size'
4 | },
5 | vals: {
6 | c: 'cover',
7 | ct: 'contain'
8 | }
9 | }
10 |
11 | exports.position = {
12 | prop: {
13 | bgp: 'background-position'
14 | },
15 | vals: [
16 | 'center',
17 | 'top',
18 | 'right',
19 | 'bottom',
20 | 'left'
21 | ]
22 | }
23 |
24 | exports.repeat = {
25 | prop: {
26 | bgr: 'background-repeat'
27 | },
28 | vals: {
29 | n: 'no-repeat',
30 | x: 'repeat-x',
31 | y: 'repeat-y'
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/utils/column.js:
--------------------------------------------------------------------------------
1 | exports.column = {
2 | prop: {
3 | c: 'width'
4 | },
5 | vals: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
6 | transform: v => Math.round((v / 12 * 100) * 100000) / 100000,
7 | unit: '%'
8 | }
9 |
10 | exports.split = {
11 | prop: {
12 | s: 'width'
13 | },
14 | vals: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
15 | transform: v => Math.round((1 / v * 100) * 100000) / 100000,
16 | unit: '%'
17 | }
18 |
19 | exports.offset = {
20 | prop: {
21 | co: 'margin-left'
22 | },
23 | vals: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
24 | transform: v => Math.round((v / 12 * 100) * 100000) / 100000,
25 | unit: '%'
26 | }
27 |
--------------------------------------------------------------------------------
/utils/dev.js:
--------------------------------------------------------------------------------
1 | var colors = {
2 | purp: '#912eff',
3 | blue: '#5497ff',
4 | teal: '#51feff',
5 | red: '#ff0000',
6 | lime: '#00ff00'
7 | }
8 |
9 | exports.dev = function (options) {
10 | var selector = options.selector || (s => `.${s}`)
11 | return [
12 | `${selector('dev')}{outline:1px solid ${colors.purp}}`,
13 | `${selector('dev')} > * {outline:1px solid ${colors.blue}}`,
14 | `${selector('dev')} > * > * {outline:1px solid ${colors.teal}}`,
15 | `${selector('dev')} > * > * > * {outline:1px solid ${colors.red}}`,
16 | `${selector('dev')} > * > * > * * {outline:1px solid ${colors.lime}}`
17 | ].join('\n')
18 | }
19 |
--------------------------------------------------------------------------------
/utils/display.js:
--------------------------------------------------------------------------------
1 | exports.display = {
2 | prop: 'display',
3 | vals: [
4 | 'flex',
5 | 'block',
6 | 'inline-block',
7 | 'inline',
8 | 'table',
9 | 'table-cell',
10 | 'table-row',
11 | 'none'
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/utils/flex.js:
--------------------------------------------------------------------------------
1 | exports.display = function (options) {
2 | var selector = options.selector || (s => `.${s}`)
3 | return `${selector('x')}{display:flex}`
4 | }
5 |
6 | exports.align = {
7 | prop: {
8 | xa: 'align-items'
9 | },
10 | vals: [
11 | 'center',
12 | 'baseline',
13 | 'stretch',
14 | 'flex-start',
15 | 'flex-end'
16 | ]
17 | }
18 |
19 | exports.direction = {
20 | prop: {
21 | xd: 'flex-direction'
22 | },
23 | vals: [
24 | 'row',
25 | 'row-reverse',
26 | 'column',
27 | 'column-reverse'
28 | ]
29 | }
30 |
31 | exports.justify = {
32 | prop: {
33 | xj: 'justify-content'
34 | },
35 | vals: {
36 | c: 'center',
37 | b: 'space-between',
38 | a: 'space-around',
39 | s: 'flex-start',
40 | e: 'flex-end'
41 | }
42 | }
43 |
44 | exports.wrap = {
45 | prop: {
46 | x: 'flex-wrap'
47 | },
48 | vals: [
49 | 'wrap',
50 | 'wrap-reverse',
51 | { wn: 'nowrap' }
52 | ]
53 | }
54 |
55 | exports.flex = {
56 | prop: {
57 | x: 'flex'
58 | },
59 | vals: [
60 | 'initial',
61 | { x: '1' },
62 | 'auto',
63 | 'none'
64 | ]
65 | }
66 |
67 | exports.order = function (options) {
68 | var values = Array.isArray(options.flexOrder)
69 | ? options.flexOrder
70 | : [options.flexOrder]
71 | return {
72 | prop: {
73 | xo: 'order'
74 | },
75 | vals: values.concat([
76 | { t: -1 },
77 | { b: 99 }
78 | ])
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/utils/float.js:
--------------------------------------------------------------------------------
1 | exports.float = {
2 | prop: 'float',
3 | vals: [
4 | 'left',
5 | 'right',
6 | 'none'
7 | ]
8 | }
9 |
10 | exports.clear = function (options) {
11 | var selector = options.selector || (s => `.${s}`)
12 | return `${selector('cf')}:after{content:"";display:block;clear:both}`
13 | }
14 |
--------------------------------------------------------------------------------
/utils/margin.js:
--------------------------------------------------------------------------------
1 | exports.margin = function (options) {
2 | return {
3 | prop: [
4 | 'margin',
5 | 'margin-top',
6 | 'margin-right',
7 | 'margin-bottom',
8 | 'margin-left',
9 | {
10 | mx: [
11 | 'margin-left',
12 | 'margin-right'
13 | ]
14 | },
15 | {
16 | my: [
17 | 'margin-top',
18 | 'margin-bottom'
19 | ]
20 | }
21 | ],
22 | vals: options.spacing,
23 | unit: options.unit
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/utils/misc.js:
--------------------------------------------------------------------------------
1 | exports.cursor = {
2 | prop: {
3 | cur: 'cursor'
4 | },
5 | vals: [
6 | 'pointer',
7 | 'default',
8 | 'alias',
9 | 'zoom-in',
10 | 'zoom-out'
11 | ]
12 | }
13 |
14 | exports.userSelect = {
15 | prop: 'user-select',
16 | vals: [
17 | 'none',
18 | 'auto',
19 | 'text'
20 | ]
21 | }
22 |
23 | exports.pointerEvents = {
24 | prop: 'pointer-events',
25 | vals: [
26 | 'none',
27 | 'auto'
28 | ]
29 | }
30 |
31 | exports.visibility = {
32 | prop: 'visibility',
33 | vals: [
34 | 'hidden',
35 | 'visible'
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/utils/opacity.js:
--------------------------------------------------------------------------------
1 | exports.opacity = function (options) {
2 | return {
3 | prop: {
4 | op: 'opacity'
5 | },
6 | vals: options.opacity,
7 | transform: v => v / 100
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/utils/overflow.js:
--------------------------------------------------------------------------------
1 | exports.overflow = {
2 | prop: [
3 | 'overflow',
4 | 'overflow-x',
5 | 'overflow-y'
6 | ],
7 | vals: [
8 | 'hidden',
9 | 'scroll',
10 | 'visible'
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/utils/padding.js:
--------------------------------------------------------------------------------
1 | exports.padding = function (options) {
2 | return {
3 | prop: [
4 | 'padding',
5 | 'padding-top',
6 | 'padding-right',
7 | 'padding-bottom',
8 | 'padding-left',
9 | {
10 | px: [
11 | 'padding-left',
12 | 'padding-right'
13 | ]
14 | },
15 | {
16 | py: [
17 | 'padding-top',
18 | 'padding-bottom'
19 | ]
20 | }
21 | ],
22 | vals: options.spacing,
23 | unit: options.unit
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/utils/positioning.js:
--------------------------------------------------------------------------------
1 | exports.position = {
2 | prop: {
3 | ps: 'position'
4 | },
5 | vals: [
6 | 'absolute',
7 | 'relative',
8 | 'fixed',
9 | 'static'
10 | ]
11 | }
12 |
13 | exports.placement = {
14 | prop: [
15 | 'top',
16 | 'right',
17 | 'bottom',
18 | 'left'
19 | ],
20 | vals: 0
21 | }
22 |
23 | exports.zindex = function (options) {
24 | return {
25 | prop: {
26 | z: 'z-index'
27 | },
28 | vals: options.zIndex
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/utils/size.js:
--------------------------------------------------------------------------------
1 | exports.size = function (options) {
2 | return {
3 | prop: ['width', 'height'],
4 | vals: options.size,
5 | unit: '%'
6 | }
7 | }
8 |
9 | exports.viewportWidth = function (options) {
10 | return {
11 | prop: {
12 | vw: 'width',
13 | vwmn: 'min-width',
14 | vwmx: 'max-width'
15 | },
16 | vals: options.viewport,
17 | unit: 'vw'
18 | }
19 | }
20 |
21 | exports.viewportHeight = function (options) {
22 | return {
23 | prop: {
24 | vh: 'height',
25 | vhmn: 'min-height',
26 | vhmx: 'max-height'
27 | },
28 | vals: options.viewport,
29 | unit: 'vh'
30 | }
31 | }
32 |
33 | exports.aspect = function (options) {
34 | return {
35 | prop: {
36 | ar: 'padding-top'
37 | },
38 | vals: options.aspectRatio,
39 | transform: v => v + '%;content:"";display:block',
40 | tail: ':before'
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/utils/type.js:
--------------------------------------------------------------------------------
1 | exports.fontSize = function (options) {
2 | return {
3 | prop: 'font-size',
4 | vals: options.fontSize,
5 | unit: options.unit
6 | }
7 | }
8 |
9 | exports.lineHeight = function (options) {
10 | return {
11 | prop: 'line-height',
12 | vals: options.lineHeight
13 | }
14 | }
15 |
16 | exports.fontStyle = {
17 | prop: 'font-style',
18 | vals: [
19 | 'normal',
20 | 'italic'
21 | ]
22 | }
23 |
24 | exports.fontWeight = {
25 | prop: 'font-weight',
26 | vals: [
27 | 'normal',
28 | 'bold'
29 | ]
30 | }
31 |
32 | exports.textAlign = {
33 | prop: 'text-align',
34 | vals: [
35 | 'left',
36 | 'center',
37 | 'right',
38 | 'justify'
39 | ]
40 | }
41 |
42 | exports.textOverflow = {
43 | prop: 'text-overflow',
44 | vals: [
45 | 'initial',
46 | 'clip',
47 | 'ellipsis'
48 | ]
49 | }
50 |
51 | exports.textDecoration = {
52 | prop: 'text-decoration',
53 | vals: [
54 | 'underline',
55 | 'overline',
56 | 'line-through',
57 | 'none'
58 | ]
59 | }
60 |
61 | exports.textTransform = {
62 | prop: 'text-transform',
63 | vals: [
64 | 'uppercase',
65 | 'lowercase',
66 | 'capitalize',
67 | 'none'
68 | ]
69 | }
70 |
71 | exports.verticalAlign = {
72 | prop: 'vertical-align',
73 | vals: [
74 | { bl: 'baseline' },
75 | 'top',
76 | 'middle',
77 | 'bottom'
78 | ]
79 | }
80 |
81 | exports.whiteSpace = {
82 | prop: 'white-space',
83 | vals: [
84 | 'normal',
85 | { nw: 'nowrap' },
86 | 'pre',
87 | 'inherit'
88 | ]
89 | }
90 |
91 | exports.textColumn = function (options) {
92 | return {
93 | prop: {
94 | tc: 'columns'
95 | },
96 | vals: options.textColumn
97 | }
98 | }
99 |
--------------------------------------------------------------------------------