Reputation: 3039
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)
Upvotes: 2
Views: 1535
Reputation: 13059
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');
Upvotes: 4
Reputation: 7591
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.
Upvotes: 0
Reputation: 29463
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);
}
Upvotes: 1