Forum: Ruby on Rails CSS Load Order Headache

0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-06-14 14:46
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.
Bee69cfed999cd13e3bff73d472a39ee?d=identicon&s=25 Hassan Schroeder (Guest)
on 2014-06-14 16:37
(Received via mailing list)
On Sat, Jun 14, 2014 at 5:46 AM, Ronald Fischer <lists@ruby-forum.com>
wrote:
> 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

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 :-)

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

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
http://about.me/hassanschroeder
twitter: @hassan
A47e0a6beeb9d048ff054fc1c3a97418?d=identicon&s=25 Walter Davis (walterdavis)
on 2014-06-14 16:58
(Received via mailing list)
On Jun 14, 2014, at 8:46 AM, Ronald Fischer wrote:

> style to, say, a:visited).
>
> What did I do wrong?
>
> I am using Rails 4.1.1.

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
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-06-15 09:58
Thanks a lot for the helpful answers! Both solutions make sense to me.
Dfc7587fd73f2efa19d6f1f9611b70ba?d=identicon&s=25 Jason Fb (jasonfb)
on 2014-06-18 16:36
(Received via mailing list)
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
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-06-18 18:25
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
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.