UVP*

and the future of

CSSinJS 

* Unique Value Proposition

by Oleg Slobodskoi @oleg008

The world’s first
Project Messenger.

I maintain a

CSSinJS lib

CSSinJS is an
approach to describe

CSS in JavaScript

CSSinJS

!==

Inline Styles

  1. Scoping
  2. Isolation
  3. Modules
  4. Code reuse
  5. Specificity
  6. Non-deterministic Resolution
  7. Dead code elimination

2014

Do we really need CSSinJS for this?

Can get there

with PostCSS?

So why CSSinJS?

JavaScript,
Motherfucker,
Do You Speak It!

2014

Since then I got a ridiculous  amount of feedback …

… did a lot of experiments …

… learned from many other CSSinJS implementations …

… and from using in production.

Lost my hair!!!

My Top 9

Examples!


    import {lighten} from 'polished'
    
    const styles = {
      button: {
        background: lighten(0.2, '#CCCD64')
      }
    }

polished


    import {zoomIn} from 'cssinjs-animations'
    
    const styles = {
      '@keyframes zoomIn': zoomIn,
      box: {
        position: 'absolute',
        width: 50,
        height: 50,
        background: 'blue',
        animation: {
          name: 'zoomIn',
          duration: '1s'
        }
      }
    }

cssinjs-animations


    import rtl 'rtl-css-js'
    
    const styles = rtl({paddingLeft: 10})
        

rtl-css-js


    const styles = {paddingRight: 10}

The contract

between packages

For JavaScript

1. Public API documentation

2. Tests

3. Linters
4. Typings

5. Runtime Errors

What about CSS?

NPM Registry
~ 550k Packages

Still wanna use BEM?

PBEM?

Package Block Element Modifier

How do you ensure?

- Source Order

- Cascading

- Global Styles

CSS Properties and Values should be part of the

contract

Many Runtimes

Is it a

CSSinJS war?

Is it
CSSinJS fatigue?

No, it is

absolutely

normal

The same is with  DOM

libs

Room for

improvements

DX gets better

Performance

gets better

Best ideas win


  <View style={{
    marginTop: 5,
    borderWidth: 1,
    borderRadius: 5,
    borderStyle: this.state.showBorder ? 'dotted' : null,
    padding: 5
  }}>
    <Text style={{fontSize: 11}}>
      Dotted border style
    </Text>
  </View>

    const styles = csjs`
      .panel {
        border: 1px solid black;
        background-color: ${green};
      }
    
      .title {
        padding: 4px;
        font-size: 15px;
      }
    `

    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: ${({theme}) => theme.palette.headline};
    `

    import {ThemeProvider} from 'theming'
    
    const theme = {
      main: 'green'
    }
    
    const App = () => (
      <ThemeProvider theme={theme}>
          <SomeComponent />
      </ThemeProvider>
    )
    

Universal Theming

So what did

 JSS learn?


    box-shadow: 10px 10px 5px 5px black;
 
    boxShadow: {
        x: 10, 
        y: 10, 
        blur: 5, 
        spread: 5, 
        color: 'black'
    }
    

Expanded syntax

Function values


  button: {
    fontSize: 12,
    color: ({focused}) => focused ? 'black' : 'gray'
  }

Template Strings


    {
      button: `
        border-radius: 3px;
        background-color: green;
        color: red;
        margin: 20px 40px;
        padding: 10px;
      `
    }

    import styled from 'styled-jss'
    
    const Button = styled('button')({
      fontSize: 12,
      color: 'gray'
    })
    
    // Composition.
    const PrimaryButton = styled(Button)({
      color: 'blue'
    })

    <PrimaryButton>Click me!<PrimaryButton>

Styled Primitives

Theming


    const styles = (theme) => ({
      button: {
        background: theme.colorPrimary
      },
      label: {
        fontWeight: 'bold'
      }
    })
    
    const StyledButton = injectSheet(styles)(Button)

Theming

Definition of "Theme",

anyone?

Look and Feel

CSS Variables


    :root {
      --main-bg-color: brown;
    }
    
    .one {
      color: white;
      background: var(--main-bg-color);
    }

CSS Variables

cascade and inherit


    :root {
      --main-bg-color: brown;
    }
    
    .one {
      color: white;
      background: var(--main-bg-color);
    }

global

When a contract between packages is vanilla CSS

Rebranding

Much easier with JavaScript

React Native


    const styles = StyleSheet.create({
      red: {
        color: 'red'
      },
      boldblue: {
        color: 'blue',
        fontWeight: 'bold'
      }
    })
    
    class SomeComponent extends Component {
      render() {
        return (
          <View>
            <Text style={styles.red}>red text</Text>
            <Text style={styles.boldblue}>bold blue text</Text>
          </View>
        );
      }
    }
    
    

Subset of CSS

No shorthand notations

No media queries

No pseudo selectors

Typed CSS

Autocomplete
Linting
Contracts

We need

Universal Flow and Typescript
typings

Shorthand support


    const styles = {
        border: '1px solid red'
    }

Expanded format


    const styles = {
        border: {
            width: 1,
            style: 'solid',
            color: 'red'
        }
    }

Colocation

Styles and Markup
in one file

Write small components!

A complex component

is a composition

of simple components

State Driven Styles

User input

Mouse position

Viewport size

JavaScript Controlled Animations

Don't use Inline Styles!

High Performance
Function Values

JavaScipt Animations

at 60FPS

Faster than

React Inline Styles

2 Problems with
React Inline Styles

1. Reconciliation

in tree structure

2. Slow interface


    <div 
        style={{
            color: 'red', 
            fontSize: 12
        }}
    >
    </div>

CSSOM

to the rescue

Same

CSSStyleDeclaration
Interface

CSSRulesList
is flat


    const style = document.createElement(‘style’)
    
    style.sheet.insertRule(‘.my-button {color: red}’, 0)
    
    style.sheet.cssRules[0].style.color = ‘green’
    

Better Interface


    const styles = {
        button: {
            color: (props) => props.isFocused ? 'red' : 'green'
        }
    }

Applies Changes Only


    class MyComponent extends Component {
        shouldComponentUpdate() {
            return false
        }
    }

1

ISTF

Talk to me

Why CSSinJS

By Oleg Isonen

Why CSSinJS

  • 4,264