JSPM

  • Created
  • Published
  • Downloads 69416
  • Score
    100M100P100Q152406F
  • License MIT

TypeSafe CSS

Package Exports

  • typestyle
  • typestyle/lib

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (typestyle) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

TypeStyle

Join the chat at  gitter

Making CSS type safe.

Build Status NPM version

Writing CSS with TypeStyle will be just as fluent as writing JavaScript with TypeScript.

There are quite a few css in js frameworks out there. This one is different:

  • Provides great TypeScript developer experience.
  • No custom AST transform or module loader support needed.
  • Works with any framework (react, angular2, cyclejs, whatever, doesn't matter).
  • Zero config. Just use.
  • super small (~1k)

This project is powered by github 🌟s ^ go ahead and star it please.

Checkout the awesome list of reviews 🌹.

Overview

Quickstart

Use it like you would use CSS modules or CSS in general with webpack etc, but this time you get to use TypeScript / JavaScript!

Install npm install typestyle --save

Use

/** Import */
import {style} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({color: 'red'});

/** Use the class name in a framework of choice */
//  e.g. React
const MyButton =
  ({onClick,children})
    => <button className={className} onClick={onClick}>
        {children}
      </button>
// or Angular2
@Component({
  selector: 'my-component',
  template: `<div class="${className}">Tada</div>`
})
export class MyComponent {}

Play with it

Server Side

Just get the styles as CSS at any point and render it in a style tag yourself. e.g.

/** Import */
import {style, css} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({color: 'red'});

/** Render to CSS style tag */
const styleTag = `<style>${css()}</style>`
/** ^ send this as a part of your HTML response */

Advanced

Pseudo States &:hover, &:active, &:focus, &:disabled as you would expect e.g.

/** Import */
import {style} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({
  color: 'blue',
  '&:hover': {
    color: 'red'
  }
});

Child selectors &>* etc work too e.g. use it to design a vertical layout:

/** Import */
import {style} from "typestyle";

/** Share constants in TS! */
const spacing = '5px';

/** style -> className :) */
const className = style({
  '&>*': {
    marginBottom: spacing,
  },
  '&>*:last-child': {
    marginBottom: '0px',
  }
});

Media Queries

const colorChangingClass = style({
  backgroundColor: 'red',
  '@media (min-width: 400px)': {
    backgroundColor: 'pink'
  }
})

Merge Objects Pass as many style objects to style and they merge just right.

const redMaker = {color:'red'};
const alwaysRedClass = style(redMaker);
const greyOnHoverClass = style(
  redMaker,
  {'&:hover':{color: 'grey'}}
);

Compose Classes You can easily compose class names using classes

const tallClass = style({height:'100px'});
const redClass = style({color:'red'});

/** Compose classes */
const tallRedClass = typestyle.classes(tallClass, redClass);

/** Even conditionally (any falsy parameters are ignored in the composed class name) */
const mightBeRed = typestyle.classes(tallClass, hasError && redClass);

Animations Use keyframes to define an animation and get the animation name

const colorAnimationName = typestyle.keyframes({
  from: { color: 'red' },
  to: { color: 'blue' }
})

const ooooClass = typestyle.style({
  animationName: colorAnimationName,
  animationDuration: '1s'
});

TypeScript Protip: namespace

/** Think of it like an inline stylesheet */
namespace MyStyles {
  const color = 'red';

  export const alwaysRedClass = style({color});
  export const onlyRedOnHoverClass = style({'&:hover':{color});
}

/** Use e.g. with React */
const AlwaysRed = ({text}) => <div className={MyStyles.alwaysRedClass}>{text}</div>
const OnlyRedOnHover = ({text}) => <div className={MyStyles.onlyRedOnHoverClass}>{text}</div>

Fallbacks

There are two kinds of fallbacks in CSS and both are supported:

  • Same key multiple values: Just use an array for the value e.g. background colors
const fallBackBackground = style({
  backgroundColor: [
    /* The fallback */
    'rgb(200, 54, 54)',
    /** Graceful upgrade */
    'rgba(200, 54, 54, 0.5)'
  ]
});
  • Vendor prefixing: Anything that starts with - is not case renamed (i.e. no fooBar => foo-bar) e.g. for smooth scroll:
const scroll = style({
  '-webkit-overflow-scrolling': 'touch',
  overflow: 'auto'
});

Protip: Big fan of flexbox? Use csx as it provides the necessary vendor prefixes so you don't need to worry about them.

Note: We don't do automatic vendor prefixing for a few reasons:

CSS Replacement

You can even use any raw CSS selector as well using cssRule e.g.

  • To setup a application style layout:
/** Use full window size for application */
cssRule('html, body', {
  height: '100%',
  width: '100%',
  padding: 0,
  margin: 0
});
  • Font faces:
cssRule('@font-face', {
  fontFamily: '"Bitstream Vera Serif Bold"',
  src: 'url("https://mdn.mozillademos.org/files/2468/VeraSeBd.ttf")'
});
  • Page level media queries:
/** Save ink with a white background */
cssRule('@media print', {
  body: {
    background: 'white'
  }
});

Advantage: cssRule(selector,properties) works seemlessly in a nodejs enviroment (for testing) whereas require('./someCss.css') does not without additional setup.

CSX

We understand that its difficult to get started with CSS in JS without additional guidance. So we also provide a lot of utility style objects in typestyle/csx to decrease you rampup. e.g. flexbox:

import * as csx from 'typestyle/lib/csx';
import {style} from 'typestyle';

const horizontal = style(csx.horizontal);

/** Sample usage with React */
var Demo = () =>
  <div className={horizontal}>
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
  </div>;

Of course you can compose styles easily:

import * as csx from 'typestyle/lib/csx';
import {style} from 'typestyle';

const flexHorizontalGreen = style(
  csx.flex,
  csx.horizontal,
  { backgroundColor: 'green' }
);

/** Sample usage with React */
const Demo = () =>
  <div className={flexHorizontalGreen}>
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
  </div>;

Type-safe colors and more

To make it easier to work with colors, TypeStyle has a lot of the same color functions as SASS or LESS built-in with type definitions. This means that writing CSS in JS is even easier than ever!

Here is an example of some of the ways colors can be used together.

import { rgb, black } from 'typestyle/lib/csx';

const primaryColor = rgb(0, 0, 255);
const primaryBgColor = primaryColor.darken('30%').desaturate('10%');
const primaryBoldColor = primaryColor.mix(black);
const invertedColor = black.lighten('20%');
const invertedBgColor = primaryBgColor.invert();

const buttonStyles = style({
  color: primaryColor,
  backgroundColor: primaryBgColor
});

const invertedButtonStyles = style({
  color: invertedColor,
  backgroundColor: invertedBgColor
});

If you need to do testing with these colors, you can even print them to console by calling the .toString() method.

console.log(red.toString()); // prints 'rgb(255,0,0)'

Book

We really really want to make CSS maintainable and simple. So we even wrote a free and open source book for how to use the utility styles in typestyle/lib/csx 🌹. Jump to the book

How

This works very much in the same principle as CSS modules in that it takes a style object and generates a non conflicting generated class name.

Really How

  • FreeStyle converts a JS style object to a CSS className using hashing
  • We keep a single style sheet updated as you register styles.
  • Provide css.d.ts to help with autocomplete + error reporting.

Help

Really apprecate as many PRs for css.d.ts CSSProperties as you can throw at us 🌹

Performance

Same as FreeStyle which is super simple and does the absolute minimum but necessary, so faster than other CSS in JS frameworks for sure. We'd love to be told otherwise.