Default values for CSS variables: only apply if the variable has not been previously defined

My Web Component relies on the power of CSS variables.

To set default values for these variables is crucial.

With their wide usage across multiple files, it's essential to define them once and for all.

The initial approach turns the text color to black. But why?

How can I establish the default values correctly just once?

.a {
  --my-variable: red;
}

.b {
  --my-variable: var(--my-variable, blue);
}
<div class="a">
  <div class="b">
    <span style="color: var(--my-variable);">text</span>
  </div>
</div>

Answer №1

Adding to the points made previously, there may arise situations where avoiding declaration of variables in the global :root scope is preferred. This can be especially useful when creating a reusable component that requires its own locally scoped styles, independent of the overarching project styles - particularly if the component is intended for use by other developers.

In such cases, one approach is to expose a single variable name to the wider development environment, while utilizing a different variable name within the component itself. The container for the component simply links the optional external variable to the internal variable and sets its default value:

.my-component-container {
  /* Link optional "external" variables to required "internal" variables */
  --my-variable-inner: var(--my-variable, blue);
}

.my-component-container .my-nested-element {
  color: var(--my-variable-inner);
}

.my-component-container .my-other-nested-element {
  border-color: var(--my-variable-inner);
}

This method ensures that --my-variable-inner is consistently defined within the component, while allowing external users the flexibility to define --my-variable as needed.

The trade-off here is managing two variable names instead of one. To streamline this process, consider implementing a project-wide convention, such as appending --inner or another uniform suffix to each relevant variable.

Answer №2

Use the :root selector to set default values, then override them in specific selectors.

:root {
  --primary-color: red;
}

* {
  color: var(--primary-color);
  border: 1px solid var(--primary-color);
  padding: 0.25rem;
  margin: 0;
}

div {
  --primary-color: green;
}

p {
  --primary-color: blue;
}
<div>HI!</div>
&hellip;
<p>Bye!</p>

Answer №3

Why does the initial attempt result in black text?

The reason for this is that the code

--my-variable: var(--my-variable, blue);
is invalid since it tries to define a variable with itself, which is not allowed. As a result, the browser will ignore this declaration. Subsequently, when trying to use color: var(--my-variable);, the color falls back to the initial value, which is black.

To resolve this issue, it is recommended to define the variable at a higher level where it can be inherited by all elements (as suggested by @kornieff).


As stated in the specification:

Custom properties are mostly left unevaluated, except for allowing and evaluating the var() function within their values. This may lead to cyclic dependencies when a custom property references itself using var(), or when multiple custom properties refer to each other.

For each element, a directed dependency graph is created, featuring nodes representing each custom property. If a custom property prop's value includes a var() function referring to the property var (including in the fallback argument of var()), an edge is added between prop and var. It is possible for edges to point from a custom property to itself. If there is a cycle in the dependency graph, all custom properties involved in the cycle must revert to their initial value (which is essentially an invalid value).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to ensure that two divs have aligned bottom edges?

I have a set of div containers positioned in different columns within a grid layout. I am looking for a way to identify the containers where the bottom edge is less than 50px higher than any other container, and adjust their heights so they align perfectly ...

Can you explain the distinction between ' &:hover' and ' & :hover' pseudoclass selectors?

While styling a Material-UI Button, I encountered an unexpected behavior when adding hover effects. When using & :hover, only the inner span of the button was affected. However, when using &:hover, the desired style was achieved. What is the diff ...

Firefox presents a compact box positioned between the images

When attempting to use flags as a way to switch between languages, I encountered an issue in Firefox where a small box appears between the images on the Hebrew site. In Chrome, everything works fine. I implemented the following code: <div class="flags ...

React-Native-Web generates default classes for inline styles and erroneously applies them in a jumbled sequence

Currently working on a project involving react native web and NextJS. I have encountered an issue with inline styles in React that seems to be caused by RN-Web. It appears that there is a mechanism within the framework that automatically generates classes ...

Troubleshooting issues with custom Bootstrap CSS implementation

I've been working on a website using Twitter Bootstrap and I wanted to add an interesting dynamic where an image starts off as grayscale and then transitions to full color when hovered over. Instead of modifying the Bootstrap.css, I decided to create ...

What are the best situations to utilize bootstrap and when should you avoid it?

When it comes to web development, there is often a debate on whether to use Bootstrap or custom CSS for designing a website. For my school project, I am tasked with creating a homepage and contact page using Bootstrap primarily. However, we are also requir ...

Looking for a way to make one image disappear briefly while transitioning to another image in Javascript

**Hey there, coding enthusiasts! I could really use some help right now. I am trying to create a smooth image transition effect using Javascript, where one image fades out while the next one fades in seamlessly. As someone who is still relatively new to pr ...

Highcharts 3D Pie Chart with Drilldown Feature

How can I create a 3D Pie Chart with Drilldown effect? I am having trouble understanding how it works. Here is a JsFiddle Demo for a 3D Pie Chart: JsFiddle Demo And here is a JsFiddle Demo for a 2D Pie Chart with Drilldown feature: JsFiddle Demo You can ...

Adjusting the height of a vertical slider in Vuetify2 is not customizable

I've been trying to adjust the height of a vertical slider in vuetify2, but setting it to "800px" or using style="height:800px" doesn't seem to work as intended. Even though the box within my grid expands, the height of the slider remains unchan ...

Explore the Codrops website with the help of our convenient tour feature and

CoDrops offers a website tour feature created with jQuery, which can be found at this link: http://tympanus.net/Development/WebsiteTour/ However, there is an issue when you click on "Start the tour". It will initially show a Next button, which then change ...

Is it important to position elements based solely on the parent container?

My frustration with element positioning persists: <div id="container"> <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> </div> #div1 { right:0; // I want its right border to be 0px from th ...

What is the best approach to transforming my jQuery function into CSS to ensure responsiveness?

I have created a jQuery animation with four functions named ani1(), ani2(), ani3(), and ani4(). Everything is working fine on desktop, but now I am facing the challenge of making it responsive for mobile devices. I am looking for CSS code to replicate the ...

Enhancing the appearance of the Switcher by framing it with

I've been working with the component package https://www.npmjs.com/package/react-switch-selector to create a design similar to this https://i.stack.imgur.com/voHqm.png Although I have made some progress, I'm struggling to add a border outline. H ...

Is it possible to use PHP to add a prefix to every selector in a snippet of CSS code?

Suppose I have a variable named $css that holds some CSS code. My goal is to prepend a specific text to each selector. For instance, consider the following CSS code: #hello, .class{width:1px;height:1px;background-color:#AAA;} div{font-size:1px} input, a, ...

Ways to focus on a specific div using JavaScript

I am attempting to create a 'snow' effect on the background of a particular div with a red border. Here is the code, but you can also view it here: <!-- language: lang-js --> var width = getWidth(); var height = getH ...

Is there a way to stop TD from going to the next line?

I am using Javascript to dynamically generate a table and I want it to extend beyond the boundaries of the page. When I manually create the table, it works fine and extends off the page, but once I put it into a loop, the <td> elements wrap onto a se ...

Is there a way to use HTML and CSS to switch the style of a dynamic decimal number to either Roman numerals or Katakana characters within a specified HTML element, such as a tag, div

I've searched everywhere but only found guides on list styling and counter styling in CSS that didn't work out. So, for example, I have a number inside an HTML tag that is changed dynamically using Vue Watch. I want to display the number in upper ...

checkbox inspired by the design of the iPhone

I'm looking to create a custom checkbox! <label id="sliderLabel"> <input type="checkbox" /> <span id="slider"> <span id="sliderOn">SELECTED</span> <span id="sliderOff">SELECT</span> ...

Creating customizable divider lines with text next to them using HTML in emails

How can I create an adjustable line with a word next to it, ensuring that long words do not wrap onto a second line? I want the line to stay on one line and the left side to shrink accordingly. Also, I need the text input area to be flexible so I can input ...

Color the area entirely in black

I am currently working on a project for one of my courses, where I have created a website for a specific service. However, I am facing some challenges and things are not going as smoothly as I had hoped. Here is a screenshot of the page: https://i.stack.im ...