42

I'm experimenting with a lot of success with CSS3 Custom Properties (aka CSS Variables). I'm talking about the --black: #000; and background: var(--black); type variables. However, I'm having no luck when variables are declared in separate linked documents.

With CSS Custom Properties being at over 72% browser compatibility (src: https://caniuse.com/#search=css%20variables), I'm keen to start using them in a very specific app where I know my audience are using compatible browsers.

I'm wondering whether these CSS Custom Properties are global in scope across all linked CSS documents or whether they are only global (at the :root element) per document?

I'm not able to find an answer (even in the spec)!

Some of the research I read:

My specific problem is occurring in a Ruby on Rails application, where I'm including the CSS Custom Properties in a <style> block ahead of an SCSS stylesheet include which when deployed is to be pre-compiled. If I include the variables at the top of the SCSS, everything works just fine. However the <style> block is to contain theme variables and needs to be compiled by ERB at runtime.

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      :root {
        --primary-color: #000;
      }
    </style>
    <%= stylesheet_link_tag 'application', media: 'all' %>
  </head>
</html>
Dom
  • 3,173
  • 4
  • 30
  • 39
  • Please clarify what you mean by "separate linked documents". Do you mean separate HTML files? Your title says "linked CSS documents"; what does that mean? –  Aug 09 '17 at 04:54
  • Linked CSS documents, as in `` and `` together in the same HTML document. – Dom Aug 09 '17 at 05:08
  • Thanks for the edit @vadim-ovchinnikov. Not sure what went wrong with the formatting there. – Dom Aug 09 '17 at 05:09
  • @Jurgen You've missed a line break there (before unordered list). I like your question but just wanted to know why do you think that CSS variables should be limited to single file? – Vadim Ovchinnikov Aug 09 '17 at 05:12
  • I'm using a ` – Dom Aug 09 '17 at 05:15
  • 1
    All linked CSS style sheets are in the same global CSS space. Please give us a specific example of "having no luck". –  Aug 09 '17 at 05:17
  • Also, if I include the variable declarations in the SCSS file at the top, everything works fine. – Dom Aug 09 '17 at 05:17
  • @torazaburo thanks for your clarification. It must be something I'm doing incorrectly in my code then. I can't share the website yet unfortunately, but I could edit my question and add an example of what I'm doing. – Dom Aug 09 '17 at 05:21
  • 1
    Thank you everyone for you input, especially @torazaburo. Confirming what I suspected about CSS variables being global to the CSS space was what I needed. I was able to then go looking for the problem in other places, which I eventually detected and fixed. Everything is working as it should now. – Dom Aug 09 '17 at 14:20

1 Answers1

55

In MDN:

Custom properties participate in the cascade: each of them can appear several times, and the value of the variable will match the value defined in the custom property decided by the cascading algorithm.

It works just like any other CSS properties. It should be declared in the ancestor of the target element. So usually it would be declared to the top-level element html or root:.

It does not matter whether CSS custom properties are declared in an external CSS file or the same file.

The following is a sample using two external CSS files. It works on Firefox, Safari and Chrome.

https://thatseeyou.github.io/css3-examples/basics/customproperty.html

variables.css :

:root {
    --red: #f00;
    --green: #0f0;
    --blue: #00f;
}

style.css :

.red {
    background-color: var(--red);
}
.green {
    background-color: var(--green);
}
.blue {
    background-color: var(--blue);
}

HTML :

<!DOCTYPE html>
<html lang="en">
    <head>
        <link href="customproperty/variables.css" rel="stylesheet">
        <link href="customproperty/style.css" rel="stylesheet">
        <style>
            .module {
                --red: #800;
                --green: #080;
                --blue: #008;
            }
        </style>
    </head>
    <body>
        <div class="red">red</div>
        <div class="green">green</div>
        <div class="blue">blue</div>
        <div class="module">
            <div class="red">red in module</div>
            <div class="green">green in module</div>
            <div class="blue">blue in module</div>
        <div>
    </body>
</html>
thatseeyou
  • 1,822
  • 13
  • 10
  • 2
    And also, as a side note, works across the shadow dom boundaries – vals Aug 09 '17 at 11:26
  • Thank you for your answer. Although the MDN reference doesn't really definitively answer my question (it kind of assumes your knowledge of cascade is sufficient), your code certainly does. @torazaburo 's comment to my question above was more direct. I have resolved my problem, it was a weird caching issue where I wasn't seeing changes I was making, and my style block wasn't rendering correctly as a result. Thanks again for your answer and pointing me at your code, it confirmed what I thought was right and led me down a different path of investigation in my code. – Dom Aug 09 '17 at 14:17
  • Thanks for adding the info about shadow DOM @vals. It's good to know. – Dom Aug 09 '17 at 14:18