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

React Inline Styles and the Future of CSS

Alex Lande
October 26, 2015

React Inline Styles and the Future of CSS

Writing and maintaining CSS for large applications (and large teams) can be challenging. Teams often have trouble with brittle selectors, naming collisions, specificity, and pile-ups of dead code.

After seeing these issues first-hand on large projects, I built Radium: a JavaScript library for styling React applications with inline styles. In the context of a React application, inline styling elegantly solves many of the issues with large-scale CSS. It also gives you the benefits of a CSS preprocessor like Sass, with extra power for expressive styling

In this presentation, we'll compare the benefits of approaches like Radium to some upcoming and proposed additions to the CSS specification that will help make scalable CSS easy in the future, whether you're using React or not. We'll talk about things like:

- Scoped CSS
- Shadow DOM
- CSS Variables and Custom Media Queries
- Native CSS Extends

Presented at CSS Dev Conf 2015

Alex Lande

October 26, 2015
Tweet

More Decks by Alex Lande

Other Decks in Programming

Transcript

  1. REACT
    INLINE STYLES
    and the
    FUTURE
    OF CSS

    View full-size slide

  2. Hey!
    @alexlande

    View full-size slide

  3. Seattle
    “Kerry Park, Start of Spring 1” by C.M. Keiner is licensed under CC BY 2.0

    View full-size slide

  4. Seattle
    “Seattle Thunderstorm 1” by C.M. Keiner is licensed under CC BY 2.0

    View full-size slide

  5. REACT
    INLINE STYLES
    and the
    FUTURE
    OF CSS

    View full-size slide

  6. I’m an architect,
    honest!

    View full-size slide

  7. You keep using that
    word…

    View full-size slide

  8. Not everybody cares
    about CSS

    View full-size slide

  9. you don’t have to care
    Good architecture means

    View full-size slide

  10. NAMING
    CONVENTIONS
    .Sidebar {}
    .Sidebar.isExpanded {}
    .Sidebar__section {}
    .Btn {}
    .Btn--primary {}
    .Btn--round {}

    View full-size slide

  11. AUTHORING
    GUIDELINES

    View full-size slide

  12. EVERYTHING WAS
    PERFECT!

    View full-size slide

  13. EVERYTHING WAS
    TERRIBLE!

    View full-size slide

  14. SPECIFICITY
    HELL

    View full-size slide

  15. SPECIFICITY
    HELL

    View full-size slide

  16. SPECIFICITY
    HELL

    View full-size slide

  17. SPECIFICITY
    HELL

    View full-size slide

  18. “Not bad”
    is not great.

    View full-size slide

  19. CoolCorp
    MENU
    a {
    color: orange;
    }

    View full-size slide

  20. CoolCorp
    MENU
    .header a {
    color: white;
    }

    View full-size slide

  21. CoolCorp
    MENU
    SOME OPTIONS
    Pages

    View full-size slide

  22. CoolCorp MENU
    SOME OPTIONS
    Pages

    View full-size slide

  23. CoolCorp MENU
    SOME OPTIONS
    Pages
    .flyout a {
    color: orange;
    }

    View full-size slide

  24. CoolCorp MENU
    SOME OPTIONS
    Pages
    LOG IN
    .button {
    color: white;
    }

    View full-size slide

  25. CoolCorp MENU
    SOME OPTIONS
    Pages
    LOG IN

    View full-size slide

  26. CoolCorp MENU
    SOME OPTIONS
    Pages
    LOG IN
    .flyout .button {
    color: white;
    }

    View full-size slide

  27. CoolCorp MENU
    SOME OPTIONS
    Pages
    LOG IN
    .button {
    color: white
    !important;
    }

    View full-size slide

  28. CoolCorp MENU
    SOME OPTIONS
    Pages
    LOG IN
    .header .flyout
    .button {
    color: white;
    }

    View full-size slide

  29. CoolCorp MENU
    BUTTON BUTTON BUTTON BUTTON
    BUTTON BUTTON BUTTON BUTTON
    BUTTON BUTTON BUTTON
    BUTTON

    View full-size slide

  30. SOURCE
    ORDER

    WOES

    View full-size slide

  31. CoolCorp MENU
    SOME OPTIONS
    Pages
    .header a {
    color: white;
    }
    .flyout a {
    color: orange;
    }
    LOG IN

    View full-size slide

  32. CoolCorp MENU
    SOME OPTIONS
    Pages
    .flyout a {
    color: orange;
    }
    .header a {
    color: white;
    }
    LOG IN

    View full-size slide

  33. NAMING
    COLLISIONS

    View full-size slide

  34. It’s all globular

    View full-size slide

  35. Just give me
    my fix!

    View full-size slide

  36. .product-page
    .sidebar
    .btn {…}

    View full-size slide

  37. DEAD
    CODE
    FOREVER

    View full-size slide

  38. IMPOSSIBLE
    TO CHANGE

    View full-size slide

  39. Let’s have a
    show of hands

    View full-size slide

  40. ✴ Specificity
    ✴ Source Order
    ✴ Naming
    ✴ Dead Code
    ✴ Modification

    View full-size slide

  41. BEM
    SMACSS
    OOCSS
    UNCSS
    IMMUTABLE STYLES
    ???

    View full-size slide

  42. A challenger
    appears…

    View full-size slide

  43. aficionado:
    one with afición

    View full-size slide

  44. Components
    all the way down

    View full-size slide



  45. Hey!

    Content!


    View full-size slide

  46. A
    BETTER
    TOMORROW

    View full-size slide

  47. AN
    INTERESTING
    STORY

    View full-size slide

  48. Christopher “vjeux” Chedeau
    React: CSS in JS

    View full-size slide

  49. Plan
    • Problems with CSS at scale
    1. Global Namespace
    2. Dependencies
    3. Dead Code Elimination
    4. Minification
    5. Sharing Constants
    6. Non-deterministic Resolution
    7. Isolation

    View full-size slide

  50. ✴ Specificity
    ✴ Source Order
    ✴ Naming
    ✴ Dead Code
    ✴ Modification
    1. Global Namespace
    2. Dependencies
    3. Dead Code Elimination
    4. Minification
    5. Sharing Constants
    6. Non-deterministic Resolution
    7. Isolation

    View full-size slide

  51. JS Everything!

    View full-size slide

  52. COLIN HAS
    A QUESTION
    @colinmegill

    View full-size slide

  53. Have you seen this talk?
    It’s pretty cool! I don’t
    know how practical it is.
    So, what’s missing?

    View full-size slide

  54. WE CALLED IT
    RADIUM

    View full-size slide

  55. So how does it
    work, then?

    View full-size slide

  56. var styles = {
    color: "#333"
    }

    View full-size slide

  57. No Selectors,
    No Semicolons,
    No Mercy

    View full-size slide

  58. REGISTER
    styles = {
    background: "green",
    padding: "1rem"
    }

    View full-size slide

  59. REGISTER
    Register

    View full-size slide

  60. NO
    SPECIFICITY

    View full-size slide

  61. SOURCE ORDER
    INDEPENDENCE

    View full-size slide

  62. ONE LESS HARD PROBLEM
    NAMING

    View full-size slide

  63. DEAD CODE
    ELIMINATION

    View full-size slide

  64. MODIFY
    AND MAINTAIN

    View full-size slide

  65. ✴ Specificity
    ✴ Source Order
    ✴ Naming
    ✴ Dead Code
    ✴ Modification

    View full-size slide

  66. Back to Radium

    View full-size slide

  67. styles = {
    color: "green",
    ":hover": {
    color: "blue"
    }
    }
    BROWSER
    STATES

    View full-size slide

  68. BROWSER
    STATES
    onMouseEnter() {
    this.setState({
    hover: true
    });
    }

    View full-size slide

  69. MEDIA
    QUERIES
    styles = {
    width: 50%,
    "@media (min-width: 600px)": {
    width: 75%
    }
    }

    View full-size slide

  70. MEDIA
    QUERIES
    var mql = window.matchMedia(
    "min-width: 600px"
    );
    mql.addListener(updateMediaState);

    View full-size slide

  71. style={[
    styles.base,
    styles[this.props.kind],
    this.props.block && styles.block
    ]}
    STYLE
    ARRAYS

    View full-size slide

  72. class="btn btn-primary btn-block"
    STYLE
    ARRAYS

    View full-size slide

  73. Let’s make a
    button

    View full-size slide

  74. BUTTON TIME
    styles = {
    background: "green",
    display: "block",
    padding: "1rem"
    }

    View full-size slide

  75. BUTTON TIME
    ":hover": {
    background: "blue"
    }

    View full-size slide

  76. BUTTON TIME
    "@media (min-width: 400px)": {
    display: "inline-block"
    }

    View full-size slide

  77. BUTTON TIME
    style={[
    styles.base,
    styles[this.props.kind],
    this.props.block && styles.block
    ]}

    View full-size slide

  78. BUTTON TIME
    kind="inverse"
    block
    >

    View full-size slide

  79. So, what’s the
    problem?

    View full-size slide

  80. Don’t panic

    View full-size slide

  81. Virtual—
    what now?

    View full-size slide

  82. DIFFING

    flyout-active

    One
    Two
    Three

    Three

    View full-size slide

  83. DIFFING

    color: white;
    color: black;

    View full-size slide

  84. STRANGE
    EXPERIMENTS
    IN USERLAND!

    View full-size slide

  85. // blog-post.css
    .title { font-size: 2rem; }
    // blog-post.js
    var styles = require("./blog-post.css");

    // Rendered HTML

    View full-size slide

  86. ✴ Specificity
    ✴ Source Order
    ✴ Naming
    ✴ Dead Code
    ✴ Modification

    View full-size slide

  87. CSS MODULE
    COMPOSITION

    View full-size slide

  88. // blog-post.css
    .normal { font-size: 2rem; }
    .highlight {
    composes: normal;
    color: orange;
    }
    // blog-post.js
    var styles = require("./blog-post.css");

    // Rendered HTML

    View full-size slide

  89. .btn,
    .btn-primary,
    .btn-secondary,
    .btn-tertiary,
    .btn-inverse,
    .sidebar-btn,
    .sidebar-btn-primary,
    .sidebar-btn-secondary,
    .sidebar-btn-tertiary,
    .sidebar-btn-inverse {
    color: #333;
    }

    View full-size slide

  90. .btn { color: #333; }
    .btn-primary { /* other styles */ }
    .sidebar-btn { /* other styles */ }

    View full-size slide

  91. TOOLS, NOT RULES
    - SOMEONE

    View full-size slide

  92. BETTER UX
    BETTER DX
    =

    View full-size slide

  93. I PLEDGE
    ALLEGIANCE
    TO THE SPEC

    View full-size slide

  94. WEB
    COMPONENTS

    View full-size slide

  95. button {
    background: blue;
    font-family: Chaparral;
    }
    Normal DOM
    Normal DOM

    View full-size slide


  96. <br/>button {<br/>background: orange;<br/>font-family: Verlag;<br/>}<br/>
    Shadow DOM!

    Normal DOM
    SHADOW DOM!

    View full-size slide

  97. @philwalton
    GO SEE PHIL

    View full-size slide

  98. RUNTIME
    VARIABLES

    View full-size slide

  99. CUSTOM
    PROPERTIES
    :root {
    --bg-color: green;
    }
    .btn{
    background-color: var(--bg-color);
    }

    View full-size slide

  100. @custom-media --medium (min-width: 30em);
    @media(--medium) {
    width: 50%;
    }
    CUSTOM
    MEDIA QUERIES

    View full-size slide

  101. @custom-selector :--button button, .btn;
    :--button:hover {
    background-color: var(--hover-color);
    }
    CUSTOM
    SELECTORS

    View full-size slide

  102. .btn {
    padding: 1rem;
    }
    .btn-primary {
    @extend .btn;
    background-color: orange;
    }

    View full-size slide

  103. .modal { /* modal styles */ }
    .panel { /* panel styles */ }
    @media (max-width: 599px) {
    .options { @extend .panel; }
    }
    @media (min-width: 600px) {
    .options { @extend .modal; }
    }

    View full-size slide

  104. FINE

    - SOMEONE
    CSS IS

    View full-size slide

  105. YOU JUST
    HAVE TO…

    View full-size slide

  106. LET’S MAKE CSS
    EASY

    View full-size slide

  107. @alexlande
    Thanks!

    View full-size slide