@@ -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 } ,
@@ -826,22 +826,22 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
826826
827827 match_ignore_ascii_case ! { & * function,
828828 "lab" => {
829- let ( l, a, b, alpha) = parse_lab:: <LAB >( input, & mut parser) ?;
829+ let ( l, a, b, alpha) = parse_lab:: <LAB >( input, & mut parser, 100.0 , 125.0 ) ?;
830830 let lab = LABColor :: LAB ( LAB { l, a, b, alpha } ) ;
831831 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
832832 } ,
833833 "oklab" => {
834- let ( l, a, b, alpha) = parse_lab:: <OKLAB >( input, & mut parser) ?;
834+ let ( l, a, b, alpha) = parse_lab:: <OKLAB >( input, & mut parser, 1.0 , 0.4 ) ?;
835835 let lab = LABColor :: OKLAB ( OKLAB { l, a, b, alpha } ) ;
836836 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
837837 } ,
838838 "lch" => {
839- let ( l, c, h, alpha) = parse_lch:: <LCH >( input, & mut parser) ?;
839+ let ( l, c, h, alpha) = parse_lch:: <LCH >( input, & mut parser, 100.0 , 150.0 ) ?;
840840 let lab = LABColor :: LCH ( LCH { l, c, h, alpha } ) ;
841841 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
842842 } ,
843843 "oklch" => {
844- let ( l, c, h, alpha) = parse_lch:: <OKLCH >( input, & mut parser) ?;
844+ let ( l, c, h, alpha) = parse_lch:: <OKLCH >( input, & mut parser, 1.0 , 0.4 ) ?;
845845 let lab = LABColor :: OKLCH ( OKLCH { l, c, h, alpha } ) ;
846846 Ok ( CssColor :: LAB ( Box :: new( lab) ) )
847847 } ,
@@ -875,15 +875,17 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
875875fn parse_lab < ' i , ' t , T : From < CssColor > + ColorSpace > (
876876 input : & mut Parser < ' i , ' t > ,
877877 parser : & mut ComponentParser ,
878+ l_basis : f32 ,
879+ ab_basis : f32 ,
878880) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
879881 // https://www.w3.org/TR/css-color-4/#funcdef-lab
880882 let res = input. parse_nested_block ( |input| {
881883 parser. parse_relative :: < T > ( input) ?;
882884
883885 // f32::max() does not propagate NaN, so use clamp for now until f32::maximum() is stable.
884- let l = parser . parse_percentage ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
885- let a = parser . parse_number ( input) ?;
886- let b = parser . parse_number ( input) ?;
886+ let l = parse_number_or_percentage ( input, parser , l_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
887+ let a = parse_number_or_percentage ( input, parser , ab_basis ) ?;
888+ let b = parse_number_or_percentage ( input, parser , ab_basis ) ?;
887889 let alpha = parse_alpha ( input, parser) ?;
888890
889891 Ok ( ( l, a, b, alpha) )
@@ -897,6 +899,8 @@ fn parse_lab<'i, 't, T: From<CssColor> + ColorSpace>(
897899fn parse_lch < ' i , ' t , T : From < CssColor > + ColorSpace > (
898900 input : & mut Parser < ' i , ' t > ,
899901 parser : & mut ComponentParser ,
902+ l_basis : f32 ,
903+ c_basis : f32 ,
900904) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
901905 // https://www.w3.org/TR/css-color-4/#funcdef-lch
902906 let res = input. parse_nested_block ( |input| {
@@ -910,8 +914,8 @@ fn parse_lch<'i, 't, T: From<CssColor> + ColorSpace>(
910914 }
911915 }
912916
913- let l = parser . parse_percentage ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
914- let c = parser . parse_number ( input) ?. clamp ( 0.0 , f32:: MAX ) ;
917+ let l = parse_number_or_percentage ( input, parser , l_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
918+ let c = parse_number_or_percentage ( input, parser , c_basis ) ?. clamp ( 0.0 , f32:: MAX ) ;
915919 let h = parse_angle_or_number ( input, parser) ?;
916920 let alpha = parse_alpha ( input, parser) ?;
917921
@@ -956,13 +960,13 @@ fn parse_predefined<'i, 't>(
956960 // Out of gamut values should not be clamped, i.e. values < 0 or > 1 should be preserved.
957961 // The browser will gamut-map the color for the target device that it is rendered on.
958962 let a = input
959- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
963+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
960964 . unwrap_or ( 0.0 ) ;
961965 let b = input
962- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
966+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
963967 . unwrap_or ( 0.0 ) ;
964968 let c = input
965- . try_parse ( |input| parse_number_or_percentage ( input, parser) )
969+ . try_parse ( |input| parse_number_or_percentage ( input, parser, 1.0 ) )
966970 . unwrap_or ( 0.0 ) ;
967971 let alpha = parse_alpha ( input, parser) ?;
968972
@@ -1088,10 +1092,11 @@ fn parse_angle_or_number<'i, 't>(
10881092fn parse_number_or_percentage < ' i , ' t > (
10891093 input : & mut Parser < ' i , ' t > ,
10901094 parser : & ComponentParser ,
1095+ percent_basis : f32 ,
10911096) -> Result < f32 , ParseError < ' i , ParserError < ' i > > > {
10921097 Ok ( match parser. parse_number_or_percentage ( input) ? {
10931098 NumberOrPercentage :: Number { value } => value,
1094- NumberOrPercentage :: Percentage { unit_value } => unit_value,
1099+ NumberOrPercentage :: Percentage { unit_value } => unit_value * percent_basis ,
10951100 } )
10961101}
10971102
@@ -1101,7 +1106,7 @@ fn parse_alpha<'i, 't>(
11011106 parser : & ComponentParser ,
11021107) -> Result < f32 , ParseError < ' i , ParserError < ' i > > > {
11031108 let res = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1104- parse_number_or_percentage ( input, parser) ?. clamp ( 0.0 , 1.0 )
1109+ parse_number_or_percentage ( input, parser, 1.0 ) ?. clamp ( 0.0 , 1.0 )
11051110 } else {
11061111 1.0
11071112 } ;
@@ -1125,6 +1130,7 @@ where
11251130 if a. is_nan ( ) {
11261131 dest. write_str ( "none" ) ?;
11271132 } else {
1133+ // Safari 15 only supports percentages.
11281134 Percentage ( a) . to_css ( dest) ?;
11291135 }
11301136 dest. write_char ( ' ' ) ?;
@@ -1579,7 +1585,7 @@ impl From<LAB> for XYZd50 {
15791585 const E : f32 = 216.0 / 24389.0 ; // 6^3/29^3
15801586
15811587 let lab = lab. resolve_missing ( ) ;
1582- let l = lab. l * 100.0 ;
1588+ let l = lab. l ;
15831589 let a = lab. a ;
15841590 let b = lab. b ;
15851591
@@ -1838,7 +1844,7 @@ impl From<XYZd50> for LAB {
18381844
18391845 let f2 = if z > E { z. cbrt ( ) } else { ( K * z + 16.0 ) / 116.0 } ;
18401846
1841- let l = ( ( 116.0 * f1) - 16.0 ) / 100 .0;
1847+ let l = ( 116.0 * f1) - 16.0 ;
18421848 let a = 500.0 * ( f0 - f1) ;
18431849 let b = 200.0 * ( f1 - f2) ;
18441850 LAB {
0 commit comments