5

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?

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

8 Comments

You point on theming is a valid one I hadn't much thought about. Although we currently have no theming, I wouldn't rule it out for the future - at least for the color scheme. But I still would consider most of our CSS structural, not really subject for theming. But as I sayd - you are raising a valid point.
As for the cascading nature of CSS - I try to mostly rely on the specificity of selectors, not on the order of them.
But I'm definitely not going to place all CSS back to just one or few files. We already did it that way in the beginning and it was a maintenance nightmare.
@Rene - Can you describe what made it so hard to maintain? In my experience, the opposite is true. I had to re-theme one of our applications and it tool forever because I had to go through several files. In many cases, rules were duplicated, so it was more busy work as I made similar modifications over and over again. Tt felt more like busy-work than application engineering. In this case, time would have been saved if I wasn't constantly changing the same colors over and over again. I am curious to hear your experiences with having CSS in less files.
I think it's a tradeoff between JavaScript and CSS side of the app. For theming you would like to have all CSS as separated from JavaScript as possible. For maintaining JavaScript you would like to have CSS as close to the JavaScript code that references it as possible. In our case I think the JavaScript side is more important - we are really JavaScript heavy and quite low on CSS.
|
2

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.

2 Comments

Comments look like a great solution for embedding. For small bits of CSS I guess trading away syntax highlighting etc is worth it.
This also gave me an idea for implementing heredoc-style strings in JavaScript: (function(){/* Your multiline text here */}).toString()
1

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.

Comments

1

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.

2 Comments

This looks interesting. Have to try it out. I see some downsides like not being able to simply copy-paste the styles between CSS file and JavaScipt. Also there doesn't seem to be a way to automatically extract the CSS rules from JavaScript code.
Thanks. I'll improve the docs. No, there's no easy way to paste in existing CSS rules... I run some regular expressions and it doesn't take long-- but I could provide a tool for this if you want... As far as "extract" (going the other way), I was going to implement this, but after using it the first time, I realized it is really easy to do this with Firebug. There's also an extension point where you get this info within Javascript. Thanks. Let me know how it goes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.