All the approaches so far do cover the extraction of just two and only rgb
/rgba
based color-stop values of a gradient. But there are much more valid variants of how a linear css gradient can be expressed ... e.g. ...
-webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));
-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55)
-o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ;
linear-gradient(135deg , red, red 60%, blue) ;
linear-gradient(yellow, blue 20%, #0f0);
linear-gradient( to left top, blue, green 40%, red );
linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ;
linear-gradient(to bottom right , red, rgba(255, 0, 0, 0));
linear-gradient(right top to left bottom, red, rgb(255, 0, 0));
Thus, the base of a generic approach has to identify the beginning(s) of any gradient-definition's color-stop.
Which means after trim
ming a gradient string-value one has to strip off all the unnecessary information except for the clean list of color-stop values. A (kind of validating) regular expression which features a(n optional) positive lookbehind in order to reflect the css-specification of linear gradients utilized by split
does achieve the stripping from the left ...
/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/
... whereas a rather simple regex like ... /\s*\)\s*;*$/
... will be utilized by replace
in order to strip off the unnecessary characters from the right ...
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(str => str
.trim()
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
.replace((/\s*\)\s*;*$/), '')
));
.as-console-wrapper { min-height: 100%!important; top: 0; }
The above example's logging shows a clean color-stop only string for each linear gradient definition.
The more complex part is how to properly distinguish/separate each possible variant of a color-stop value. The spec does help again. The splitting of values can take place at every comma-character which is followed by a non-digit character.
A regex like this ... /,(?=\D)/
... which features a positive lookahead already does this job.
But in order to secure this task one first needs to strip every leading and trailing whitespace around every comma-character. In the end one can go and prettify each color stop value by inserting again a single space before each occurring comma-character.
A final generic approach, which extracts a list of all color-stop values from a linear css-gradient definition might look similar to the following implementation ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(getLinearGradientColorStopValues));
.as-console-wrapper { min-height: 100%!important; top: 0; }
The OP's example/task then solves like that ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
const [
colorstop1,
colorstop2,
] = getLinearGradientColorStopValues(
"linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))"
);
console.log({ colorstop1, colorstop2 });
.as-console-wrapper { min-height: 100%!important; top: 0; }