Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

About the good parts of writing styles in javascript using JSS. Comparison to other existing CSS solutions and points about negative aspects got so far.

React Amsterdam

April 21, 2016
Tweet

More Decks by React Amsterdam

Other Decks in Technology

Transcript

  1. 2 Plan Plan 1. React and CSS. 2. What are

    inline styles. 3. Problems solved by inline styles. 4. Interesting CSS in JS libs. 5. What is JSS. 6. Problems solved by JSS. 7. Unsolved problems.
  2. 3 React and CSS React and CSS React is about

    React is about components components. . CSS is for CSS is for documents. documents.
  3. 5

  4. 6 Inline styles Inline styles const style = {color: red}

    <div style={style}></div> <div style="color: red"></div> HTML React const element = document.createElement('div') element.style.color = 'red' DOM
  5. 7 Global Namespace Global Namespace Selectors are the evil. Try

    to write an application inside of one function.
  6. 8 Implicit Implicit Dependencies Dependencies <button class="default-button my-button">My Button</button> /*

    buttons.css */ .default-button { cursor: pointer; } /* my-component.css */ .my-button { color: red; }
  7. 9 Dead code Dead code A task for a compiler.

    function module() { var styles = { button: { color: 'green' }, myButton: { color: 'red' } } // Renders a button. button({style: styles.myButton}) } function module(){button({style:{color:"red"}})};
  8. 10 Minification Minification function test(a) { var obj = {a:

    a, b: 2}; return obj.a + obj.b; } window.a = test(1) window.a=3; No selectors to minify. JavaScript compressor for the rest.
  9. 12 Non-deterministic Non-deterministic Resolution Resolution CSS Specificity Concept. /* my-button-1.css

    */ .my-button.my-blue-button { color: blue; } /* my-button-2.css */ button.my-button { color: red; } <head> <link href="my-button-1.css" rel="stylesheet" /> <link href="my-button-2.css" rel="stylesheet" /> </head> <body> <button class="my-button">My Button</button> </body>
  10. 21 Pure Pure Inline Inline Already built in React No

    support for @media, @keyframes etc. Performance Downsides
  11. 22 Mixed Mode Mixed Mode Radium is using: React Events

    for Pseudo Selectors. Style Sheets for @media and co. Inline for everything else.
  12. 24 What is JSS. What is JSS. Good parts of

    CSS only. Designed with components in mind. Declarative JavaScript. JavaScript to CSS compiler. Easy to reason about.
  13. 25 How does it work. How does it work. Virtual

    CSS Tree Process Render Run plugins on every VRule Output <style> with CSS. Abstraction for CSS Rules Manipulation
  14. 27 Example with React Example with React import React from

    'react' import {useSheet} from 'react-jss' @useSheet({ button: { color: 'green' } }) export default function Button(props) { const {classes} = props.sheet return <button className={classes.button}>{props.text}</button> } No magic in code.
  15. 28

  16. 30 Problems it solves. Problems it solves. 1. All issues

    solved by Inline Styles. 2. Issues introduced by Inline Styles. 3. More CSS Issues.
  17. 31 Plan Plan 1. Media Queries 2. Keyframes Animation 3.

    Font Face 4. Pseudo Selectors 5. Fallbacks 6. Rules Caching 7. Rules Sharing 8. Extensible Architecture 9. Tools Agnostic 10. Vendor Prefixer 11. Inheritance DSL Library
  18. 32 Media Queries Media Queries export default { '@media (min-width:

    1024px)': { button: { minWidth: 200 } } } const breakpoint = 1024 export default { [`@media (min-width: ${breakpoint}px)`]: { button: { minWidth: 200 } } } @media (min-width: 1024px) { .button-jss-0 { min-width: 200px; } } JSS in ES5 JSS in ES6 CSS Not possible Inline.
  19. 33 Keyframes Animation Keyframes Animation export default { '@keyframes my-animation':

    { from: {opacity: 0}, to: {opacity: 1} } } const identifier = random() export default { [`@keyframes ${identifier}`]: { from: {opacity: 0}, to {opacity: 1} } } @keyframes my-animation { from { opacity: 0; } to { opacity: 1; } } JSS in ES5 JSS in ES6 CSS Not possible Inline.
  20. 34 Font Face Font Face export default { '@font-face': {

    fontFamily: 'MyWebFont', src: [ 'url(webfont.eot)', 'url(webfont.eot?#iefix) format(embedded-opentype)', 'url(webfont.woff2) format(woff2)' ] } } @font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); src: url('webfont.eot?#iefix') format('embedded-opentype'), url('webfont.woff2') format('woff2'); } JSS CSS Not possible Inline.
  21. 35 Pseudo Selectors Pseudo Selectors export default { button: {

    color: 'green' '&:hover': { color: 'red' }, '&:active': { color: blue }, '&:before': { content: '"icon"' }, '& span': { verticalAlign: 'middle' } } } .jss-0-1 { color: green; } .jss-0-1:hover { color: red; } .jss-0-1:active { color: blue; } .jss-0-1:before { content: "icon"; } .jss-0-1 span { vertical-align: middle; } JSS CSS Not possible Inline. Inspired by Sass.
  22. 36 Fallbacks Fallbacks export default { container: { display: ['box',

    'flexbox','flex'] } } .jss-0-1 { display: box; display: flexbox; display: flex; } JSS CSS Not possible Inline.
  23. 39 Class Names are fast. Class Names are fast. 1.

    Find modified props. 2. Find props to unset. 3. Ensure valid property name, value, default unit. 4. Apply each property to an element
  24. 43 Vendor Prefixer Vendor Prefixer Plugin export default { container:

    { display: 'flex' } } .jss-0-1 { display: -webkit-flex; } JSS CSS
  25. 45 JSS-ISOLATE JSS-ISOLATE Created a JSS plugin. and SOLVED INHERITANCE

    PROBLEM Maxim Koretskiy “ This plugin protects styles from inheritance. It automatically creates a reset rule and applies it to every user's rule.
  26. 48 Wrong Language? Wrong Language? import color from 'color' import

    fonts from 'theme/fonts' import mixins from 'jss-mixins' import {gainsboroLight, grapeTypo, grey, blue, white} from 'theme/colors' const grapeTypoSemi = color(grapeTypo).alpha(0.5).rgbaString() export default { datalist: { background: white, border: `1px solid ${gainsboroLight}`, boxShadow: `0px 3px 4px 0 ${grapeTypoSemi}`, overflow: 'auto' }, item: { extend: [fonts.normal, mixins.ellipsis], padding: `5px 7px`, color: grey, cursor: `pointer` }, `@media (min-width: 1024px)`: { item: { color: blue } } }
  27. 49 Let's experiment! Let's experiment! export default css` datalist {

    background: ${white}; border: 1px solid ${gainsboroLight}; box-shadow: 0px 3px 4px 0 ${grapeTypoSemi}; overflow: auto } item { extend: ${[fonts.normal, mixins.ellipsis]}; padding: 5px 7px; color: ${grey}; cursor: ${pointer}; } @media (min-width: 1024px) { item { color: ${blue} } } ` Tagged template literals
  28. 51 Missing dev tools Missing dev tools There is no

    autocomplete tools like Emmet or IntelliSense. There is no CSS specific highlighting. No linters.
  29. 52 Blocks initial Blocks initial rendering. rendering. Use it where

    it doesn't matter. Use server-side rendering. Use a hybrid approach.
  30. 53 Takeaways Takeaways CSS in JS is not only for

    big projects, it's for any maintainable project. Use Inline Styles for: 1. State styles. For e.g. when a "width" of a component depends on its state. 2. Animations. Don't be religious. Keep an open mind. Use tools that solve your problems!