2

I have my code with a CSS variable, let's call it --element-padding, which allows multiple values like 8px 0 12px 79px, this variable is in a webcomponent that I own, and it's being used by third parties.

And I use it in my webcomponent CSS

padding: var(--element-padding, '0');

This variable allows my users to override the padding declaring it when styling my component

.awesome-component {
   --element-padding: 8px 0 12px 79px;
}

Now I have found that I would need to process it, because I just need the padding-top for another style.

One option would be to change --element-padding to 4 different variables

--element-padding-top
--element-padding-right
--element-padding-bottom
--element-padding-left

But then, the users will have to change their code to adapt to the new variables, causing a lot of trouble.

Is there any way to get this variable and make some kind of splitting-calculations before using it in the var() CSS function? that way I can get the 1st position of the variable, without the need to tell the users to change their implementation.

(The code and explanation is a simplified one which doesn't adjust to the real case, but the point is about splitting a variable containing 4 measures into 4 different variables, without the need to add/modify variables in the user side / root)

4
  • How is JS involved in the question? Commented Oct 1, 2021 at 10:37
  • Maybe there could be some JS option to solve my problem, it's doesn't need to be pure CSS Commented Oct 1, 2021 at 10:45
  • Given your latest update, It seems that the question is an over-simplification and doesn't really represent what you're trying to do. This will make it difficult to appreciate the nuances and provide an appropriate answer. Commented Oct 1, 2021 at 12:02
  • That being said, I think I know what you mean - see updated answer. Commented Oct 1, 2021 at 12:39

3 Answers 3

4

Original answer at the bottom 👇🏻👇🏻👇🏻

I think I understand that you want to allow your consumers to continue using the --element-padding CSS variable and you want to derive the individual top/right/bottom/left values from that they can customise the --element-padding but you're going to be using the individual properties in your development going forward.

You can read CSS variables:

getComputedStyle(document.documentElement).getPropertyValue('--element-padding')

And set them:

document.documentElement.style.setProperty('--element-padding-top', '8px')

Putting it all together:

const updatePadding = () => {

  let elementPadding = getComputedStyle(document.documentElement)
    .getPropertyValue('--element-padding'); // "8px 0 12px 79px";

  let [top, right, bottom, left] = elementPadding.trim().split(/\s+/);

  const docStyle = document.documentElement.style;
  docStyle.setProperty('--element-padding-top', top);
  docStyle.setProperty('--element-padding-right', right);
  docStyle.setProperty('--element-padding-bottom', bottom);
  docStyle.setProperty('--element-padding-left', left);

};

updatePadding();
:root {
  --element-padding: 8px 0 12px 79px;
  /* Default values but will overridden by updatePadding() */
  --element-padding-top: 8px;
  --element-padding-right: 0;
  --element-padding-bottom: 12px;
  --element-padding-left: 79px;
}

ORIGINAL ANSWER

You should think about the other way around. Rather than split --element-padding why not declare the individual variables and then use those to create the all-in-one CSS variable.

::root {
  --element-padding-top: 8px;
  --element-padding-right: 0;
  --element-padding-bottom: 12px;
  --element-padding-left: 79px;
  --element-padding: var(--element-padding-top) var(--element-padding-right) var(--element-padding-bottom) var(--element-padding-left);
}

You can still use the original variable as you previously did.

  padding: var(--element-padding, '0');
Sign up to request clarification or add additional context in comments.

7 Comments

That's what I said, but I don't want to change the variable, because it will cause a breaking change in the interface of the users of my component
Why would it break it, you still have the original --element-padding variable, plus the 4 new ones? Could you update your question with an example of how this would break things?
This would break because I am maintaining the part of a webcomponent, that has the variable implementation, and all my consumers are using the webcomponent, setting the --element-padding to their needs to override my styles. If I change the variables, the paddings will not be correct for the users until they refactor their code
Could you add that extra information to the question so that we may know exactly what you need?
Their overrides should still override your declaration though!
|
1

A key thing to note here is that CSS Custom Properties may reference other CSS Custom Properties:

Example:

:root {
  --element-padding-top: 8px;
  --element-padding: var(--element-padding-top) 0 12px 79px;
}

 .element1 {
   padding: var(--element-padding, '0');
 }

 .element2 {
   padding-top: var(--element-padding-top);
 }

1 Comment

I have edited the question, I don't want to add more variables or modify the existing ones in the root side :( but thanks for your time!
0

You can use default values. If the ones who use your component haven't set the values, no biggie, but you give them the opportunity to declare them if they want to.

:host {
  --element-padding: 20px;

  padding:
     var(--element-padding-top,    var(--element-padding))
     var(--element-padding-right,  var(--element-padding))
     var(--element-padding-bottom, var(--element-padding))
     var(--element-padding-left,   var(--element-padding));
}

The downside is that they probably can't declare padding as a set of numbers.

2 Comments

Exactly, the default value wouldn't be correct because it's a set of numbers :(
@Víctor I guess the only thing you can do is to use the ready method and check how element-padding is declared, and set the rest of the four variables based on that. Clumsy, IMHO, but sadly true. Using mixin, or just declare padding-top et al with empty variable names. Then the browser will fall back on the default padding declaration.

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.