Dealing with CSS universally

706fd8456611f27799aa0ea36eff63f3?s=47 Simon Vocella
April 20, 2018
24

Dealing with CSS universally

706fd8456611f27799aa0ea36eff63f3?s=128

Simon Vocella

April 20, 2018
Tweet

Transcript

  1. Dealing with CSS universally 1

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

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

  4. import React, { Component } from 'react'; import logo from

    './logo.svg'; import './App.css'; class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </header> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> </div> ); } } export default App; App.js 4
  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
  6. 6

  7. 7

  8. 8

  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
  10. 10

  11. 11

  12. yarn add styled-components 12

  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
  14. class App extends Component { render() { return ( <div

    className="App"> <AppHeader> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </AppHeader> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> </div> ); } } export default App1; App.js 14
  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
  16. class App extends Component { render() { return ( <AppBody

    className="App"> <AppHeader> <Logo src={logo} className="App-logo" alt="logo" /> <Title className="App-title">Welcome to React</Title> </AppHeader> <AppIntro className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </AppIntro> </AppBody> ); } } export default App1; App.js 16
  17. yarn add react-native-scripts 17

  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
  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
  20. It works but it still sucks.. 20

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

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

  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
  24. import App from './App.core'; export default App(); App.web.js 24

  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
  26. import App from './App.core'; const webComponent = component => component;

    export default App(webComponent); App.web.js 26
  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}) => <SvgUri source={src} alt={alt} width="113" height="80" /> }; return reactToReactNative[component]; } Expo.registerRootComponent(App(mobileComponent)); 27
  28. 28

  29. 29

  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
  31. 31

  32. 32

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

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

  35. Thank you 35