23

Intro

I recently watched the slides from React: CSS in JS and I really like the idea of having CSS applied using JS (and with JSX, this would mean having all the HTML, JS and CSS in one file, which is just great for small, reusable components); however I'm worried about possible problems with semantic/performance/whatever, which lead me to...

The question

Why is it important to separate CSS from HTML?

Obvious reasons I can think of are avoiding duplication and keeping the HTML purely semantic while letting CSS handle the styling. I can do both in JS. Are there any other reasons I'm missing?


Edit: I missed a very important thing here - I'm designing architecture for a big web application, not some small blog thing. It will have its own build pipeline, with virtually any configuration possible.


Edit #2: I see a lot of arguments about separation of concerns, most of which are (in my understanding) based on assumption that it is more often to change just HTML or just CSS and once as opposed to editing HTML and CSS in parallel. While this might be the case for small websites, my commit history shows me the opposite - I usually edit both HTML and CSS together. So instead of separating all HTML from all CSS I would separate each component from each other.

I still don't see any serious drawback of doing this.

  • Caching? Each component file could be cached.
  • Semantics? I could still have semantic in HTML and styles in CSS, just in one file.
  • Re-use and maintainability? It will be even easier with separated components instead of a bunch of HTML and CSS files with unclear relationships.
  • MVC? I could have my mini MVC inside each component.

Edit #3: FYI all: @keithjgrant wrote a great folow-up article about this question: http://keithjgrant.com/posts/against-css-in-js.html

9
  • 5
    The canonical answer to this is csszengarden.com Jan 27, 2015 at 15:59
  • 1
    1. Re-use. 2. Single-update point (not spanned across HTML files). 3. Caching Jan 27, 2015 at 16:01
  • If you have on css file, some inline style attribute, and then also do some changes using js, then will some day get to into the situation where you don't know anymore why a certain element has the current styling. Doing changes to the styling will become time intensive, often resulting in the usage of !imporant for a fast fix, which would make everything even worse ...
    – t.niese
    Jan 27, 2015 at 16:02
  • 2
    Because HTML=structure and CSS=style (and for the matter, JS=behavior).
    – Яois
    Jan 27, 2015 at 16:50
  • 3
    "my commit history shows me the opposite - I usually edit both HTML and CSS together." -- If this is the case, then you are not using best practices with your CSS. I strongly suggest you read up on OOCSS, SMACSS, and/or BEM. May 29, 2015 at 15:12

4 Answers 4

16

1. Why was it important to separate CSS from HTML?

Originally, JavaScript was used for fancy (and extremely annoying) animations and websites were globally just a bunch of HTML and CSS. On server side, frameworks were not as numerous and powerful as now.

This meant that you had a choice:

  • Either you make proper separation between content (HTML) and style (CSS),

  • Or you mix both, either by putting CSS code within HTML files, or simply by using HTML analogs (<div color="red">I'm red.</div>).

The first alternative gave you two important benefits:

  1. No code duplication, which becomes valuable where you find yourself changing the color of a commonly used element from red to purple on every page of the website, making hundreds of changes in your code base instead of just one,

  2. Reduced bandwidth usage (extremely important where most of your visitors have 56 Kbps internet connection), thanks to client cache,

  3. Hypothetical ability to change style without touching the content: a point I'll discuss in part 3.

which also explains why so many personal websites were using <div color="red">I'm red.</div> style at their beginning, and when becoming larger and more popular, were forced to migrate to pure CSS.

2. Why is it important to separate CSS from HTML today?

Assume we are not under legal obligation to make our web app accessible (since accessibility would inevitably lead to no-JavaScript version), and that the app is already using JavaScript extensively for its core features.

At development level:

Separating content from style may still be useful for the same reason as above: code duplication. If two elements share the same style, you shouldn't be writing the style twice: you should define it once, and then reuse it. Writing it twice leads to maintenance problems which are too obvious to explain.

Note that it doesn't really matter how are you storing content and how are you storing styles. Content would in general be generated by the web app based on (1) data from the database and (2) business logic, while style would be defined in a static form, would it be a CSS file, XAML, or something completely different.

This leads to the second point: how this content and style is served.

At client level:

Serving content and style and applying style to content may take different forms: maybe an ordinary HTML/CSS, maybe some complex solution involving AJAX requests, DOM, etc. The previous bandwidth argument is irrelevant here: not only most users have 8 Mbps or faster connections, but AJAX requests can be cached as well.

Instead, the choice of the alternative would be rather based on the ease of use of a specific solution provided by a specific framework, and how comfortable the developer is delegating this task to the framework.

Here's a story.

Some version of ASP.NET MVC added a feature called bundles. Instead of serving CSS and JavaScript files yourself, you simply fed the framework with those files and the framework did all the job for you: it minified the files and sent them as a single file—one CSS file and one JavaScript file.

But as any magical tool, it had limitations. It worked well for small websites, and if one day, my grandma starts programming in C# and decides to make her personal website, I would be the first one to convince her that she should use bundles.

The story was different for more complex ones. What if I want to include LESS files? Well, there was¹ a possibility to do that, thanks to the excellent architecture of ASP.NET MVC, but this meant reading through dozens of pages of documentation and creating dozens of classes. I'm not sure why would I want to do that, when a bundle-lessn from scratch solution can be done in less than half an hour with fewer code to write.

Same thing for JavaScript. Can I ask ASP.NET MVC to use Google Closure Compiler to minify the files? Probably not easily, or at least not in the earlier versions of ASP.NET MVC.

Framework features are great and can simplify your life, but they can also be a limitation. Small, personal projects can benefit a lot from these. Large projects tend to rely more on custom-made solutions, which are easier and faster to develop than to extend the framework.

Imagine I have a great framework which does an excellent job of generating relevant styles for every page, managing cached styles, etc. This is great, because:

  • This can reduce even further the bandwidth: if I have 600 styles but only 30 are used on the home page, this means 570 styles less to send through the wire and to process by the client; chances are, my home page will appear a few seconds faster.

  • This can make my life and my code simpler, for example by removing the global state. For instance, if I know that a specific style should appear only on that page, I may let the framework figure out which selector should be used, without taking the risk of picking one which may be used on a different page.

Now, personally, I've never seen a framework which can do that, and the ones I've seen appear too limited while not making my life simpler.

Is writing plain CSS easier? I would say so. CSS has its weak points, but many of them are solved by preprocessors such as LESS and Sass. Being able to use features of LESS/Sass while letting the framework process the code into minified CSS is great. But I'm not sure today's tools are mature enough to move from this way of working to something more powerful and abstract.

3. Separation of concerns matters. Is it?

You were mentioning separation of concerns in your question, so I would like to highlight this particular aspect separately.

I see a lot of arguments about separation of concerns, most of which are (in my understanding) based on assumption that it is more often to change just HTML or just CSS and once as opposed to editing HTML and CSS in parallel. While this might be the case for small websites, my commit history shows me the opposite - I usually edit both HTML and CSS together. So instead of separating all HTML from all CSS I would separate each component from each other.

When you change HTML, you will necessarily change CSS in most cases. This is not like DAL/BL/PL, where you can, for example, swap database layer without affecting anything else. If you change content, presentation, often, will have to change.

For instance, you're adding a new button to an element. Not surprisingly, the element is now too small, so you need to adjust its width.

In theory, the inverse is not true: you're expected to be able to throw away all your CSS code, and do something completely different. Same content, different presentation.

When Microsoft released WPF (a technology which powers the interfaces of some Windows applications, making it easier than it was before to design interfaces and apply styles to them) and the underlying XAML (a language used to describe both the content of the interface—buttons, lists, combo boxes—and the style—rounded corners, fonts, transitions), one of the benefits which were highlighted all over the ads was the ability to style application independently of the content.

Microsoft even made a tool for that. It's called Microsoft Blend. The theoretical workflow of a team is the following:

  1. Interaction designers make a wireframe of an application on a piece of paper.

  2. Software developers pick this piece of paper and create, in Visual Studio (developer's tool number one in Microsoft's world), the different windows of the application, putting buttons, lists and combo boxes.

  3. They then give the unfinished application to interaction and graphical designers who open the source code not in Visual Studio—they are designers, they don't use IDEs—but in Microsoft Blend, which shows them not the source code, but a pretty interface where they can visually change the visual aspects of the app: move controls, set color and font, add transitions and animations, etc. Meanwhile, developers finish to implement the features behind the buttons, lists and combo boxes.

We have here:

  • The same initial requirement: being able to change style independently of the content, with the ability to completely replace the current presentation with a different one.

  • The same constraint: if content changes, presentation will be affected in most cases and requires changes too.

While Microsoft did a great job with WPF and XAML, there is still a tiny problem: from time to time, when you need to change a style, you have to change the content as well, which means that the workflow of the team is rather:

  1. Interaction designers make a wireframe of an application on a piece of paper.

  2. Software developers pick this piece of paper and create, in Visual Studio, the different windows of the application, putting buttons, lists and combo boxes.

  3. Interaction and graphical designers and software developers work side by side on the interface of the future application, ensuring constant communication, regular meetings, etc.

This is exactly what happens with HTML and CSS. In theory, you shouldn't touch HTML when working on style. In practice, you're constantly adjusting the markup when working on CSS, because:

  • Either a specific style is impossible with the current markup,

  • Or doing it with the current markup would require too much CSS code or produce a very unclean, difficult to maintain code.

When you change HTML too often when you're working on CSS, this may be a sign that:

  1. The HTML code was not well done in the first place.

  2. The HTML code was made "without styling in mind". Experienced programmers who know well CSS will produce HTML code which will be easier to style. Programmers who master HTML but know nothing about CSS will write code which will require a huge amount of changes.

As an extreme example, CSS Zen Garden is an interesting study case of what can be done with pure CSS, based on an unchanged HTML code which was originally well done.

In practice, most websites and web applications are on the other side: every site I know which was "redesigned" visually was changed completely: different CSS, different HTML, different JavaScript, different code-behind.


¹ I believe LESS support is automatic in newer versions of ASP.NET MVC.

1
  • 1
    > accessibility would inevitably lead to no-JavaScript version That is simply not true. JAWS, NVDA, Voice Over, Narrator all work perfectly fine with JavaScript-heavy websites . Oct 23, 2017 at 14:45
6

The key point is separation of concerns:

Readability:

It's definitely easier to just open the file that contains css rules instead of your huge HTML file looking for the culprit. So, it is easier to maintain your website.

Cachability:

Since your HTML code will be different for all the pages of your site but your CSS won't, and it would be silly to reload them for every page. Separating css styles in separate files make the cachable. So, it affects the page load time too (also decrease the more page load times by minifying the css).

5
  • Readability: huge HTML files are a bad sign itself. In a real web app, you'd have lots of small templates. This point isn't valid to me. Cachability: The same here. HTML (and I mean templates), JS, CSS - they all can be cached using the same mechanism.
    – mik01aj
    Jan 27, 2015 at 16:13
  • It's only about between html and css. Then why isn't it suitable then?
    – Bhojendra Nepal
    Jan 27, 2015 at 16:14
  • @m01 Your question asks about putting the HTML JS and CSS all in the same file. Then you say you want them in small separate files. Which one do you want? Inline CSS doesn't make sense neither does inline js. And if it's all inline then you're not caching anything except for the rendered page, when you go to another page, all of the CSS and JS comes inline as well. There's no reuse except for at a conceptual/code level. The browser will have to download the same styles over and over for each page. Jan 27, 2015 at 18:40
  • @MikeBrown, I meant having many self-contained modules which would contain HTML, CSS and JS, bundled together with help of JSX and react. All those components can be cached. And I believe that having component-oriented architecture (as opposed to type-oriented) would actually help readability even more.
    – mik01aj
    Jan 27, 2015 at 21:09
  • @m01 okay I must admit being unfamiliar with JSX so I have to learn. If you're saying that JSX would create a bundle of your CSS and JS then it might be a viable option. My thoughts are that there are a number of JS compilers competing for attention and none has become the standard. But if that works as part of your development chain it makes sense. Jan 27, 2015 at 22:20
2

It is all about separation. Separating HTML, CSS and JS is necessary for readability and maintainability. While you COULD mesh them all together for a small site you definitely should not. When designing you should always try to make the site as maintainable and expandable as you can (within reason).

JS is also too heavy to be used for markup and styles on a regular basis. For larger sites this would drag down your performance greatly.

0

One could say that the separation of html, css and js codewise conforms web development to the Model-View-Controller-Pattern.

Also html, css and js are often very much entangled, so looking at them in different windows, can be quite handy from time to time.

Not the answer you're looking for? Browse other questions tagged or ask your own question.