cssta
v0.10.1
Published
Cssta is a styling system for [React Native 📱](https://facebook.github.io/react-native/) that lets you define components using CSS.
Downloads
92
Maintainers
Readme
🌞 Cssta
Cssta is a styling system for React Native 📱 that lets you define components using CSS.
It takes heavy inspiration from styled-components, but makes changes for readability 👀, to enable more features 🤙, and performance ⚡️.
Most notably, Cssta supports media queries, CSS animations and transitions, and CSS custom properties.
Performance-wise, Cssta compiles your CSS at compile time via a babel-plugin. Cssta is also able to perform Svelte-like stripping of its framework, and is able to build many components with no Cssta runtime.
import cssta from "cssta/native";
const BlueView = cssta(View)`
background: blue;
`;
<BlueView>I am a View with a blue background</BlueView>;
This returns a regular React component, which when used, will have the styling applied.
We have a repo with a whole bunch of examples if you want to see how it’s setup and examples of usage. It’s over on CsstaExample.
🔧 Setup
Cssta can be used with its own babel plugin, or can use babel-plugin-macros.
You can install Cssta with,
npm install --save cssta
npm install --save-dev babel-plugin-cssta
In your React Native project, you’ll find a babel.config.js
file. Edit this to read,
module.exports = {
+ plugins: ['babel-plugin-cssta'],
presets: ['module:metro-react-native-babel-preset'],
};
🎣 Babel Plugin Macros
If you want to use babel-plugin-macros, change babel-plugin-cssta
to babel-plugin-macros
. You’ll then need to import the macro version of Cssta whenever you need to use it.
-import cssta from "cssta/native"
+import cssta from "cssta/native.macro"
📝 CSS
Cssta supports all the CSS React Native supports, and has the same syntax as your browser.
font-size: 12px;
color: red;
There’s also support for short-hands.
margin: 0px 5px; /* { marginTop: 0, marginRight: 5, ... } */
font: bold italic 12px/18px "Helvetica";
And support for more complicated attributes.
shadow-offset: 10px 5px; /* { width: 10, height: 5 } */
font-variant: small-caps; /* ["small-caps"] */
transform: scale(3) rotate(30deg); /* [{ scale: 3 }, { rotate: "30deg" }] */
For more information, see css-to-react-native.
🎛 Props
We extend the attribute selector syntax in CSS. Now when your attribute name starts with an at symbol, we’ll query the React props. We call these prop selectors. You can use,
[@stringAttribute="stringValue"]
for string props[@booleanAttribute]
for boolean props
You’ll always need the &
selector when using prop selectors.
const Message = cssta(Text)`
padding: 6px 12px;
&[@large] {
padding: 12px 18px;
}
&:not([@noOutline]) {
border: 1px solid grey;
}
&[@priority="critical"] {
background-color: red;
}
&[@priority="important"] {
background-color: orange;
}
`;
<Message large>Large Button with an Outline</Message>;
<Message noOutline>Button with no Outline</Message>;
<Message priority="critical">Red Button with an Outline</Message>;
<Message priority="important">Orange Button with an Outline</Message>;
<Message large noOutline priority="critical">
Large, Red Button with no Outline
</Message>;
All properties defined in prop selectors are not passed down to the component—they’re really only for styling. All other props get passed down.
const Button = cssta(View)`
&[@large] {
padding: 12px;
}
`;
<Button large onClick={() => alert("clicked")}>
onClick Prop Passed Down
</Button>;
💗 Composition
You can style any React Native component that takes style
as a prop—that’s most of them!
import { Link } from "react-router-native";
const StyledLink = cssta(Link)`
color: rebeccapurple;
`;
It is also possible to compose your own components.
const OutlineView = cssta(View)`
padding: 6px 12px;
border: 2px solid grey;
border-radius: 1000px;
`;
const RedOutlineView = cssta(OutlineView)`
background-color: red;
`;
const BlueOutlineView = cssta(OutlineView)`
background-color: blue;
`;
You can also define mixins—these can be used in Cssta components or as a hook in regular React components.
const useStyles = cssta.mixin`
padding: 6px 12px;
border: 2px solid grey;
border-radius: 1000px;
`;
const RedOutlineView = cssta(View)`
@include ${useStyles};
background-color: red;
`;
const BlueOutlineView = () => {
const styles = useStyles();
return <View style={[styles, { backgroundColor: "blue" }]} />;
};
See in the mixins section.
🖌 Overriding Styles
Setting style
on Cssta components will override those already defined by the component.
Be careful setting styles margin
, as Cssta always sets the most specific styles possible (i.e. marginTop
etc.)
<Button style={{ marginRight: 0 }}>
Composing Styles
</Button>
🖥 Media Queries
These work just as they do in CSS. We support min-
and max-
width
and height
, as well as orientation: portrait
and orientation: landscape
. We also support a non-standard platform
, which queries whatever Platform.OS
returns,
const Title = cssta(Text)`
font-size: 12px;
@media (min-width: 600px) {
font-size: 24px;
}
`;
We also support viewport units.
const Title = cssta(View)`
width: 20vw;
`;
You can see more under media queries.
🏳️🌈 Theming
The best way to do theming in Cssta is by using CSS custom properties. Use them as in Cssta as you’d use them on the web, and they’ll just work.
const Inverted = cssta(View)`
background-color: black;
--primary: white;
`;
const ThemedText = cssta(Text)`
color: var(--primary, black);
border: 1px solid var(--primary, black);
padding: 6px 12px;
`;
<ThemedText>I black text</ThemedText>;
<Inverted>
<ThemedText>I am white text on a black background!</ThemedText>
</Inverted>;
There’s a few extra examples in theming.
✂️ Interpolation
In addition to CSS custom properties, you can use JavaScript’s ${value}
syntax to interpolate values. Note that you can only interpolate values or parts of values, and not entire rules or mixins. This is mostly useful for using platform constants.
const Component = cssta(View)`
border-bottom: ${StyleSheet.hairlineWidth}px solid grey;
`;
See the interpolation section.
🍿 Transitions and Animations
These also work just like CSS. For transitions, it’s as simple as,
const Action = cssta(View)`
opacity: 1;
transition: opacity 300ms;
[@disabled] {
opacity: 0.5;
}
`;
Animations work too—you’ll need to put the keyframes in the component though.
const ButtonWithKeyframes = cssta(Animated.View)`
animation: fade-in 1s ease-in;
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
`;
You’ll find more information in the transitions & animations section.
🤓 Refs
When using the ref
prop, it will refer to the component you are styling rather than the styled component.
const InnerRef = cssta(View)`
background: red;
`;
<InnerRef
ref={reactNativeViewElement => {
/* Code here */
}}
/>;
See the documentation for React.forwardRef
for more information.