CSS Load Order Headache

I used rails generate scaffold for part of my application, and this looks fine so far. Now I would like to change a style for the <a> element, which happens to be defined in scaffold.css.scss. I don't want to touch the generated file, so I place the definition into my own file. I have one (rkanren.css.scss) which has CSS definitions which are used project wide.

Testing the page, I see that my style change is not honoured. Using the "inspect" function of Google Chrome, I indeed see that the definition in scaffold.css overrides mine (although both are specific in giving a style to, say, a:visited).

Next, I tried to place my scss file explicitly in the load order, for example:

*= require rkanren *= require_tree . *= require_self

But to no effect. I tried the other 5 permutations of this sequence too, but Chrome always shows that my definition is masked.

What did I do wrong?

I am using Rails 4.1.1.

Why?? It's your app, and it makes no sense to keep a style definition that you don't want, much less a duplicate that conflicts with what you *do* want. Edit it and be done :slight_smile:

Otherwise, you need to explicitly require your files in the appropriate order, but why bother?

You are very close in your solution, but you need to require your stylesheet after the scaffold one, not before it. CSS works in a "who has the last word" order, where a later reference (in source order) to the same selector will alter whatever has come before.

.foo { color: blue; font-family: 'Helvetica Neue', sans-serif } ...later... .foo { color: red }

all .foo elements will be red, not blue. But they will also be Helvetica Neue, since the later style did not override that preceding attribute. The two rules are coalesced into one in the browser's "mind".

When Rails concatenates the stylesheets into application.css, it just mashes them together in whatever order you listed them, and de-SASSes and minifies the whole mess at once. It does not perform any de-duplication of styles, instead it relies on the normal order of precedence of CSS to do that part.

You can fix this in a couple of ways. You could rename your stylesheet to start with a couple of Zs, or you could explicitly require the scaffold sheet before yours, and then require tree (which will only bring in anything you haven't already asked for by name).

Whichever reference to the a:hover style comes last in that combined sheet will have the last word on the way it looks on screen.

Walter

Thanks a lot for the helpful answers! Both solutions make sense to me.

Also you didn’t show us the actual styles themselves, and I’m not sure how familiar with CSS you are. In case you aren’t (no offense intended-- I am writing this to be thorough), the style inside of scaffold may be more specific than your own style.

For example:

/* scaffold.css */

a.some-class.some-other-class {

color: blue;

}

/* your css, presumably defined AFTER scaffold CSS */

a {

color: red;

}

In the example above, a elements with two classes (some-class and some-other-class) override definitions for an a element with no classes, even if the no-class one comes after the two-class one. (This may be obvious if you know CSS well, I’m just pointing it out as a possible cause since you didn’t show us your code).

The other suggestions for fixes are valid too. However, I disagree that changing scaffold.css is universally the right answer in all cases. I tend to avoid generating scaffolding from rails for these reasons. Alternatively, take the styles in scaffold and move them to your app (cut & paste), and then delete the scaffold file. Unless it’s a library, treat it as boiler-place starter CSS, not as a library you want to maintain congruence with.

If we were talking about some library’s CSS, on the other hand – like Bootstrap — then I would not recommend you edit the library’s CSS directly. We did this on a large project using Bootstrap 2 and wound up with such a monster of CSS diffs that we were basically unable to upgrade Bootstrap because of all our “tweeks” baked into the original Bootstrap CSS were so intertwined with our app it was nearly impossible to reverse-engineer them at a later date. So in a case like that, your instinct to override with additional CSS files instead of change the original declarations is right on.

-Jason

Jason Fb wrote in post #1150056:

Also you didn't show us the actual styles themselves, and I'm not sure how familiar with CSS you are. In case you aren't (no offense intended-- I am writing this to be thorough), the style inside of scaffold may be more specific than your own style.

Actually, this was not the case. I used Google Chrome's "inspect element" feature, which is very handy, because it shows not only the definition place of the styles, which apply, but also, which other styles have the same (or lower) specifity (and where their definitions are).

In effect, changing the load order solved the problem.

Alternatively, take the styles in scaffold and move them to your app (cut & paste), and then delete the scaffold file. Unless it's a library, treat it as boiler-place starter CSS, not as a library you want to maintain congruence with.

Thanks for the suggestion! I will consider this do for future conflicts.

If we were talking about some library's CSS, on the other hand -- like Bootstrap --- then I would not recommend you edit the library's CSS directly.

Thanks for this warning too! While I don't feel so comfortable with Bootstrap, I am currently looking for other libraries and will probably face this problem again.

Ronald