@@ -487,8 +487,8 @@ impl ToCss for CssColor {
487487 Ok ( ( ) )
488488 }
489489 CssColor :: LAB ( lab) => match & * * lab {
490- LABColor :: LAB ( lab) => write_components ( "lab" , lab. l , lab. a , lab. b , lab. alpha , dest) ,
491- LABColor :: LCH ( lch) => write_components ( "lch" , lch. l , lch. c , lch. h , lch. alpha , dest) ,
490+ LABColor :: LAB ( lab) => write_components ( "lab" , lab. l / 100.0 , lab. a , lab. b , lab. alpha , dest) ,
491+ LABColor :: LCH ( lch) => write_components ( "lch" , lch. l / 100.0 , lch. c , lch. h , lch. alpha , dest) ,
492492 LABColor :: OKLAB ( lab) => write_components ( "oklab" , lab. l , lab. a , lab. b , lab. alpha , dest) ,
493493 LABColor :: OKLCH ( lch) => write_components ( "oklch" , lch. l , lch. c , lch. h , lch. alpha , dest) ,
494494 } ,
@@ -828,22 +828,22 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
828828
829829 match_ignore_ascii_case ! { & * function,
830830 "lab" => {
831- let ( l, a, b, alpha) = parse_lab:: <LAB >( input, & mut parser) ?;
831+ let ( l, a, b, alpha) = parse_lab:: <LAB >( input, & mut parser, 100.0 , 125.0 ) ?;
832832 let lab = LABColor :: LAB ( LAB { l, a, b, alpha } ) ;
833833 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
834834 } ,
835835 "oklab" => {
836- let ( l, a, b, alpha) = parse_lab:: <OKLAB >( input, & mut parser) ?;
836+ let ( l, a, b, alpha) = parse_lab:: <OKLAB >( input, & mut parser, 1.0 , 0.4 ) ?;
837837 let lab = LABColor :: OKLAB ( OKLAB { l, a, b, alpha } ) ;
838838 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
839839 } ,
840840 "lch" => {
841- let ( l, c, h, alpha) = parse_lch:: <LCH >( input, & mut parser) ?;
841+ let ( l, c, h, alpha) = parse_lch:: <LCH >( input, & mut parser, 100.0 , 150.0 ) ?;
842842 let lab = LABColor :: LCH ( LCH { l, c, h, alpha } ) ;
843843 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
844844 } ,
845845 "oklch" => {
846- let ( l, c, h, alpha) = parse_lch:: <OKLCH >( input, & mut parser) ?;
846+ let ( l, c, h, alpha) = parse_lch:: <OKLCH >( input, & mut parser, 1.0 , 0.4 ) ?;
847847 let lab = LABColor :: OKLCH ( OKLCH { l, c, h, alpha } ) ;
848848 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
849849 } ,
@@ -877,15 +877,17 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
877877fn parse_lab < ' i , ' t , T : From < CssColor > + ColorSpace > (
878878 input : & mut Parser < ' i , ' t > ,
879879 parser : & mut ComponentParser ,
880+ l_basis : f32 ,
881+ ab_basis : f32 ,
880882) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
881883 // https://www.w3.org/TR/css-color-4/#funcdef-lab
882884 let res = input. parse_nested_block ( |input| {
883885 parser. parse_relative :: < T > ( input) ?;
884886
885887 // f32::max() does not propagate NaN, so use clamp for now until f32::maximum() is stable.
886- let l = parser . parse_percentage ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
887- let a = parser . parse_number ( input) ?;
888- let b = parser . parse_number ( input) ?;
888+ let l = parse_number_or_percentage ( input, parser , l_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
889+ let a = parse_number_or_percentage ( input, parser , ab_basis ) ?;
890+ let b = parse_number_or_percentage ( input, parser , ab_basis ) ?;
889891 let alpha = parse_alpha ( input, parser) ?;
890892
891893 Ok ( ( l, a, b, alpha) )
@@ -899,6 +901,8 @@ fn parse_lab<'i, 't, T: From<CssColor> + ColorSpace>(
899901fn parse_lch < ' i , ' t , T : From < CssColor > + ColorSpace > (
900902 input : & mut Parser < ' i , ' t > ,
901903 parser : & mut ComponentParser ,
904+ l_basis : f32 ,
905+ c_basis : f32 ,
902906) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
903907 // https://www.w3.org/TR/css-color-4/#funcdef-lch
904908 let res = input. parse_nested_block ( |input| {
@@ -912,8 +916,8 @@ fn parse_lch<'i, 't, T: From<CssColor> + ColorSpace>(
912916 }
913917 }
914918
915- let l = parser . parse_percentage ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
916- let c = parser . parse_number ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
919+ let l = parse_number_or_percentage ( input, parser , l_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
920+ let c = parse_number_or_percentage ( input, parser , c_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
917921 let h = parse_angle_or_number ( input, parser) ?;
918922 let alpha = parse_alpha ( input, parser) ?;
919923
@@ -958,13 +962,13 @@ fn parse_predefined<'i, 't>(
958962 // Out of gamut values should not be clamped, i.e. values < 0 or > 1 should be preserved.
959963 // The browser will gamut-map the color for the target device that it is rendered on.
960964 let a = input
961- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
965+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
962966 . unwrap_or ( 0.0 ) ;
963967 let b = input
964- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
968+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
965969 . unwrap_or ( 0.0 ) ;
966970 let c = input
967- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
971+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
968972 . unwrap_or ( 0.0 ) ;
969973 let alpha = parse_alpha ( input, parser) ?;
970974
@@ -1090,10 +1094,11 @@ fn parse_angle_or_number<'i, 't>(
10901094fn parse_number_or_percentage < ' i , ' t > (
10911095 input : & mut Parser < ' i , ' t > ,
10921096 parser : & ComponentParser ,
1097+ percent_basis : f32 ,
10931098) -> Result < f32 , ParseError < ' i , ParserError < ' i > > > {
10941099 Ok ( match parser. parse_number_or_percentage ( input) ? {
10951100 NumberOrPercentage :: Number { value } => value,
1096- NumberOrPercentage :: Percentage { unit_value } => unit_value,
1101+ NumberOrPercentage :: Percentage { unit_value } => unit_value * percent_basis ,
10971102 } )
10981103}
10991104
@@ -1103,7 +1108,7 @@ fn parse_alpha<'i, 't>(
11031108 parser : & ComponentParser ,
11041109) -> Result < f32 , ParseError < ' i , ParserError < ' i > > > {
11051110 let res = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1106- parse_number_or_percentage ( input, parser) ?. clamp ( 0.0 , 1.0 )
1111+ parse_number_or_percentage ( input, parser, 1.0 ) ?. clamp ( 0.0 , 1.0 )
11071112 } else {
11081113 1.0
11091114 } ;
@@ -1127,6 +1132,7 @@ where
11271132 if a. is_nan ( ) {
11281133 dest. write_str ( "none" ) ?;
11291134 } else {
1135+ // Safari 15 only supports percentages.
11301136 Percentage ( a) . to_css ( dest) ?;
11311137 }
11321138 dest. write_char ( ' ' ) ?;
@@ -1567,7 +1573,7 @@ impl From<LAB> for XYZd50 {
15671573 const E : f32 = 216.0 / 24389.0 ; // 6^3/29^3
15681574
15691575 let lab = lab. resolve_missing ( ) ;
1570- let l = lab. l * 100.0 ;
1576+ let l = lab. l ;
15711577 let a = lab. a ;
15721578 let b = lab. b ;
15731579
@@ -1826,7 +1832,7 @@ impl From<XYZd50> for LAB {
18261832
18271833 let f2 = if z > E { z. cbrt ( ) } else { ( K * z + 16.0 ) / 116.0 } ;
18281834
1829- let l = ( ( 116.0 * f1) - 16.0 ) / 100 .0;
1835+ let l = ( 116.0 * f1) - 16.0 ;
18301836 let a = 500.0 * ( f0 - f1) ;
18311837 let b = 200.0 * ( f1 - f2) ;
18321838 LAB {
0 commit comments