From 6c0cd1139548bc236668d535eb63a1a00aeba9c0 Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 17 Jan 2024 10:44:13 +1100 Subject: [PATCH] Fluid typography: do not calculate fluid font size when min and max viewport widths are equal (#57866) * When the same value is provided for min and max viewport widths in the fluid typography config, do not calculate fluid typography values and return null. We could provide a fallback from the default values in gutenberg_get_typography_font_size_value() but I think it might be better to bypass returning clamp values altogether because fundamentally, the input is wrong. * Comment --- lib/block-supports/typography.php | 14 +++++++++++--- .../src/components/font-sizes/fluid-utils.js | 10 ++++++++-- .../src/components/font-sizes/test/fluid-utils.js | 9 +++++++++ phpunit/block-supports/typography-test.php | 10 ++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index 3cda86cf0a257..b3fa4b4252eed 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -401,10 +401,18 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) { return null; } - // Build CSS rule. - // Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. + // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. + $linear_factor_denominator = $maximum_viewport_width['value'] - $minimum_viewport_width['value']; + if ( empty( $linear_factor_denominator ) ) { + return null; + } + + /* + * Build CSS rule. + * Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. + */ $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; - $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $maximum_viewport_width['value'] - $minimum_viewport_width['value'] ) ); + $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $linear_factor_denominator ) ); $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 ); $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled; $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)"; diff --git a/packages/block-editor/src/components/font-sizes/fluid-utils.js b/packages/block-editor/src/components/font-sizes/fluid-utils.js index b26d542708c37..595011b68bafb 100644 --- a/packages/block-editor/src/components/font-sizes/fluid-utils.js +++ b/packages/block-editor/src/components/font-sizes/fluid-utils.js @@ -181,6 +181,13 @@ export function getComputedFluidTypographyValue( { return null; } + // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. + const linearDenominator = + maximumViewportWidthParsed.value - minimumViewportWidthParsed.value; + if ( ! linearDenominator ) { + return null; + } + // Build CSS rule. // Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. const minViewportWidthOffsetValue = roundToPrecision( @@ -193,8 +200,7 @@ export function getComputedFluidTypographyValue( { const linearFactor = 100 * ( ( maximumFontSizeParsed.value - minimumFontSizeParsed.value ) / - ( maximumViewportWidthParsed.value - - minimumViewportWidthParsed.value ) ); + linearDenominator ); const linearFactorScaled = roundToPrecision( ( linearFactor || 1 ) * scaleFactor, 3 diff --git a/packages/block-editor/src/components/font-sizes/test/fluid-utils.js b/packages/block-editor/src/components/font-sizes/test/fluid-utils.js index 0a1092a1d8128..27b1cfe8c994a 100644 --- a/packages/block-editor/src/components/font-sizes/test/fluid-utils.js +++ b/packages/block-editor/src/components/font-sizes/test/fluid-utils.js @@ -64,6 +64,15 @@ describe( 'getComputedFluidTypographyValue()', () => { ); } ); + it( 'should return `null` when maximum and minimum viewport width are equal', () => { + const fluidTypographyValues = getComputedFluidTypographyValue( { + fontSize: '30px', + minimumViewportWidth: '500px', + maximumViewportWidth: '500px', + } ); + expect( fluidTypographyValues ).toBeNull(); + } ); + it( 'should return a fluid font size when given a scale factor', () => { const fluidTypographyValues = getComputedFluidTypographyValue( { fontSize: '30px', diff --git a/phpunit/block-supports/typography-test.php b/phpunit/block-supports/typography-test.php index f6d5344222678..ec7df51317a3f 100644 --- a/phpunit/block-supports/typography-test.php +++ b/phpunit/block-supports/typography-test.php @@ -933,6 +933,16 @@ public function data_get_computed_fluid_typography_value() { ), 'expected_output' => 'clamp(50px, 3.125rem + ((1vw - 3.2px) * 7.353), 100px)', ), + 'returns `null` when maximum and minimum viewport width are equal' => array( + 'args' => array( + 'minimum_viewport_width' => '800px', + 'maximum_viewport_width' => '800px', + 'minimum_font_size' => '50px', + 'maximum_font_size' => '100px', + 'scale_factor' => 1, + ), + 'expected_output' => null, + ), 'returns `null` when `maximum_viewport_width` is an unsupported unit' => array( 'args' => array( 'minimum_viewport_width' => '320px',