From 43e21c29f9eeb7885d53bf0fd7cfa3d2b89248e7 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Fri, 11 Nov 2022 17:54:23 +0000 Subject: [PATCH] Editor: Improve how `min`/`max` font sizes are calculated for fluid typography. - Where no fluid max values are set (e.g., single or custom font size values), the "size" value will act as the maximum value in a `clamp()` function. - In the absence of any fluid `min`/`max` values, the lower bound rule of `>16px` will be enforced. This applies to custom values from the editor or single-value `theme.json` styles. Font sizes below this will not be clamped. - In a preset, if a `fluid.min` value has been specified, the lower bound rule of `>16px` won't be enforced on this value. Presets with a fluid object therefore, give precedence to theme author's values. - In a preset, if there is NOT a `fluid.max` but there is `fluid.min`, use the incoming "size" value as the `max`. - In a preset, if there is NOT a `fluid.min` but there is a `fluid.max`, use `size * min_size_factor` as the `min`. The lower bound rule of `>16px` is enforced here, because the block editor is computing the `min` value. This is consistent with the way minimum sizes are calculated for single or custom values. Props ramonopoly, mamaduka, andrewserong, aristath, joen, desrosj. Merges [54823] to the 6.1 branch. Fixes #57075. git-svn-id: https://develop.svn.wordpress.org/branches/6.1@54825 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/typography.php | 64 +++---- .../tests/block-supports/typography.php | 157 +++++++++--------- 2 files changed, 109 insertions(+), 112 deletions(-) diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php index 2a1d90f55e..c571d88b1d 100644 --- a/src/wp-includes/block-supports/typography.php +++ b/src/wp-includes/block-supports/typography.php @@ -452,6 +452,7 @@ function wp_get_computed_fluid_typography_value( $args = array() ) { * formula depending on available, valid values. * * @since 6.1.0 + * @since 6.1.1 Adjusted rules for min and max font sizes. * * @param array $preset { * Required. fontSizes preset value as seen in theme.json. @@ -489,7 +490,6 @@ function wp_get_typography_font_size_value( $preset, $should_use_fluid_typograph $default_maximum_viewport_width = '1600px'; $default_minimum_viewport_width = '768px'; $default_minimum_font_size_factor = 0.75; - $default_maximum_font_size_factor = 1.5; $default_scale_factor = 1; $default_minimum_font_size_limit = '14px'; @@ -508,22 +508,15 @@ function wp_get_typography_font_size_value( $preset, $should_use_fluid_typograph // Font sizes. $preferred_size = wp_get_typography_value_and_unit( $preset['size'] ); - // Protect against unsupported units. + // Protects against unsupported units. if ( empty( $preferred_size['unit'] ) ) { return $preset['size']; } - // If no fluid max font size is available, create one using max font size factor. - if ( ! $maximum_font_size_raw ) { - $maximum_font_size_raw = round( $preferred_size['value'] * $default_maximum_font_size_factor, 3 ) . $preferred_size['unit']; - } - - // If no fluid min font size is available, create one using min font size factor. - if ( ! $minimum_font_size_raw ) { - $minimum_font_size_raw = round( $preferred_size['value'] * $default_minimum_font_size_factor, 3 ) . $preferred_size['unit']; - } - - // Normalizes the minimum font size limit according to the incoming unit, so we can perform checks using it. + /* + * Normalizes the minimum font size limit according to the incoming unit, + * in order to perform comparative checks. + */ $minimum_font_size_limit = wp_get_typography_value_and_unit( $default_minimum_font_size_limit, array( @@ -531,29 +524,38 @@ function wp_get_typography_font_size_value( $preset, $should_use_fluid_typograph ) ); - if ( ! empty( $minimum_font_size_limit ) ) { + // Don't enforce minimum font size if a font size has explicitly set a min and max value. + if ( ! empty( $minimum_font_size_limit ) && ( ! $minimum_font_size_raw && ! $maximum_font_size_raw ) ) { /* * If a minimum size was not passed to this function * and the user-defined font size is lower than $minimum_font_size_limit, - * then use the user-defined font size as the minimum font-size. + * do not calculate a fluid value. */ - if ( ! isset( $fluid_font_size_settings['min'] ) && $preferred_size['value'] < $minimum_font_size_limit['value'] ) { - $minimum_font_size_raw = implode( '', $preferred_size ); - } else { - $minimum_font_size_parsed = wp_get_typography_value_and_unit( - $minimum_font_size_raw, - array( - 'coerce_to' => $preferred_size['unit'], - ) - ); + if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) { + return $preset['size']; + } + } - /* - * If the passed or calculated minimum font size is lower than $minimum_font_size_limit - * use $minimum_font_size_limit instead. - */ - if ( ! empty( $minimum_font_size_parsed ) && $minimum_font_size_parsed['value'] < $minimum_font_size_limit['value'] ) { - $minimum_font_size_raw = implode( '', $minimum_font_size_limit ); - } + // If no fluid max font size is available use the incoming value. + if ( ! $maximum_font_size_raw ) { + $maximum_font_size_raw = $preferred_size['value'] . $preferred_size['unit']; + } + + /* + * If no minimumFontSize is provided, create one using + * the given font size multiplied by the min font size scale factor. + */ + if ( ! $minimum_font_size_raw ) { + $calculated_minimum_font_size = round( + $preferred_size['value'] * $default_minimum_font_size_factor, + 3 + ); + + // Only use calculated min font size if it's > $minimum_font_size_limit value. + if ( ! empty( $minimum_font_size_limit ) && $calculated_minimum_font_size <= $minimum_font_size_limit['value'] ) { + $minimum_font_size_raw = $minimum_font_size_limit['value'] . $minimum_font_size_limit['unit']; + } else { + $minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit']; } } diff --git a/tests/phpunit/tests/block-supports/typography.php b/tests/phpunit/tests/block-supports/typography.php index fb97de4deb..b9d16fbdf4 100644 --- a/tests/phpunit/tests/block-supports/typography.php +++ b/tests/phpunit/tests/block-supports/typography.php @@ -292,6 +292,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { * Tests generating font size values, including fluid formulae, from fontSizes preset. * * @ticket 56467 + * @ticket 57065 * * @covers ::wp_get_typography_font_size_value * @@ -320,7 +321,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { */ public function data_generate_font_size_preset_fixtures() { return array( - 'default_return_value' => array( + 'returns value when fluid typography is deactivated' => array( 'font_size_preset' => array( 'size' => '28px', ), @@ -328,7 +329,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => '28px', ), - 'size: int 0' => array( + 'returns value where font size is 0' => array( 'font_size_preset' => array( 'size' => 0, ), @@ -336,7 +337,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => 0, ), - 'size: string 0' => array( + "returns value where font size is '0'" => array( 'font_size_preset' => array( 'size' => '0', ), @@ -344,7 +345,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => '0', ), - 'default_return_value_when_size_is_undefined' => array( + 'returns value where `size` is `null`' => array( 'font_size_preset' => array( 'size' => null, ), @@ -352,7 +353,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => null, ), - 'default_return_value_when_fluid_is_false' => array( + 'returns value when fluid is `false`' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => false, @@ -361,7 +362,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => '28px', ), - 'default_return_value_when_value_is_already_clamped' => array( + 'returns already clamped value' => array( 'font_size_preset' => array( 'size' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', 'fluid' => false, @@ -370,7 +371,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', ), - 'default_return_value_with_unsupported_unit' => array( + 'returns value with unsupported unit' => array( 'font_size_preset' => array( 'size' => '1000%', 'fluid' => false, @@ -379,57 +380,65 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => '1000%', ), - 'return_fluid_value' => array( + 'returns clamp value with rem min and max units' => array( 'font_size_preset' => array( 'size' => '1.75rem', ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(1.313rem, 1.313rem + ((1vw - 0.48rem) * 2.523), 2.625rem)', + 'expected_output' => 'clamp(1.313rem, 1.313rem + ((1vw - 0.48rem) * 0.84), 1.75rem)', ), - 'return_fluid_value_with_floats_with_units' => array( - 'font_size_preset' => array( + 'returns clamp value with em min and max units' => array( + 'font_size' => array( + 'size' => '1.75em', + ), + 'should_use_fluid_typography' => true, + 'expected_output' => 'clamp(1.313em, 1.313rem + ((1vw - 0.48em) * 0.84), 1.75em)', + ), + + 'returns clamp value for floats' => array( + 'font_size' => array( 'size' => '100.175px', ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(75.131px, 4.696rem + ((1vw - 7.68px) * 9.03), 150.263px)', + 'expected_output' => 'clamp(75.131px, 4.696rem + ((1vw - 7.68px) * 3.01), 100.175px)', ), - 'return_fluid_value_with_integer_coerced_to_px' => array( + 'coerces integer to `px` and returns clamp value' => array( 'font_size_preset' => array( 'size' => 33, ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(24.75px, 1.547rem + ((1vw - 7.68px) * 2.975), 49.5px)', + 'expected_output' => 'clamp(24.75px, 1.547rem + ((1vw - 7.68px) * 0.992), 33px)', ), - 'return_fluid_value_with_float_coerced_to_px' => array( + 'coerces float to `px` and returns clamp value' => array( 'font_size_preset' => array( 'size' => 100.23, ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(75.173px, 4.698rem + ((1vw - 7.68px) * 9.035), 150.345px)', + 'expected_output' => 'clamp(75.173px, 4.698rem + ((1vw - 7.68px) * 3.012), 100.23px)', ), - 'return_default_fluid_values_with_empty_fluid_array' => array( + 'returns clamp value when `fluid` is empty array' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => array(), ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', + 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 0.841), 28px)', ), - 'return_default_fluid_values_with_null_value' => array( + 'returns clamp value when `fluid` is `null`' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => null, ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', + 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 0.841), 28px)', ), - 'return_clamped_value_if_min_font_size_is_greater_than_max' => array( + 'returns clamp value if min font size is greater than max' => array( 'font_size_preset' => array( 'size' => '3rem', 'fluid' => array( @@ -441,7 +450,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => 'clamp(5rem, 5rem + ((1vw - 0.48rem) * -5.769), 32px)', ), - 'return_size_with_invalid_fluid_units' => array( + 'returns value with invalid min/max fluid units' => array( 'font_size_preset' => array( 'size' => '10em', 'fluid' => array( @@ -453,15 +462,23 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => '10em', ), - 'return_clamped_size_where_no_min_is_given_and_less_than_default_min_size' => array( + 'returns value when size is < lower bounds and no fluid min/max set' => array( 'font_size_preset' => array( 'size' => '3px', ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(3px, 0.188rem + ((1vw - 7.68px) * 0.18), 4.5px)', + 'expected_output' => '3px', ), - 'return_fluid_clamp_value_with_different_min_max_units' => array( + 'returns value when size is equal to lower bounds and no fluid min/max set' => array( + 'font_size' => array( + 'size' => '14px', + ), + 'should_use_fluid_typography' => true, + 'expected_output' => '14px', + ), + + 'returns clamp value with different min max units' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => array( @@ -473,7 +490,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => 'clamp(20px, 1.25rem + ((1vw - 7.68px) * 93.75), 50rem)', ), - 'return_clamp_value_with_default_fluid_max_value' => array( + 'returns clamp value where no fluid max size is set' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => array( @@ -481,10 +498,10 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { ), ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(2.6rem, 2.6rem + ((1vw - 0.48rem) * 0.048), 42px)', + 'expected_output' => 'clamp(2.6rem, 2.6rem + ((1vw - 0.48rem) * -1.635), 28px)', ), - 'default_return_clamp_value_with_default_fluid_min_value' => array( + 'returns clamp value where no fluid min size is set' => array( 'font_size_preset' => array( 'size' => '28px', 'fluid' => array( @@ -495,53 +512,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 7.091), 80px)', ), - 'should_adjust_computed_min_in_px_to_min_limit' => array( - 'font_size_preset' => array( - 'size' => '14px', - ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(14px, 0.875rem + ((1vw - 7.68px) * 0.841), 21px)', - ), - - 'should_adjust_computed_min_in_rem_to_min_limit' => array( - 'font_size_preset' => array( - 'size' => '1.1rem', - ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.48rem) * 1.49), 1.65rem)', - ), - - 'default_return_clamp_value_with_replaced_fluid_min_value_in_em' => array( - 'font_size_preset' => array( - 'size' => '1.1em', - ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.875em, 0.875rem + ((1vw - 0.48em) * 1.49), 1.65em)', - ), - - 'should_adjust_fluid_min_value_in_px_to_min_limit' => array( - 'font_size_preset' => array( - 'size' => '20px', - 'fluid' => array( - 'min' => '12px', - ), - ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(14px, 0.875rem + ((1vw - 7.68px) * 1.923), 30px)', - ), - - 'should_adjust_fluid_min_value_in_rem_to_min_limit' => array( - 'font_size_preset' => array( - 'size' => '1.5rem', - 'fluid' => array( - 'min' => '0.5rem', - ), - ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.48rem) * 2.644), 2.25rem)', - ), - - 'should_adjust_fluid_min_value_but_honor_max_value' => array( + 'should not apply lower bound test when fluid values are set' => array( 'font_size_preset' => array( 'size' => '1.5rem', 'fluid' => array( @@ -550,10 +521,32 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { ), ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.48rem) * 7.933), 5rem)', + 'expected_output' => 'clamp(0.5rem, 0.5rem + ((1vw - 0.48rem) * 8.654), 5rem)', ), - 'should_return_fluid_value_when_min_and_max_font_sizes_are_equal' => array( + 'should not apply lower bound test when only fluid min is set' => array( + 'font_size' => array( + 'size' => '20px', + 'fluid' => array( + 'min' => '12px', + ), + ), + 'should_use_fluid_typography' => true, + 'expected_output' => 'clamp(12px, 0.75rem + ((1vw - 7.68px) * 0.962), 20px)', + ), + + 'should not apply lower bound test when only fluid max is set' => array( + 'font_size' => array( + 'size' => '0.875rem', + 'fluid' => array( + 'max' => '20rem', + ), + ), + 'should_use_fluid_typography' => true, + 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.48rem) * 36.779), 20rem)', + ), + + 'returns clamp value when min and max font sizes are equal' => array( 'font_size_preset' => array( 'size' => '4rem', 'fluid' => array( @@ -573,6 +566,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { * when "settings.typography.fluid" is set to true. * * @ticket 56467 + * @ticket 57065 * * @covers ::wp_register_typography_support * @@ -637,7 +631,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'return_value_with_fluid_typography' => array( 'font_size_value' => '50px', 'should_use_fluid_typography' => true, - 'expected_output' => 'font-size:clamp(37.5px, 2.344rem + ((1vw - 7.68px) * 4.507), 75px);', + 'expected_output' => 'font-size:clamp(37.5px, 2.344rem + ((1vw - 7.68px) * 1.502), 50px);', ), ); } @@ -648,6 +642,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { * and the correct block content is generated. * * @ticket 56467 + * @ticket 57065 * * @dataProvider data_generate_replace_inline_font_styles_with_fluid_values_fixtures * @@ -695,7 +690,7 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'block_content' => '', 'font_size_value' => '4rem', 'should_use_fluid_typography' => true, - 'expected_output' => '', + 'expected_output' => '', ), 'return_content_if_no_inline_font_size_found' => array( 'block_content' => '

A paragraph inside a group

', @@ -713,13 +708,13 @@ class Tests_Block_Supports_Typography extends WP_UnitTestCase { 'block_content' => '

A paragraph inside a group

', 'font_size_value' => '20px', 'should_use_fluid_typography' => true, - 'expected_output' => '

A paragraph inside a group

', + 'expected_output' => '

A paragraph inside a group

', ), 'return_content_with_first_match_replace_only' => array( 'block_content' => "
\n \n

A paragraph inside a group

", 'font_size_value' => '1.5em', 'should_use_fluid_typography' => true, - 'expected_output' => "
\n \n

A paragraph inside a group

", + 'expected_output' => "
\n \n

A paragraph inside a group

", ), ); }