In this talk we will go through the main problems with CSS at scale and we will see some interesting JavaScript-based solutions, from Inline Styles to CSS Modules. Are you ready to enter the magical world of CSS in JS?
CSS in JS@MicheleBertoli
View Slide
Michele (Mee-keh-leh)Front End Developer at YPlanMember of WEBdeBSFollow me @MicheleBertoliI’ve got the CSSinJS skill on LinkedIn
MicheleBertoli/css-in-js
- Give it five minutes- Unlearn everything- ComponentsMindset
Cascading Style Sheets
Problems with CSS at scale (vjeux)- Global Namespace- Dependencies- Dead Code Elimination- Minification- Sharing Constants- Non-deterministic Resolution- Isolation
Inline Styles
const divStyle = {color: 'white',backgroundImage: `url(${imgUrl})`,WebkitTransition: 'all',msTransition: 'all',};ReactDOM.render(Hello World!,mountNode);
Pros- Recompute styles- Object literals- Application state- Testing
Cons- Pseudo classes/elements- Media queries- Style fallbacks- Animations- !important- Separation of concerns- Performance (?)
Debugging
Aphrodite
import { StyleSheet, css } from 'aphrodite';const styles = StyleSheet.create({btn: { color: 'red' }});el.innerHTML = `Yo`;
const styles = StyleSheet.create({hover: {':hover': { color: 'red' }},small: {'@media (max-width: 600px)': { color: 'red' }},});
AphroditeInline Styles that work.
Features- Pseudo selectors- Media queries- Smart style injection- Autoprefixer included
CSSX
const sheet = cssx();const button = sheet.add('.button', {color: 'red',});button.update({color: 'green',});
const sheet = cssx();sheet.add(<br/>.button {<br/>color: blue;<br/>}<br/>);
CSSXCSSX is a set of tools that will help you write vanilla CSS inJavaScript.
Benefits- Avoid additional “state” classes- No interaction with the DOM- Real dynamic CSS
CSS Modules
// button.css.common {color: red;}// button.jsimport styles from "./button.css";el.innerHTML = `Yo`;
.JoFm3I_KMlvnoKpksAd60 {color: red;}Yo;
CSS ModulesA CSS Module is a CSS file in which all class names andanimation names are scoped locally by default.
Composition.className {color: green;background: red;}.otherClassName {composes: className;color: yellow;}
Webpackmodule.exports = {module: {loaders: [{ test: /\.css$/, loader: 'style-loader!css-loader' }]}};
Bonus
@media screen and (min-width: 48em) {.f3-ns { font-size: 1.5rem; }}.f4 { font-size: 1.25rem; }.mb0 { margin-bottom: 0; }.fw6 { font-weight: 600; }Responsive
Atomic CSSThe bad parts:- Too many classes- Similar to inline styles- Hard to maintainThe good parts:- Quick prototyping- CSS file size
Atomic CSS Modules.title {composes: fw6 f4 f3-ns from './fonts.css';composes: mb0 from './margins.css';}Responsive
The End
Recap- Use the right tool, no matter if it breaks the rules- Inline styles vs local scope- Appearance vs state- Have fun :)
Any Questions?