Question

I'm working on a large JavaScript-heavy app. Several pieces of JavaScript have some related CSS rules. Our current practice is for each JavaScript file to have an optional related CSS file, like so:

MyComponent.js  // Adds CSS class "my-comp" to div
MyComponent.css // Defines .my-comp { color: green }

This way I know that all CSS related to MyComponent.js will be in MyComponent.css.

But the thing is, I all too often have very little CSS in those files. And all too often I feel that it's too much effort to create a whole file to just contain few lines of CSS - it would be easier to just hardcode the styles inside JavaScript. But this would be the path to the dark side...

Lately I've been thinking of embedding the CSS directly inside JavaScript - so it could still be extracted in the build process and merged into one large CSS file. This way I wouldn't have to create a new file for every little CSS-piece. Additionally when I move/rename/delete the JavaScript file I don't have to additionally move/rename/delete the CSS file.

But how to embed CSS inside JavaScript? In most other languages I would just use string, but JavaScript has some issues with multiline strings. The following looks IMHO quite ugly:

Page.addCSS("\
  .my-comp > p {\
    font-weight: bold;\
    color: green;\
  }\
");

What other practices have you for keeping your JavaScript and CSS in sync?

No correct solution

OTHER TIPS

My perspective on CSS files is that they describe rules that define the theme of an application. Best practices generally state that content, presentation, and behavior should be kept separate so that it is relatively easy to change that theme. By having multiple CSS files, this becomes slightly more difficult, as a designer would have more files to deal with.

Additionally, CSS (Cascading StyleSheets) rules are affected by their position in the CSS document. By having multiple CSS files with different rules in each, it may become more difficult to prioritize which rules take precedence.

Finally, if you want to find out what CSS selector in your JS file matches what CSS file, try using a cool search tool, like grep, if you're on linux. If you're using a good IDE, you can also use it to quickly search for the rules, then you can just jump to the line number. I really see no advantage in keeping the CSS rules in different files; it will only complicate matters.

Additionally, I would advise against the idea of putting the CSS inline. By doing this, you will inevitably make it more difficult for your web designer to quickly and easily swap out the styles. The whole point of external CSS is so your web designer can change the theme or provide multiple themes for different users. If you embed the CSS in the JavaScript or HTML, you've then tightly coupled the content, behavior, and presentation.

Best practices generally suggest keeping content, behavior, and presentation separate for this very purpose.

Having one CSS file per JS file seems a good thing for me. It's clean, and easy to understand and to maintain. The only problem would be to have dozens of CSS files on every page, but I suppose you combine those files to one big file, so this problem does not exist in your case.

How to embed CSS in JavaScript? It depends on the environment you have, and how the build process is done. The easiest thing is to have a large comment at the beginning of every JavaScript file, something like this:

// <...>Your copyright notice here</...>

// <css>
/*
body{color:red;}
div{border:solid 10px lime;}
// ... other ugly styles.
*/
// </css>

Then during the build, you have to search for <css>...</css> blocks and extract the CSS by trimming the /* and */.

Of course, it creates a problem: if you are using an IDE with auto-completion, embedding CSS into a JavaScript file will make it impossible to use auto-completion in this case.

My preferred method is to keep all the CSS files separate and then have a build process that compiles them into a larger CSS file on deployment.

I would avoid merging your JS with your CSS. It may sound like a cleaner solution from the file-level, I think it'll get messy fast. That, and you'll lose the highlighting and syntax assistance your editor gives you.

Check out Csster. I wrote it to solve just this problem.

You embed your CSS rules directly in your Javascript, using Javascript object literal syntax. It's no uglier than raw CSS.

Csster.style({
  h1: {
    fontSize: 18,
    color: 'red'
  }
});

The rules are inserted into the DOM on the client side. This architecture simplifies your build process and reduces client requests.

You can use it like you describe, but Csster also provides a couple other niceties:

  • nesting to DRY up stylesheets
  • color functions like darken and saturate
  • built-in macros for common CSS idioms like clearfix, rounded corners, drop shadows.
  • extension points for custom behavior or cross-browser support

It's well tested and I've used it on quite a few projects. It is independent of jQuery, but plays well with it.

I'd love to have more people use it and provide feedback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top