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

Dealing with CSS universally

Simon Vocella
April 20, 2018
270

Dealing with CSS universally

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