KEMBAR78
Implementing CSS support for React Native | PDF
Implementing CSS for
React Native
I’m Krister
Twitter
@kristerkari
Github
@kristerkari
Why does
React Native
need
CSS support?
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10,
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5,
},
});
StyleSheet is a
subset of CSS
const Container = styled.View`
flex: 1;
justify-content: center;
align-items: center;
background-color: #0f0;
`;
const Title = styled.Text`
font-size: 30px;
text-align: center;
color: palevioletred;
box-shadow: 1px 2px 3px red;
elevation: 6;
`;
styled-components 💅 
CSS-in-JS
libraries bring us
powerful new
tools
CSS type checking
What about all the
existing CSS? What
about Sass, Less
and PostCSS?
https://github.com/search?q=css&type=Code
Github has almost 45 million
CSS files
Cool new things are created
with CSS every day
Wouldn’t it be nice if
there would be an
easier way to use
all that CSS
in React Native?
Supporting CSS in
React Native means
that developers have
more options to
choose from
CSS modules
for Web
.container {
padding: 30px 10px;
margin-top: 65px;
align-items: center;
border: 2px dashed #f00;
}
<div className={styles.container}>Some text</div>
import styles from "./styles.css";
<style>
._20WEds96_Ee1ra54-24ePy {
padding: 30px 10px;
margin-top: 65px;
align-items: center;
border: 2px dashed #f00;
}
</style>
<div class="_20WEds96_Ee1ra54-24ePy">Some text</div>
React Native
CSS modules
What is included?
React Native specific CSS parser
Transformer to parse and live reload CSS
Babel plugins
to add className property to React Native
to add platform specific extensions for
CSS files
CSS parser is the
same one that
styled-components
is using
.container {
padding: 30px 10px;
margin-top: 65px;
align-items: center;
border: 2px dashed #f00;
}
{
container: {
paddingBottom: 30,
paddingLeft: 10,
paddingRight: 10,
paddingTop: 30,
marginTop: 65,
alignItems: "center",
borderColor: "#f00",
borderStyle: "dashed",
borderWidth: 2
}
}
↓ ↓ ↓ ↓ ↓ ↓
CSS
JS
What is a
transformer?
module.exports = {
getTransformModulePath() {
return require.resolve("./my-css-transformer.js");
},
getSourceExts() {
return ["css"];
}
}
rn-cli.config.js
Tell bundler to support
additional file extensions
Custom transformer
Transformer is just a
function that gets
called when a file is
getting bundled
module.exports.transform = function({ src, filename, options }) {
if (filename.endsWith(".css")) {
return upstreamTransformer.transform({
src: "module.exports = " + JSON.stringify(css2rn(src)),
filename,
options
});
}
return upstreamTransformer.transform({ src, filename, options });
};
my-css-transformer.js
Call to CSS parser
CSS gets parsed when
the app is bundled
There is no runtime
overhead
Choose from the
available transformers
CSS, Sass, Less, Stylus or
PostCSS
module.exports = {
getTransformModulePath() {
return require.resolve("react-native-sass-transformer");
},
getSourceExts() {
return ["scss", "sass"];
}
}
rn-cli.config.js
Babel plugins
Node {
type: 'JSXExpressionContainer',
start: 67,
end: 85,
loc:
SourceLocation {
start: Position { line: 1, column: 67 },
end: Position { line: 1, column: 85 } },
expression:
Node {
type: 'ObjectExpression',
start: 68,
end: 84,
loc: SourceLocation { start: [Position], end: [Position] },
properties: [ [Node] ] } }
Abstract Syntax Tree (AST)
AST Explorer
babel-plugin-react-native-
classname-to-style
<Text className={styles.myClass} />
<Text style={styles.myClass} />
↓ ↓ ↓ ↓ ↓ ↓
With className you
can use the same
React components
for Web and Native
React Native’s
platform specific
extensions
import styles from "./styles.css";
styles.android.css  - Android
styles.ios.css  - iOS
styles.native.css  - Android and iOS
styles.css  - Android, iOS and Web
↓
babel-plugin-react-native-
platform-specific-
extensions
import styles from "./styles.css";
import { Platform } from "react-native";
var styles = Platform.OS === "ios" ?
require("./styles.ios.css") :
require("./styles.css");
↓ ↓ ↓ ↓ ↓ ↓
CSS Media
Queries
The implementation is
based on
React Native Extended
StyleSheet
library
.container {
background-color: red;
}
@media (orientation: landscape) {
.container {
background-color: blue;
}
}
{
container: {
backgroundColor: "red"
},
"@media (orientation: landscape)": {
container: {
backgroundColor: "blue"
}
}
}
CSS JS
Media Queries require
that parts of the styles
are modified at runtime
Doing parsing at
runtime can hurt
performance, so
avoid it
.container {
background-color: red;
}
@media (orientation: landscape) {
.container {
background-color: blue;
}
}
{
__mediaQueries: {
"@media (orientation: landscape)": [{
expressions: [
{
feature: "orientation",
modifier: undefined,
value: "landscape"
}
],
inverse: false,
type: "all"
}]
},
container: {
backgroundColor: "red"
},
"@media (orientation: landscape)": {
container: {
backgroundColor: "blue"
}
}
}
CSS JS
What is actually done
at runtime?
Media Queries are
matched against React
Native’s dimensions
import { Dimensions } from "react-native";
function getMatchObject() {
const win = Dimensions.get("window");
return {
width: win.width,
height: win.height,
orientation: win.width > win.height ? "landscape" : "portrait",
"aspect-ratio": win.width / win.height,
type: "screen"
};
}
Check if a Media Query
matches current
dimensions
const isMatch = mediaQuery.match(query, matchObject);
if (isMatch) {
res = merge(res, styles[key]);
}
When a Media Query
matches, everything
inside it gets merged
with base styles
.container {
background-color: red;
font-size: 20px;
}
@media (orientation: landscape) {
.container {
background-color: blue;
}
}
{
container: {
backgroundColor: "blue",
fontSize: 20
}
}
↓ ↓ ↓ ↓ ↓ ↓
CSS
JS
new Babel plugin is
needed for Media
Queries
babel-plugin-react-native-
classname-to-dynamic-style
<Text className={styles.myClass} />
<Text style={process(styles).myClass} />
↓ ↓ ↓ ↓ ↓ ↓
To be implemented…
CLI installer
A better way to measure Media Queries
runtime performance
CSS Viewport units
And more…
Thanks!
Questions?
github.com/kristerkari/
react-native-css-modules

Implementing CSS support for React Native