Color variable best practices #485
-
A standard use case for Stylex will be to store colors with For example, Sass compiles this (see playground): $blue: #0093ff;
.blue {
color: $blue;
background-color: rgba($blue, 0.2);
} to this: .blue {
color: #0093ff;
background-color: rgba(0, 147, 255, 0.2);
} This has allowed us to store colors in their hex format and use them with opacity in our codebase. It looks like Stylex doesn't support this, so I'm wondering what the recommended way of storing colors is, and whether support for similar functionality to Sass is planned. Currently it seems I have to resort to listing out each variant: import stylex from "@stylexjs/stylex";
export const colors = stylex.defineVars({
blue: rgb(0, 147, 255),
blue_20: rgba(0, 147, 255, 0.2),
}); Another (convoluted) option might be to define the I'm sure there must be a better way I'm missing, but couldn't find any discussions on the topic so thought I'd start one for reference. Looking forward to your response! Thanks folks. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Well, this isn't really a solution, but something to think about. You can use one definedvar inside of another in StyleX. You could use function hexToRRGGBBAA(hex: string, opacity: number): string {
// Remove the hash at the start if it's there
hex = hex.replace(/^#/, '');
// If the hex code is shorthand, convert it to full length
if (hex.length === 3) {
hex = hex.split('').map(char => char + char).join('');
}
// Parse the hex color to get the RGB components
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
// Convert the opacity to an integer between 0 and 255
const a = Math.round(opacity * 255);
// Convert back to a hex string and append
return `${hex}${a.toString(16).padStart(2, '0')}`.toUpperCase();
} However, I don't know where in the StyleX sytem this would fit. export const colors = stylex.defineVars({
primary: 'black',
});
export const opaqueColors = stylex.defineVars({
primary: hexToRRGGBBAA(colors.primary, 0.5),
}); anyways, as I said, not an answer but maybe something can come of it? :-) |
Beta Was this translation helpful? Give feedback.
-
The cleanest answer here is to use the new native CSS feature Relative Color Syntax. With it, you'd be able to do something like this: import * as stylex from "@stylexjs/stylex";
export const colors = stylex.defineVars({
blue: '#0093ff',
}); And then use it like so: import * as stylex from "@stylexjs/stylex";
import {vars} from './tokens';
const styles = stylex.create({
blue: {
color: vars.blue,
backgroundColor: `rgb(from ${vars.blue} r g b / 0.2)`,
}
}); This works natively in Chrome and Safari and hopefully, there is a polyfill for Firefox. Another simple approach is to store the import * as stylex from "@stylexjs/stylex";
export const colors = stylex.defineVars({
blue: '0, 147, 255',
}); And then use it like so: import * as stylex from "@stylexjs/stylex";
import {vars} from './tokens';
const styles = stylex.create({
blue: {
color: `rgb(${vars.blue})`,
backgroundColor: `rgba(${vars.blue}, 0.2)`,
}
}); Yes, you'd need to manually wrap the variable in a Finally, you can also make three separate variables for import * as stylex from "@stylexjs/stylex";
export const colors = stylex.defineVars({
blueH: '0',
blueS: '147',
blueL: '255',
}); And then use it like so: import * as stylex from "@stylexjs/stylex";
import {vars} from './tokens';
const styles = stylex.create({
blue: {
color: `hsl(${vars.blueH}, ${vars.blueS}, ${vars.blueL})`,
backgroundColor: `hsla(${vars.blueH}, ${vars.blueS}, ${vars.blueL}, 0.2)`,
}
}); Here you can also use import * as stylex from "@stylexjs/stylex";
import {vars} from './tokens';
const styles = stylex.create({
blue: {
backgroundColor: `hsla(${vars.blueH}, ${vars.blueS}, calc(2 * ${vars.blueL}), 0.2)`,
}
}); This is essentially the same set of capabilities as Relative Color Syntax, but works in all browsers today. |
Beta Was this translation helpful? Give feedback.
The cleanest answer here is to use the new native CSS feature Relative Color Syntax. With it, you'd be able to do something like this:
And then use it like so:
This works natively in Chrome and Safari and hopefully, there is a polyfill for Firefox.
Another simple approach is to store the
r
,g
,b
values: