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

Dealing with CSS universally

Simon Vocella
April 20, 2018
170

Dealing with CSS universally

Simon Vocella

April 20, 2018
Tweet

Transcript

  1. Dealing with CSS universally
    1

    View Slide

  2. Hi, I'm Simon
    @simonvocella
    https://github.com/voxsim
    2

    View Slide

  3. One day..
    npx create-react-app my-app
    cd my-app
    npm start
    3

    View Slide

  4. import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    class App extends Component {
    render() {
    return (



    Welcome to React


    To get started, edit src/App.js and save to reload.


    );
    }
    }
    export default App;
    App.js
    4

    View Slide

  5. .App {
    text-align: center;
    }
    .App-logo {
    height: 80px;
    }
    .App-header {
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    }
    .App-title {
    font-size: 1.5em;
    }
    .App-intro {
    font-size: large;
    }
    App.css
    5

    View Slide

  6. 6

    View Slide

  7. 7

    View Slide

  8. 8

    View Slide

  9. React Native for Web implements the React Native style API
    in a way that avoids all the problems with CSS at scale:
    https://github.com/necolas/react-native-web/blob/master/website/guides/style.md
    https://speakerdeck.com/vjeux/react-css-in-js
    No code minification.
    No sharing of constants.
    Non-deterministic resolution.
    No isolation.
    No local variables.
    Implicit dependencies.
    No dead code elimination.
    9

    View Slide

  10. 10

    View Slide

  11. 11

    View Slide

  12. yarn add styled-components
    12

    View Slide

  13. import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    import styled from "styled-components";
    const AppHeader = styled.div`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    `;
    App.js
    13

    View Slide

  14. class App extends Component {
    render() {
    return (



    Welcome to React


    To get started, edit src/App.js and save to reload.


    );
    }
    }
    export default App1;
    App.js
    14

    View Slide

  15. import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    import styled from "styled-components";
    const AppHeader = styled.div`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    `;
    const Logo = styled.img`
    height: 80px;
    `;
    const AppIntro = styled.p`
    font-size: large;
    `;
    ...
    App.js
    15

    View Slide

  16. class App extends Component {
    render() {
    return (



    Welcome to React


    To get started, edit src/App.js and save to reload.


    );
    }
    }
    export default App1;
    App.js
    16

    View Slide

  17. yarn add react-native-scripts
    17

    View Slide

  18. {
    "name": "css-universal-app",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
    "expo": "^26.0.0",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-native": "^0.54.2",
    "react-native-scripts": "^1.13.1",
    "react-native-svg-uri": "^1.2.3",
    "react-scripts": "1.1.4",
    "styled-components": "^3.2.5"
    },
    "main": "./src/App.mobile.js",
    "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "ios": "react-native-scripts ios"
    }
    }
    package.json
    18

    View Slide

  19. import React, { Component } from 'react';
    import logo from './logo.svg';
    import styled from "styled-components";
    import { Text, View, Image } from "react-native";
    const AppHeader = styled.Viewdiv`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    `;
    const Logo = styled.Imageimg`
    height: 80px;
    `;
    const AppIntro = styled.Textp`
    font-size: 18pxlarge;
    `;
    ...
    App.mobile.js
    19

    View Slide

  20. It works
    but
    it still sucks..
    20

    View Slide

  21. App.mobile.js
    App.web.js
    21

    View Slide

  22. App.web.js App.mobile.js
    22

    View Slide

  23. const makeApp = () => {
    const AppHeader = styled('div')`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    `;
    const Logo = styled('img')`
    height: 80px;
    `;
    const AppIntro = styled('p')`
    font-size: 18px;
    `;
    ...
    return class App extends Component {
    ...
    }
    App.core.js
    23

    View Slide

  24. import App from './App.core';
    export default App();
    App.web.js
    24

    View Slide

  25. const makeApp = (platformComponent) => {
    const AppHeader = styled(platformComponent('div'))`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    `;
    const Logo = styled(platformComponent('img'))`
    height: 80px;
    `;
    const AppIntro = styled(platformComponent('p'))`
    font-size: 18px;
    `;
    ...
    return class App extends Component {
    ...
    }
    App.core.js
    25

    View Slide

  26. import App from './App.core';
    const webComponent = component => component;
    export default App(webComponent);
    App.web.js
    26

    View Slide

  27. App.mobile.js
    import Expo from 'expo';
    import App from './App.core';
    import React from 'react';
    import {View, Text} from 'react-native';
    import SvgUri from 'react-native-svg-uri';
    if (process.env.NODE_ENV === 'development') {
    Expo.KeepAwake.activate();
    }
    const mobileComponent = (component) => {
    const reactToReactNative = {
    'div': View,
    'p': Text,
    'img': ({src, alt}) =>
    };
    return reactToReactNative[component];
    }
    Expo.registerRootComponent(App(mobileComponent));
    27

    View Slide

  28. 28

    View Slide

  29. 29

    View Slide

  30. const makeApp = () => {
    const AppHeader = styled('div')`
    background-color: #222;
    height: 150px;
    padding: 20px;
    color: white;
    align-items: center;
    justify-content: center;
    flex: 1;
    `;
    const Logo = styled('img')`
    height: 80px;
    `;
    ...
    const Title = styled('p')`
    font-size: 18px;
    color: white;
    `;
    ...
    return class App extends Component {
    ...
    }
    App.core.js
    30

    View Slide

  31. 31

    View Slide

  32. 32

    View Slide

  33. https://github.com/voxsim/css-universal-
    app
    33

    View Slide

  34. @simonvocella
    https://github.com/voxsim
    34

    View Slide

  35. Thank you
    35

    View Slide