Using CSS Custom Properties With Ember.js
Recently there was some hype around CSS Custom Properties landing in Google Chrome. I was using them before in some Firefox only projects and with support from Google Chrome, I'm sure I will be using them even more as there are a lot of customers who are fine with Firefox + Chrome only browser support for company internal applications.
In this post, I won't go into deep detail why custom properties are awesome and very powerful. If you never heard of custom properties or css variables before, I highly recommend reading Philipp Waltons post about CSS Custom Properties. Besides the powerful feature like cascading the properties, custom properties also enables us to specify some kind of "public API" for our CSS components.
With Ember.js there are easy ways to bind a component property to a element attribute or element class, but no easy way to bind to a custom CSS property. One possibility is to bind the style
attribute, but as more properties get involved the component gets bigger and more complicated. This is where my Ember.js addon ember-custom-css-properties comes in handy, it allows you to bind custom CSS properties just like attributes or classes.
Lets build a small progress-bar component using ember-custom-css-properties.
$ ember new example-app
$ ember install ember-custom-css-properties
$ ember generate component progress-bar
Open up app/components/progress-bar.js
:
import Component from 'ember-component'
export default Component.extend({
classNames: [ 'progress-bar' ],
cssPropertyBindings: [ 'progress' ]
})
This is all we need, when we assign something to the progress
property on our component, it will be available as --progress
in our CSS definitions for .progress-bar
and all its descendant elements.
app/styles/app.css
:
.progress-bar {
border: 1px solid black;
height: 24px;
}
.progress-bar::before {
content: '';
display: block;
background: black;
height: 100%;
/* Multiply by 1% to cast to a percentage value, this way,
* we only have to provide a numeric value for `--progress`. */
width: calc(var(--progress, 0) * 1%);
}
app/templates/application.hbs
:
{{progress-bar progress=75}}
And done! We now have a very simple progress-bar, which accepts a numeric progress
property and displays the current progress.
By default, ember-custom-css-properties will wrap any JavaScript number, CSS numeric value, the string none
and hex colors like #ff000
in a Handlebars.SafeString
as they can't introduce any CSS XSS vulnerabilities.
As an exercise, try to add a width
and height
property to the progress-bar component, similar to how the <img>
element works.
I think there are many use-cases and possibilities with this addon from quite static components like my example to complex animated components. I'm really curious what you can build with this! :)