6

I have a project which is split up into the parent app, and several reusable child components in separate repositories. I'd like to define default CSS variables in these child components, which can be overridden by the parent app, however I can't find the right syntax for this. Here's what I've tried:

/* parent */
:root {
  --color: blue;
}

/* child */
:root {
  --color: var(--color, green);
}

.test {
  width: 200px;
  height: 200px;
  background: var(--color, red);
}

https://codepen.io/daviestar/pen/brModx

The color should be blue, but when the child :root is defined, the color is actually red, at least in Chrome.

Is there a correct approach for this? In SASS you can add a !default flag to your child variables which basically means 'declare if it's not already declared'.

3 Answers 3

5

I would suggest an approach by aliasing the variables in the component and using "parent" or root variables as main value while local value is by !default.

.parent {
  --background: red;
}

.child {
  --child_size: var(--size, 30px); /* !default with alias */
  --child_background: var(--background, green); /* !default with alias */

  background-color: var(--child_background);
  width: var(--child_size);
  height: var(--child_size);
}
<div class="parent">
  <div class="child"></div>  
</div>
<hr>
<div class="child"></div>  

Sign up to request clarification or add additional context in comments.

1 Comment

That's a neat approach, thanks
2

CSS stands for cascading style sheets, so you cannot override anything by a parent...

The only way is to create a stronger rule.

look at .c1 and .p1

.parent {
  --background: red;
}

.child {
  --size: 30px;
  --background: green; /* this wins */

  background-color: var(--background);
  width: var(--size);
  height: var(--size);
}

.p1 .c1 {
  --background: red; /* this wins */
}

.c1 {
  --size: 30px;
  --background: green;

  background-color: var(--background);
  width: var(--size);
  height: var(--size);
}
<div class="parent">
  <div class="child"></div>  
</div>

<hr />

<div class="p1">
  <div class="c1"></div>  
</div>  

1 Comment

does it suit for you?
2

Thanks to @Hitmands hint I have a neat solution:

/* parent */
html:root { /* <--- be more specific than :root in your parent app */
  --color: blue;
}

/* child */
:root {
  --color: green;
}

.test {
  width: 200px;
  height: 200px;
  background: var(--color);
}

3 Comments

I don't understand why moving variables to the global scope could be neater?
My most common use case for CSS variables is for global stuff like font-size and theme colors, and it's this stuff I want to be able to override from the parent app.
Also using this approach means you don't have to add a new CSS rule in your parent app, ie. .parent .child { /* override */ }, you can let the variable specificity do that for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.