I want VS Code to only provide suggestions for custom properties I can actually use. So when I type var() I want VS Code to give me a list of properties which will actually make a change…
In CSS you can define globally scoped custom properties with :root, like this :
:root {
--custom-property-1: #000;
--custom-property-2: #fff;
}
However, I think you can also define class scoped properties that only work on a specific class, here is the example I’m giving :
<body>
<div>
Hello world
</div>
<button class="custom-class">
<p>Hello world</p>
</button>
<button>
Hello world
</button>
</body>
.custom-class {
--background-color: red;
}
.custom-class p {
background-color: var(--background-color);
}
button {
background-color: var(--background-color);
}
div {
background-color: var(--background-color);
}
So in this example I just made a div and two buttons where one button has a paragraph child. My theory is that if I define the custom property --background-color: red;
in the scope of the .custom-class
ruleset I will only be able to access that property in elements that have that class and not globally.
To prove my theory I gave the custom property to all of my elements. What I expect to happen is that only the elements that are somehow connected to the custom-class will be painted red.
Here are the results:
So it seems like my theory works… Now that this is over I can start defining my real issue. It is an issue with VS Code and IntelliSense.
VS Code provides suggestions when I type var(), and that is fine for globally scoped custom properties, but it is unacceptable for those which are class scoped.
Here is the example:
Even though this div element cannot possibly access the custom property and writing it like that makes no change, VS Code is still giving me a suggestion for it… I cannot have that happening because I think I will have lots and lots and lots of these class scoped custom properties and I only want VS Code to suggest the custom properties which the element can actually access.
Is there a way to make this happen?
2
Answers
TL;DR As far as I am aware, and at the time of this writing, VS Code doesn’t support anything significantly more sophisticated than what you have observed, and to do so would be a very difficult task (unless solutions that only address some set of the simpler problems are settled for).
If the assumption is that a suggestion for referencing a custom property be given if and only if that property will always be accessible at either some number or all of the elements where the selector for the rule referencing the custom property applies, (which is my understanding of what this question is about) then this is significantly more complicated than you are estimating it to be. Some of what I’ve already written in my answer to How can I get color decorations for CSS variable references to work in VS Code? applies, though since this is not exactly the same question (that one is particularly concerned about property values (where the cascade is a big source of complexity), whereas this is concerned more with just whether a property is accessible or not (where the cascade is not really a source of complexity (unless I’m missing some other source of complexity, which I very well could be))), I’ll give it an answer.
You gave the example of defining a custom property on a class selector, and being surprised that you get suggestions for using it in a selector that doesn’t include that class. That’s not that surprising. For VS Code to be able to prove in all/any cases whether a custom property defined in one selector
A
is "accessible" from another selectorB
, it must be able to prove that eitherB
selects is necessarily a descendant ofA
everythingA
selects (which can be done- for example, the example you gave with.custom-class
and.custom-class p
),B
selects is a descendent of everything/something thatA
selects (take your pick of the words "everything"/"all" vs. "something"/"any" based on what behaviour you expect). This is really non-trivial:A
orB
might reference, such as attributes), custom properties can be added or removed on any element via style properties, etc. All of this being controllable dynamically via JavaScript (imagine IntelliSense having to parse JavaScript to see what it will do at runtime!)B
that are descendants ofA
), each linking or not linking to your stylesheet where those rules are definedAnd so on. I’d wager that even tackling (just) all the complexities mentioned above is intractable or close to intractable. Of course, you can create imperfect solutions and write extensions for VS Code that only support the kind of IntelliSense you want for some subset of those complexities, but writing such extensions I think is getting outside the scope of what this question is asking here- especially given how vast those types of complexities are.
On the other hand, a tool that works at runtime such as a browser’s developer tools has access to state at runtime, and isn’t subject to many of the sources of complexity above (it still is to some, and to varying degrees for others, such as DOM state changing dynamically, but not to all).
It is not easy to create a solution to this problem because there are simply too many unknowns due to the freedom that CSS offers the developer.
Here is an example code to demonstrate just one of many unsolvable things:
It would be possible to remove the suggestions completely as long as the element is not clearly assigned to the class in which the variable was defined, but for that someone would have to think apart and write a plugin for vscode.
In the future, the problem could certainly solve itself with AI integration like Copilot.