3

When I define a variable in various CSS files, and include these files in my HTML file, then it overrides the previous variable. Why is it happening?

Let's say that I have

test1.css

:root {
    --size-of-font: 5rem;
 }
.logo{
    font-size: var(--size-of-font);
}

test2.css

:root {
--size-of-font: 1.2rem;
}
.outer {
    font-size: var(--size-of-font);
    cursor: pointer;
    text-align: center;
}

test.html

<link rel="stylesheet" href="test1.css">
  <link rel="stylesheet" href="test2.css">

<div class="outer">
    <h1 class="logo">Lorem Ipsum</h1>
     <p>Neque porro quisquam est qui dolorem 
          ipsum quia..."<br>
          "There is no one who loves pain 
          itself..."
     </p>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
P.Bora
  • 31
  • 1
  • 1
  • 5
  • 5
    In CSS the latest style rule applied to an element is used, unless the original rule has a greater specificity. So if you apply two style sheets and they both target the same element, the last one loaded will be the one that is applied. – gavgrif Nov 01 '18 at 08:40
  • Do you not just want the outer-size-font variable in your .outer { }? because then you won't have thie font-size issue if that is the case. – JeroenE Nov 01 '18 at 08:42
  • just to go off of gavgrif's comment: `:root` is more generic then `.outer`, thus `.outer` stylings get applied :) – treyBake Nov 01 '18 at 08:46
  • @ThisGuyHasTwoThumbs: What does "generic" mean here? – BoltClock Nov 01 '18 at 08:52
  • @BoltClock `:root` can apply to anything, kinda like.. targetting `div` with CSS. it's a more generic specification, as opposed to classes and IDs. Classes and IDs are less generic and more specific – treyBake Nov 01 '18 at 08:53
  • @ThisGuyHasTwoThumbs :root apply to only root not to anything – Temani Afif Nov 01 '18 at 08:56
  • @ThisGuyHasTwoThumbs: That doesn't really mean anything to CSS, though. .outer still uses the custom property defined in :root - since that's the only place it is ever defined. – BoltClock Nov 01 '18 at 08:57
  • @TemaniAfif ah true dat ^^ haha – treyBake Nov 01 '18 at 08:57
  • @BoltClock I let you answer this one ;) – Temani Afif Nov 01 '18 at 08:57
  • @BoltClock sorry, not getting what you mean :) – treyBake Nov 01 '18 at 08:58
  • @Temani Afif: SazooCat's answer is satisfactory. You have two competing :root CSS rules across two stylesheets, so one overrides the other and all other rules that depend on --size-of-font are affected accordingly. – BoltClock Nov 01 '18 at 09:00
  • no. both has same variable size-of-font – P.Bora Nov 01 '18 at 09:02
  • Please note that CSS variables are not that different from other CSS properties. First of all, `:root` simply means the element at the root of the document, that is, the `html` element. Other elements then inherit the variables via the normal CSS rules. – Mr Lister Nov 01 '18 at 09:03
  • @BoltClock I know but I am pretty sure that he's thinking that the first var() is evaluated to the custom property defined before it in the CSS file and will not consider the one after defined after – Temani Afif Nov 01 '18 at 10:07
  • @TemaniAfif Ah, you mean the OP thinks that after the first assignment of the var to a property, the property value can't change any more, even if the var does? That's possible, but then maybe you should post that as an answer, pointing out their mistake. – Mr Lister Nov 01 '18 at 10:12
  • @Mr Lister: I posted an answer. – BoltClock Nov 01 '18 at 10:39
  • @MrLister I also posted one :p – Temani Afif Nov 01 '18 at 10:47

5 Answers5

4

CSS = Cascading Style Sheets... this means the sequence of definition matters, the most recent and more specific takes precedence. If you switched test1 and test2 over in your html you'd get a different result because the variable is defined as the more recent value.

I recommend you use a different variable name for your different .css files if you require them to not share this value.

SazooCat
  • 150
  • 1
  • 6
  • 2
    not always the most recent - later rules may still not apply with case use of `!important` or if the previous CSS rules have a higher specificity value – treyBake Nov 01 '18 at 08:45
1

When you include both stylesheets, all of their rules are combined into one single stylesheet. This means that you introduce a conflict in two :root CSS rules with the same custom property declaration:

:root {
  --size-of-font: 5rem;
}

:root {
  --size-of-font: 1.2rem;
}

Cascade resolution means that the specified value of the --size-of-font custom property is 1.2rem, not 5rem. Simply, the second declaration overrides the first as both rules have identical selectors.

This value of 1.2rem is then applied to both uses of var(--size-of-font), in .logo and .outer, again because two stylesheets combine to form one. .logo does not only see the --size-of-font in its own stylesheet; it sees whatever is resolved by the cascade, taking all declarations into account.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
0

Yes it will overwrite. If I have two classes having the same name like:

test1.css contains

.text-color{
    color:red;
}

test2.css contains

.text-color{
    color:blue
}

and apply them in sequence

test1.css
test2.css

it will apply the CSS which is in test2.css. It takes the latest CSS if the class names are the same.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
0

Here we need to consider two things: How custom properties works and how they are evaluated using var().

  1. The first part is trivial because custom property behave the same as any other property. From the specification we can read:

Custom properties are ordinary properties, so they can be declared on any element, are resolved with the normal inheritance and cascade rules, can be made conditional with @media and other conditional rules, can be used in HTML’s style attribute, can be read or set using the CSSOM, etc.

Considering this, the last custom property defined in your case will override the first one:

:root {
    --size-of-font: 5rem;
 }
.logo{
    font-size: var(--size-of-font);
}

:root {
  --size-of-font: 1.2rem; /* This one will win !*/
}
.outer {
    font-size: var(--size-of-font);
    cursor: pointer;
    text-align: center;
}
  1. When using var() we need to also consider some rules like defined in the same specification:

To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property. Otherwise,
  3. if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at computed-value time

In our situation, we will consider the (2) because .logo will inherit the custom property defined inside :root with its value 1.2rem (not an initial value).

In other words, the evaluation of a custom property doesn't consider the order of their appearance in the CSS file. It considers the value of the custom property that is resolved as an ordinary property.


Here another useful question where you can get more details and more examples: CSS scoped custom property ignored when used to calc var in outer scope

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Note that custom properties don't work the same as other properties in all respects. You cannot use `var(..)` on ordinary properties; e.g. `{color: #444; background: var(color);}` won't work. – Mr Lister Nov 01 '18 at 11:07
0

There are 3 ways to CSS for websites, within a CSS file, <style> tag, or inside an HTML tag. CSS files will always have precedence over any other CSS format. <style> tags only have precedence over CSS tags in HTML, which are at the bottom.

Here's a visual

  1. CSS Files (Comes first)

  2. <style> (Cannot override CSS files but can override HTML inline)

  3. HTML inline styles (least important)

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Elitezen
  • 91
  • 1
  • 8