Cut the SASS: How to Use Inline JavaScript Styles for Everything.

Andrew Davis
Capital One Tech
Published in
7 min readOct 5, 2016

Today, front end web development is about building applications, not just web pages. And while CSS and SASS were both great for styling pages, they’re not well suited for styling applications. This is especially true if you are building with a component-based strategy.

A component-based strategy is the idea of breaking your application down into small, reusable building blocks called components. Using components to build your app can bring reusability, clarity and efficiency to your front end.

To gain the full benefits from a component-based approach, we want components that fully encapsulate function, markup, and styles.

In this post we’ll explore how writing styles using inline JavaScript is a great way to support component-based development. In the end, we’ll end up with front-end components that are a single file, easily sharable, and fully self-contained.

Writing your styles in JS is a big change, so I want to take some time to explain why we’d want to do this. I believe in choosing the right tool for the right job. SASS was certainly the right tool for its time, providing some great benefits such as:

  • Nesting
  • Variables
  • Mixins

Nesting was a big benefit because it allowed your styles to reflect your markup. If you had:

You could do:

This benefit is no longer as useful. We are still very interested in having our styles mirror our markup, but our markup has changed!

Today, using a component-based approach, we prefer to separate these into two distinct components called `UserList` and `User`. The result is two files, where `UserList` would contain a repeating series of `User`.

Since we’re breaking our application down into components, we should write our styles using the same strategy. That means we should attempt to co-locate our styles with our component’s markup so that they’ll be encapsulated together.

One way to accomplish this is to use inline-styles, like the days of old before Cascading Style Sheets.

This classic method is very well aligned with a component-based approach. We won’t be using it, because it’s very limiting, but it’s demonstrates the principles we’re looking for in a modern styling solution.

Variables and Mixins

We’ve talked about SASS’ nesting, what about the other big benefits — variables and mixins?

Well, it just so happens that another quite popular solution exists for those — JavaScript!

Wouldn’t it be great if we could leverage JavaScript’s natural features for `var` and `function` to give us what we need in a styling solution? If we use JavaScript to write our styles, we gain the flexibility, power, and familiarity we love about JS. Plus! Our entire component can be composed in a single language! And even a single file!

Our Goals

Here’s what we want to do:

  • Compose our styles directly alongside markup
  • `import` and `export` variables like colors or breakpoints
  • Write “dynamic” styles based on state ( open/closed menu, etc.)

Here are a few more requirements:

  • Needs to cover pseudo states like `:hover, :before, :after`
  • Must directly support media-queries like `@media (max-width: 600px)`
  • Allow functions / ternaries (see dynamic, above)

Side note: explaining the difference between “JS styles” and “CSS in JS”

There are two distinct approaches:

  • You can include CSS in your JS
  • You can write your CSS using JS

I prefer the second method and it’s what we’ll cover here.

For the first approach, CSS Modules is a popular solution in the “write CSS in your JS” category. It scopes, or name-spaces, the regular CSS you write to a component’s `<div></div>`. Name-spacing is something you can do manually with classes or IDs, and isn’t enough reason to use something like this alone. For variable support or mixins, you need to use a CSS “enhancer” like PostCSS or SASS with CSS Modules.

Again, we want to be able to leverage JavaScript for language features including variables, ternaries, or functions. If our solution forces us to write some sort of “enhanced” CSS instead of JS, it won’t work for our needs.

There are lots of css-in-js solutions available for both approaches. Check ’em out! For now, we’re going to implement what I found works best to solve our goals and requirements.

Let’s Get Started!

We will be using:

First, we’ll create a simple component, called UserMenu. It’ll have a little user avatar, and a menu that drops down when you click it.

You can use it on your app page like:

The markup isn’t important. This is just basic React or even AngularJS with a little ES6 / stateless functional components syntax.

Let’s start styling! Begin by including Aphrodite.

Here, we’re importing the specific functions we need from Aphrodite as the docs instruct.

Note on imports: We’re importing specific references with the `import {bar} from ‘foo’ syntax`. Read more on MDN import documentation

Now we’ve written a `const styles` and use `StyleSheet.create()` with our styles object inside. This is from the Aphrodite documentation. Aphrodite injects a `<style>` tag into your document and inserts the css for `.foo` that tag. It’s properly name-spaced as well.

We’ve written `backgroundColor` instead of `background-color`. All of our CSS properties must be camelCased in JS! Like `marginLeft` or `fontSize` or `justifyContent`. It’s actually really easy to get used to, especially if you write as much JavaScript as I do!

That’s the very basics.

Now, instead of a red hex color, we want to use a branded color. We can use JavasScript variables. Let’s set up a `colors.js` file. This is the entire file:

Our color variables are all being exported from this file. We’re using `const` instead of `var`, because the values won’t be re-assigned. Now we can import the file in our component and use our colors like this:

What about the case where we need to use our JS variable in combination with a string? Like with a `border` specification? Easy. Just use ES6 template literals.

There we go. Our variable is combined with our string.

What about pseudo-classes? No problem. Aphrodite has great support for pseudo classes like `:before` and `:after`.

Simply nest the pseudo-class, but use a `string` as the key name (`:before`)! The above example will create a small circle to the left of the user’s name.

Media queries work the same way.

Now we’ve got a breakpoint going! Padding will be reduced below `600px`.

Now, what if we wanted to take it one step further and keep track of our breakpoints across the app? JavaScript!

We’ll create a separate file, write the breakpoints we want to use as strings, and assign them to variables.

Now we can import a breakpoint from our .js file and use it as a variable, just like we did with `colors.js`.

The `[isMobile]` will be interpolated into the string ‘@media (max-width: 600px)’ from our `breakpoints.js` file and work just like intended.

Let’s do our final implementation. We’re going to put it all together, including everything we’ve learned. We’ll also create a state-based style that will display the menu based on if the component is open or closed.

Note: It’s safe to ignore some of the details around receiving the `isOpen` variable from a higher level. Just assume it’s being managed elsewhere and that a click on our div toggles it from `true` to `false`.

Note 2: It’s important to understand arrow functions in order to read this code. They’re wonderful when you get used to them. They’re essentially `functions`, that immediately `return`. Arrow functions on MDN.

Here’s our final code: (You can also view a working demo on CodePen)

The major change here is that we’ve turned our styles const into a function that returns a StyleSheet.create object. It takes isOpen as an argument from the component. When isOpen changes, our menu will show and hide.

View the working demo

Conclusions

So, what have we done by using this approach? Well, we were able to encapsulate everything about a fairly complex component in a single file, and in a single language.

Because the implementation is essentially all JavaScript, you can choose how you want to construct your components. All of the patterns JavaScript will allow are available to you.

This means your styling solution can directly reflect your overall application architecture. This method allows you to have full control over your structure. You can move these pieces around and fit them together however you think makes the most human-readable and sensible configuration.

In my experience, the best method is to create many small, fully isolated components; most of which are “stateless” or “dumb” components, only receiving data from the top-down in what’s called an Immutable Application Architecture.

I prefer these components to encapsulate their markup, styles, and functionality. Maintaining or changing components becomes trivial when there is a single location and a clear dependency tree.

Because these components only have a single concern, rarely do the files become too large. If they do get too complex, you can easily abstract or refactor them into separate components.

Another benefit to inline JS styling is that locating code when making updates becomes trivial because everything you need for a component is co-located in a single file.

Components composed this way are also easy to share, as you can pass off as a single .js file. Your consumers can satisfy the `import` declarations as they see fit. There’s no reason that `import React` couldn’t become `import Angular.`

I hope I’ve demonstrated the power of inline JS styles and how they are able to replace SASS, as well as given some insight into component-based development. It’s an approach that really works for our team, hope it works for yours!

Andrew Davis has been designing and developing awesome user experiences for Capital One since 2014, and the wider web since 2001.

For more on APIs, open source, community events, and developer culture at Capital One, visit DevExchange, our one-stop developer portal. https://developer.capitalone.com/

--

--