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

Dealing with CSS universally

Avatar for Simon Vocella Simon Vocella
April 20, 2018
280

Dealing with CSS universally

Avatar for Simon Vocella

Simon Vocella

April 20, 2018
Tweet

Transcript

  1. 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
  2. .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
  3. 6

  4. 7

  5. 8

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

  8. 11

  9. 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
  10. 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
  11. 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
  12. 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
  13. { "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
  14. 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
  15. 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
  16. 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
  17. import App from './App.core'; const webComponent = component => component;

    export default App(webComponent); App.web.js 26
  18. 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
  19. 28

  20. 29

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

  23. 32