1# CSSType
2
3[![npm](https://img.shields.io/npm/v/csstype.svg)](https://www.npmjs.com/package/csstype)
4
5TypeScript and Flow definitions for CSS, generated by [data from MDN](https://github.com/mdn/data). It provides autocompletion and type checking for CSS properties and values.
6
7```ts
8import * as CSS from 'csstype';
9
10const style: CSS.Properties = {
11  colour: 'white', // Type error on property
12  textAlign: 'middle', // Type error on value
13};
14```
15
16## Getting started
17
18```sh
19$ npm install csstype
20$ # or
21$ yarn add csstype
22```
23
24## Table of content
25
26- [Style types](#style-types)
27- [At-rule types](#at-rule-types)
28- [Pseudo types](#pseudo-types)
29- [Usage](#usage)
30- [What should I do when I get type errors?](#what-should-i-do-when-i-get-type-errors)
31- [Version 2.0](#version-20)
32- [Contributing](#contributing)
33  - [Commands](#commands)
34
35## Style types
36
37Properties are categorized in different uses and in several technical variations to provide typings that suits as many as possible.
38
39All interfaces has one optional generic argument to define length. It defaults to `string | 0` because `0` is the [only unitless length](https://www.w3.org/TR/REC-CSS2/syndata.html#length-units). You can specify this, e.g. `string | number`, for platforms and libraries that accepts any numeric value as length with a specific unit.
40
41|                | Default              | `Hyphen`                   | `Fallback`                   | `HyphenFallback`                   |
42| -------------- | -------------------- | -------------------------- | ---------------------------- | ---------------------------------- |
43| **All**        | `Properties`         | `PropertiesHyphen`         | `PropertiesFallback`         | `PropertiesHyphenFallback`         |
44| **`Standard`** | `StandardProperties` | `StandardPropertiesHyphen` | `StandardPropertiesFallback` | `StandardPropertiesHyphenFallback` |
45| **`Vendor`**   | `VendorProperties`   | `VendorPropertiesHyphen`   | `VendorPropertiesFallback`   | `VendorPropertiesHyphenFallback`   |
46| **`Obsolete`** | `ObsoleteProperties` | `ObsoletePropertiesHyphen` | `ObsoletePropertiesFallback` | `ObsoletePropertiesHyphenFallback` |
47| **`Svg`**      | `SvgProperties`      | `SvgPropertiesHyphen`      | `SvgPropertiesFallback`      | `SvgPropertiesHyphenFallback`      |
48
49Categories:
50
51- **All** - Includes `Standard`, `Vendor`, `Obsolete` and `Svg`
52- **`Standard`** - Current properties and extends subcategories `StandardLonghand` and `StandardShorthand` _(e.g. `StandardShorthandProperties`)_
53- **`Vendor`** - Vendor prefixed properties and extends subcategories `VendorLonghand` and `VendorShorthand` _(e.g. `VendorShorthandProperties`)_
54- **`Obsolete`** - Removed or deprecated properties
55- **`Svg`** - SVG-specific properties
56
57Variations:
58
59- **Default** - JavaScript (camel) cased property names
60- **`Hyphen`** - CSS (kebab) cased property names
61- **`Fallback`** - Also accepts array of values e.g. `string | string[]`
62
63## At-rule types
64
65At-rule interfaces with descriptors.
66
67|                      | Default        | `Hyphen`             | `Fallback`             | `HyphenFallback`             |
68| -------------------- | -------------- | -------------------- | ---------------------- | ---------------------------- |
69| **`@counter-style`** | `CounterStyle` | `CounterStyleHyphen` | `CounterStyleFallback` | `CounterStyleHyphenFallback` |
70| **`@font-face`**     | `FontFace`     | `FontFaceHyphen`     | `FontFaceFallback`     | `FontFaceHyphenFallback`     |
71| **`@page`**          | `Page`         | `PageHyphen`         | `PageFallback`         | `PageHyphenFallback`         |
72| **`@viewport`**      | `Viewport`     | `ViewportHyphen`     | `ViewportFallback`     | `ViewportHyphenFallback`     |
73
74## Pseudo types
75
76String literals of pseudo classes and pseudo elements
77
78- `Pseudos`
79
80  Extends:
81
82  - `AdvancedPseudos`
83
84    Function-like pseudos e.g. `:not(:first-child)`. The string literal contains the value excluding the parenthesis: `:not`. These are separated because they require an argument that results in infinite number of variations.
85
86  - `SimplePseudos`
87
88    Plain pseudos e.g. `:hover` that can only be **one** variation.
89
90## Usage
91
92Length defaults to `string | 0`. But it's possible to override it using generics.
93
94```ts
95import * as CSS from 'csstype';
96
97const style: CSS.Properties<string | number> = {
98  padding: 10,
99  margin: '1rem',
100};
101```
102
103In some cases, like for CSS-in-JS libraries, an array of values is a way to provide fallback values in CSS. Using `CSS.PropertiesFallback` instead of `CSS.Properties` will add the possibility to use any property value as an array of values.
104
105```ts
106import * as CSS from 'csstype';
107
108const style: CSS.PropertiesFallback = {
109  display: ['-webkit-flex', 'flex'],
110  color: 'white',
111};
112```
113
114There's even string literals for pseudo selectors and elements.
115
116```ts
117import * as CSS from 'csstype';
118
119const pseudos: { [P in CSS.SimplePseudos]?: CSS.Properties } = {
120  ':hover': {
121    display: 'flex',
122  },
123};
124```
125
126Hyphen cased (kebab cased) properties are provided in `CSS.PropertiesHyphen` and `CSS.PropertiesHyphenFallback`. It's not **not** added by default in `CSS.Properties`. To allow both of them, you can simply extend with `CSS.PropertiesHyphen` or/and `CSS.PropertiesHyphenFallback`.
127
128```ts
129import * as CSS from 'csstype';
130
131interface Style extends CSS.Properties, CSS.PropertiesHyphen {}
132
133const style: Style = {
134  'flex-grow': 1,
135  'flex-shrink': 0,
136  'font-weight': 'normal',
137  backgroundColor: 'white',
138};
139```
140
141## What should I do when I get type errors?
142
143The goal is to have as perfect types as possible and we're trying to do our best. But with CSS Custom Properties, the CSS specification changing frequently and vendors implementing their own specifications with new releases sometimes causes type errors even if it should work. Here's some steps you could take to get it fixed:
144
145_If you're using CSS Custom Properties you can step directly to step 3._
146
1471.  **First of all, make sure you're doing it right.** A type error could also indicate that you're not :wink:
148
149    - Some CSS specs that some vendors has implemented could have been officially rejected or haven't yet received any official acceptance and are therefor not included
150    - If you're using TypeScript, [type widening](https://blog.mariusschulz.com/2017/02/04/typescript-2-1-literal-type-widening) could be the reason you get `Type 'string' is not assignable to...` errors
151
1522.  **Have a look in [issues](https://github.com/frenic/csstype/issues) to see if an issue already has been filed. If not, create a new one.** To help us out, please refer to any information you have found.
1533.  Fix the issue locally with **TypeScript** (Flow further down):
154
155    - The recommended way is to use **module augmentation**. Here's a few examples:
156
157      ```ts
158      // My css.d.ts file
159      import * as CSS from 'csstype';
160
161      declare module 'csstype' {
162        interface Properties {
163          // Add a missing property
164          WebkitRocketLauncher?: string;
165
166          // Add a CSS Custom Property
167          '--theme-color'?: 'black' | 'white';
168
169          // ...or allow any other property
170          [index: string]: any;
171        }
172      }
173      ```
174
175    - The alternative way is to use **type assertion**. Here's a few examples:
176
177      ```ts
178      const style: CSS.Properties = {
179        // Add a missing property
180        ['WebkitRocketLauncher' as any]: 'launching',
181
182        // Add a CSS Custom Property
183        ['--theme-color' as any]: 'black',
184      };
185      ```
186
187    Fix the issue locally with **Flow**:
188
189    - Use **type assertion**. Here's a few examples:
190
191      ```js
192      const style: $Exact<CSS.Properties<*>> = {
193        // Add a missing property
194        [('WebkitRocketLauncher': any)]: 'launching',
195
196        // Add a CSS Custom Property
197        [('--theme-color': any)]: 'black',
198      };
199      ```
200
201## Version 2.0
202
203The casing of CSS vendor properties are changed matching the casing of prefixes in Javascript. So all of them are capitalized except for `ms`.
204
205- `msOverflowStyle` is still `msOverflowStyle`
206- `mozAppearance` is now `MozAppearance`
207- `webkitOverflowScrolling` is now `WebkitOverflowScrolling`
208
209More info: https://www.andismith.com/blogs/2012/02/modernizr-prefixed/
210
211## Contributing
212
213**Never modify `index.d.ts` and `index.js.flow` directly. They are generated automatically and committed so that we can easily follow any change it results in.** Therefor it's important that you run `$ git config merge.ours.driver true` after you've forked and cloned. That setting prevents merge conflicts when doing rebase.
214
215### Commands
216
217- `yarn build` Generates typings and type checks them
218- `yarn watch` Runs build on each save
219- `yarn test` Runs the tests
220- `yarn lazy` Type checks, lints and formats everything
221