![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6605799/WildWestLandscape-01.jpg)
Scripting in Style
What's your Vue?
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Who?
![](https://cdn.freebiesupply.com/logos/large/2x/medium-m-logo-png-transparent.png)
Senior FED
![](https://res.cloudinary.com/mayashavin/image/upload/c_fill,h_245,r_20,w_245/f_gif/c_thumb,ar_1:1,g_auto,r_max,w_200,e_blur:50,l_IMG_0046/fl_layer_apply,o_85/v1562191891/CSSinJS/sailormoonTrans.jpg)
![](https://pbs.twimg.com/profile_images/1085999117367676929/r0SmDsBp.jpg)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562192610/CSSinJS/logo.png)
![](https://res.cloudinary.com/mayashavin/image/upload/c_fill,h_245,r_20,w_245/f_gif/c_thumb,ar_1:1,g_auto,r_max,w_200,e_blur:50,l_IMG_0046/fl_layer_apply,o_85/v1562191891/CSSinJS/sailormoonTrans.jpg)
Back to the past (1991)
![](https://res.cloudinary.com/mayashavin/image/upload/v1560777376/CSSinJS/screengrab_css-violaWWW_sk3dwf.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
1995
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561924500/CSSinJS/illustration-web-design_53876-5835.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925029/CSSinJS/images.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6320270/Screen_Shot_2019-07-02_at_16.52.43.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
2002
2005
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561924500/CSSinJS/illustration-web-design_53876-5835.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1561998560/CSSinJS/jquery-logo-png-jquery-320.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561924500/CSSinJS/illustration-web-design_53876-5835.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925029/CSSinJS/images.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1561997534/CSSinJS/1280px-AJAX_logo_by_gengns.svg.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_white_bg/cloudinary_logo_for_white_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
2011
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6314368/iconfinder_HTML_Logo_65687.png)
![](https://res.cloudinary.com/mayashavin/image/upload/r_15/v1561999551/CSSinJS/es6.png)
2010
2014
![](https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Backbone.js_logo.svg/2880px-Backbone.js_logo.svg.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562000366/CSSinJS/React_logo_wordmark.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6314368/iconfinder_HTML_Logo_65687.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562000640/CSSinJS/1_MBB1xH8MOSL2qiHqwq7LGg.png)
2008
![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Sass_Logo_Color.svg/2000px-Sass_Logo_Color.svg.png)
2015
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_white_bg/cloudinary_logo_for_white_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
2010
2014
2002
1991
1995
2005
2008
2011
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561924500/CSSinJS/illustration-web-design_53876-5835.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561924500/CSSinJS/illustration-web-design_53876-5835.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925029/CSSinJS/images.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925029/CSSinJS/images.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1561998560/CSSinJS/jquery-logo-png-jquery-320.png)
![](https://res.cloudinary.com/mayashavin/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,b_transparent/v1561925314/CSSinJS/css-logo-300x300.png)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Sass_Logo_Color.svg/2000px-Sass_Logo_Color.svg.png)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Backbone.js_logo.svg/2880px-Backbone.js_logo.svg.png)
![](https://res.cloudinary.com/mayashavin/image/upload/r_15/v1561999551/CSSinJS/es6.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562000366/CSSinJS/React_logo_wordmark.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6314368/iconfinder_HTML_Logo_65687.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562000640/CSSinJS/1_MBB1xH8MOSL2qiHqwq7LGg.png)
2015
![](https://res.cloudinary.com/mayashavin/image/upload/v1561997534/CSSinJS/1280px-AJAX_logo_by_gengns.svg.png)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Boostrap_logo.svg/440px-Boostrap_logo.svg.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_white_bg/cloudinary_logo_for_white_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
2017
Component
CSS/SCSS
![](https://cdn4.iconfinder.com/data/icons/logos-3/600/React.js_logo-512.png)
CSS-in-JS
CSS/SCSS
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
CSS Modules
Scoped CSS
Component
CSS/SCSS
2018
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_white_bg/cloudinary_logo_for_white_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6608411/Screen_Shot_2019-10-02_at_20.49.47.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
The Fear
...of CSS
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
CSS is awesome
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6320080/Screen_Shot_2019-07-02_at_15.57.10.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6320083/Screen_Shot_2019-07-02_at_15.58.25.png)
BUT
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Scaling
Global namespace
Implicit dependencies
Code Maintenance (DEAD code)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562077276/CSSinJS/chris-evans-arrives-at-the-los-angeles-premiere-of-captain-america-the-winter-soldier-held-at-the-el-capitan-theatre-on-march-13-2014-in-hollywood-california-photo-by-michael-tran_filmmagicjpg-square.jpg)
![](https://res.cloudinary.com/mayashavin/image/upload/w_400,h_400,c_thumb,g_auto/v1562077275/CSSinJS/25-Chris-Hemsworth.w330.h412.jpg)
![](https://res.cloudinary.com/mayashavin/image/upload/w_400,h_400,c_thumb/v1562077274/CSSinJS/MV5BMTM4OTQ4NTU3NV5BMl5BanBnXkFtZTcwNjEwNDU0OQ_._V1_.jpg)
Chris
Chris
Chris
/* style.css */
.chris {
color:'blue';
}
/* style.css */
.chris {
color:'gold';
}
/* style.css */
.chris {
color:'green';
}
<div class="my-awesome-container">
<button class="chris">
Chris!
</button>
</div>
Chris!
😰
!important
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Scaling
Minification
Sharing constants
Non deterministic order of source
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
The (not) old style
OOCSS & SMACSS
BEM
CSS processors
NOT pure CSS
HARD to migrate
NAMING !
STILL GLOBAL
STILL NOT scalable
(that HUGE CSS file!)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Scoped SS
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Component.vue
JS
Scoped CSS
/*Item.vue*/
<template>
<div class="item__container_card item__container">
<img :src="src" width="200">
<h3 class="title">{{title}}</h3>
</div>
</template>
<script>
export default { //...code }
</script>
<style scoped lang="scss">
.item__container {
/* ..stylings */
&_card {
margin-right: 10px;
margin-bottom: 10px;
width: 220px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
}
.title {
color: #842803;
margin: 0;
padding: 0.8rem 0;
border-top: 1px solid lightgray;
}
</style>
HTML
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6612276/Screen_Shot_2019-10-03_at_15.32.24.png)
/*App.vue*/
<template>
<div id="app">
<h1 class="title">The Pokemons</h1>
<item v-bind="pokemon"/>
</div>
</template>
<script>
export default { /*code */ }
</script>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6612311/Screen_Shot_2019-10-03_at_15.40.33.png)
/*App.vue*/
<template>
<div id="app">
<h1 class="title">The Pokemons</h1>
<item v-bind="pokemon"/>
</div>
</template>
<script>
export default { /*code */ }
</script>
<style>
.title {
color: #111;
}
</style>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6612376/Screen_Shot_2019-10-03_at_15.50.36.png)
/*App.vue*/
<template>
<div id="app" class="app">
<h1 class="title">The Pokemons</h1>
<item v-bind="pokemon"/>
</div>
</template>
<script>
export default { /*code */ }
</script>
<style>
.app .title {
color: #111;
}
</style>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6612396/Screen_Shot_2019-10-03_at_15.52.46.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Full CSS support
Pre-processor support
Reusable CSS
Random class generator
/*Item.vue*/
<style lang="scss">
//...
</style>
/* OR */
<style lang="less">
//...
</style>
/* Item.vue */
<template>
//...
<h3 class="title">{{title}}</h3>
//...
</template>
<style scoped>
.title {
//...
}
</style>
/* will be compiled to */
<head>
<style>
.title[data-v-6b294924] {
//...
}
</style>
</head>
<body>
/*...*/
<h3 class="title" data-v-6b294924>
/*...*/
</body>
Scoped
Global Extendable
.app .title >>> title[data-v-6b294924]
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Real-time CSS modifiers ?
var()
😍
![](https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Internet_Explorer-512.png)
😱
JavaScript
😰 Performance
😰 Complexity
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
CSS has fundamental flaws at scale that can be solved by writing styles in JS .
@VJEUX — NOVEMBER 2014
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
SS-in-JS
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Ideal concepts
Scoped CSS
Extendable
Full CSS support
SSR (Static CSS extraction)
Debuggable
Syntax highlighting
Free of dead CSS code
Themes
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562188495/CSSinJS/css-modules-logo.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562188495/CSSinJS/css-modules-logo.png)
2015
![](https://res.cloudinary.com/mayashavin/image/upload/v1552918920/VueJS/logo.png)
![](https://cdn4.iconfinder.com/data/icons/logos-3/600/React.js_logo-512.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
<template>
<div class="item__container_card item__container">
<img :src="src">
<h3 class="title">{{title}}</h3>
</div>
</template>
// Will become
<template>
<div :class="[this.item.container, this.item.container_card]">
<img :src="src">
<h3 :class="description.title">{{title}}</h3>
</div>
</template>
<style scoped lang="scss">
.item__container {
/*...*/
}
.title {
/*...*/
}
</style>
//Will become
<style module="item" lang="scss">
.container {
/* Same as before */
}
</style>
<style module="description">
.title {
/* Same as before */
</style>
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
/*App.vue*/
//...
<style module="theme" lang="scss">
$primary-color: #B4DC47;
$light-orange: #fc9e2d;
$purple: rgb(76, 76, 111);
$dark-purple: #111;
$pink: pink;
:export {
colors: {
default: $primary-color;
lightorange: $light-orange;
purple: $purple;
darkpurple: $dark-purple;
pink: $pink;
}
}
</style>
/*App.vue*/
<script>
//...
provide() {
const theme = {};
Object.defineProperty(theme, "defaultColor", {
enumerable: true,
get: () => this.currentThemeColor
});
return {
theme: theme,
};
},
data() {
return {
colors: this.theme,
currentThemeColor: this.theme.default
};
}
//...
</script>
Theming
/*Layout.vue*/
<template>
<div class="layout__container"
:style="{ background: theme.defaultColor}">
/*...*/
<h4>Current Theme: {{theme.defaultColor}}</h4>
/*...*/
</div>
</template>
<script>
export default {
/*...*/
inject: ["theme"],
/*...*/
}
</script>
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
All SCOPED CSS Benefits
Theming
Dynamic modifiers
<div
:class="[this.item.container]">
//...
</div>
//Will become
<div
class="_src_components_ModuledItem__container">
//...
</div>
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
BUT
CSS in JS
not really
It's still
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
NOT Full extendable CSS in global scope
NO EASY way for theming
NAMING (not name collisions)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
THE CSS-in-JS
![](https://res.cloudinary.com/mayashavin/image/upload/v1562253405/CSSinJS/styled_components.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614063/Screen_Shot_2019-10-03_at_23.41.39.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614062/Screen_Shot_2019-10-03_at_23.41.50.png)
The challenge
List-view
Grid-view
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614060/Screen_Shot_2019-10-03_at_23.42.23.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614061/Screen_Shot_2019-10-03_at_23.42.13.png)
+
Themes
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
/*App.vue*/
<script>
const colors = {
default: "#fff",
lightorange: "#fc9e2d",
purple: "rgb(76, 76, 111)",
darkpurple: "#111",
pink: "pink"
};
export default {
name: "App",
components: {
Layout
},
provide() { /*....*/ },
/*...*/
data() {
return {
colors: colors,
currentThemeColor: colors.default
};
}
};
</script>
/*Item.vue*/
<script>
import yiq from "yiq";
import { darken } from "polished";
import styled, { css } from "vue-styled-components";
const itemProps = {
isGrid: Boolean,
themeColor: String
};
const TitleRowStyle = css`/*...*/`;
const StyledItemTitle = styled("h3", itemProps)`
color: ${props => yiq(props.themeColor)};
/*...*/
${props => (props.isGrid ? null : TitleRowStyle)}
`;
const Card = css`/*...*/`;
const Row = css`/*...*/`;
const StyledItem = styled("div", itemProps)`
/*...*/
background: ${props => props.themeColor};
${props => (props.isGrid ? Card : Row)}
&:hover {
background-color: ${props => darken(0.05, props.themeColor)};
cursor: pointer;
}
`;
export default {
inject: ["viewMode", "theme"],
components: { StyledItem, StyledItemTitle },
/*...*/
};
</script>
/*Item.vue*/
<template>
<styled-item
:is-grid="viewMode.isGrid"
:theme-color="theme.defaultColor">
<img :src="src">
<styled-item-title
:is-grid="viewMode.isGrid"
:theme-color="theme.defaultColor">
{{title}}
</styled-item-title>
</styled-item>
</template>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614249/Screen_Recording_2019-10-04_at_0.10.24__1_.gif)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
The GOOD
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
EASY to theme
NO Dead code
Run-time modifier
Extendable
Scoped (100%)
/* ExtendedItem.vue */
import styled from "styled-components";
import Item from './Item'
const ExtendedItem = Item.extend`
background: "blue";
border-color: "blue";
`;
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6336038/Screen_Shot_2019-07-07_at_13.47.42.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6336266/Screen_Shot_2019-07-07_at_16.00.04.png)
NO more CSS file!
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
It's awesome!
Or is it really ? 😏
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
The NOT so good
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
JS
CSS
Parse CSS
Inject to Stylesheet
stylesheet.insertRule
Browser
HTML Paint
load
😮 Accessibility?
NO Cache
download
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1562823328/CSSinJS/C-4KxZbXkAA7NOP.jpg)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6336334/Screen_Shot_2019-07-07_at_16.28.51.png)
Box
/* Box.vue */
<template>
<styled-box :size="size"/>
</template>
<script>
import styled from "vue-styled-components";
const boxProps = {
size: String
};
const StyledBox = styled("div", boxProps)`
width: ${props => props.size}px;
height: ${props => props.size}px;
background: grey;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
`;
export default {
components: { StyledBox },
props: boxProps
};
</script>
Input size of box
Interactive Comp
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6336928/InteractiveBox.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6614225/2019-10-04_01-11-56.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
🤯
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
How about
Security?
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Security?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6338549/Screen_Shot_2019-07-08_at_12.43.18.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6338550/Screen_Shot_2019-07-08_at_12.41.10.png)
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
CSS-in-JS means
It's still CSS! (not JS)
Learning CSS is still required! 😆
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Should we use CSS-in-JS?
Yes, but with caution
So
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Easy to theme
NO Dead code
Extendable
Scoped
Styles on run time
Security
Portability
Context switch
Messy code
CSS-in-JS
The Good
The Bad
The Ugly
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Portable
No escapsulation
Bundle size
Dead code (somewhere)
Naming
Private to JS code
Load once
No re-render
Scoped CSS
The Good
The Bad
The Ugly
Theme-able
Basic scope
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
"Use the right tool for the right job"
And naming is not a good enough reason...
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
Styled components
Scoped CSS
When?
CSS modules
CSS consistency between projects
Simple and isolated component
Medium size apps / third-party libs
Security is a concern
Full control over component styling
Theme is critical (IE included)
Support dynamic styling via props
Complex and large apps
IE 11 is not a concern
Basic scope
NO dynamic styling via props
![](https://res.cloudinary.com/cloudinary/image/upload/c_scale,w_500/v1/logo/for_blue_bg/cloudinary_logo_for_blue_bg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/5996033/Twitter_Logo_Blue.png)
![](https://res.cloudinary.com/mayashavin/image/upload/c_fill,h_245,r_20,w_245/f_gif/c_thumb,ar_1:1,g_auto,r_max,w_200,e_blur:50,l_IMG_0046/fl_layer_apply,o_85/v1562191891/CSSinJS/sailormoonTrans.jpg)
Thank you
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6606030/WildWestLandscape-05.jpg)
Scripting in style - What's your Vue?
By Maya Shavin
Scripting in style - What's your Vue?
Code Demo: https://codesandbox.io/embed/style-with-vue-fzzci
- 2,019