Skip to content

Commit

Permalink
Fluid typography: adjust font size min and max rules (#45536)
Browse files Browse the repository at this point in the history
* Initial commit. No tests.

* Update PHP unit tests

* Updating JS tests
Harmonizing test descriptions across PHP and JS
Updated CHANGELOG.md and README.md

* Updating global styles JS tests

* Update typography props JS units tests to reflect new max value

* Aligning comments acrossing PHP and JS and making sure they're clearer.

Bumping the lower bound from 14px to 16px
Updating tests

* Updating global styles tests

* Revert "Updating global styles tests"

This reverts commit 72d4a38.

* Revert "Aligning comments acrossing PHP and JS and making sure they're clearer."

This reverts commit 863d9ae.
  • Loading branch information
ramonjd committed Nov 10, 2022
1 parent 1b209f7 commit 9928e2c
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 274 deletions.
55 changes: 25 additions & 30 deletions lib/block-supports/typography.php
Expand Up @@ -461,7 +461,6 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
$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';

Expand All @@ -480,21 +479,11 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
// Font sizes.
$preferred_size = gutenberg_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'];
}

// Parses the minimum font size limit, so we can perform checks using it.
$minimum_font_size_limit = gutenberg_get_typography_value_and_unit(
$default_minimum_font_size_limit,
Expand All @@ -503,29 +492,35 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
)
);

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 uses 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 );
if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) {
return $preset['size'];
}
}

// 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_parsed = gutenberg_get_typography_value_and_unit(
$minimum_font_size_raw,
array(
'coerce_to' => $preferred_size['unit'],
)
);

/*
* 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 );
}
$minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit'];
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
### Enhancement

- `BlockLockModal`: Move Icon component out of CheckboxControl label ([#45535](https://github.com/WordPress/gutenberg/pull/45535))
- Fluid typography: adjust font size min and max rules ([#45536](https://github.com/WordPress/gutenberg/pull/45536)).

## 10.4.0 (2022-11-02)

Expand Down
1 change: 0 additions & 1 deletion packages/block-editor/README.md
Expand Up @@ -428,7 +428,6 @@ _Parameters_
- _args.minimumFontSize_ `?string`: Minimum font size for any clamp() calculation. Optional.
- _args.scaleFactor_ `?number`: A scale factor to determine how fast a font scales within boundaries. Optional.
- _args.minimumFontSizeFactor_ `?number`: How much to scale defaultFontSize by to derive minimumFontSize. Optional.
- _args.maximumFontSizeFactor_ `?number`: How much to scale defaultFontSize by to derive maximumFontSize. Optional.

_Returns_

Expand Down
101 changes: 37 additions & 64 deletions packages/block-editor/src/components/font-sizes/fluid-utils.js
Expand Up @@ -9,7 +9,6 @@ const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px';
const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '768px';
const DEFAULT_SCALE_FACTOR = 1;
const DEFAULT_MINIMUM_FONT_SIZE_FACTOR = 0.75;
const DEFAULT_MAXIMUM_FONT_SIZE_FACTOR = 1.5;
const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px';

/**
Expand Down Expand Up @@ -41,7 +40,6 @@ const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px';
* @param {?string} args.minimumFontSize Minimum font size for any clamp() calculation. Optional.
* @param {?number} args.scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional.
* @param {?number} args.minimumFontSizeFactor How much to scale defaultFontSize by to derive minimumFontSize. Optional.
* @param {?number} args.maximumFontSizeFactor How much to scale defaultFontSize by to derive maximumFontSize. Optional.
*
* @return {string|null} A font-size value using clamp().
*/
Expand All @@ -53,15 +51,8 @@ export function getComputedFluidTypographyValue( {
maximumViewPortWidth = DEFAULT_MAXIMUM_VIEWPORT_WIDTH,
scaleFactor = DEFAULT_SCALE_FACTOR,
minimumFontSizeFactor = DEFAULT_MINIMUM_FONT_SIZE_FACTOR,
maximumFontSizeFactor = DEFAULT_MAXIMUM_FONT_SIZE_FACTOR,
minimumFontSizeLimit = DEFAULT_MINIMUM_FONT_SIZE_LIMIT,
} ) {
/*
* Caches minimumFontSize in minimumFontSizeValue
* so we can check if minimumFontSize exists later.
*/
let minimumFontSizeValue = minimumFontSize;

/*
* Calculates missing minimumFontSize and maximumFontSize from
* defaultFontSize if provided.
Expand All @@ -75,15 +66,6 @@ export function getComputedFluidTypographyValue( {
return null;
}

// If no minimumFontSize is provided, derive using min scale factor.
if ( ! minimumFontSizeValue ) {
minimumFontSizeValue =
roundToPrecision(
fontSizeParsed.value * minimumFontSizeFactor,
3
) + fontSizeParsed.unit;
}

// Parses the minimum font size limit, so we can perform checks using it.
const minimumFontSizeLimitParsed = getTypographyValueAndUnit(
minimumFontSizeLimit,
Expand All @@ -92,57 +74,51 @@ export function getComputedFluidTypographyValue( {
}
);

if ( !! minimumFontSizeLimitParsed?.value ) {
// Don't enforce minimum font size if a font size has explicitly set a min and max value.
if (
!! minimumFontSizeLimitParsed?.value &&
! minimumFontSize &&
! maximumFontSize
) {
/*
* If a minimum size was not passed to this function
* and the user-defined font size is lower than `minimumFontSizeLimit`,
* then uses the user-defined font size as the minimum font-size.
* and the user-defined font size is lower than $minimum_font_size_limit,
* do not calculate a fluid value.
*/
if (
! minimumFontSize &&
fontSizeParsed?.value < minimumFontSizeLimitParsed?.value
) {
minimumFontSizeValue = `${ fontSizeParsed.value }${ fontSizeParsed.unit }`;
} else {
const minimumFontSizeParsed = getTypographyValueAndUnit(
minimumFontSizeValue,
{
coerceTo: fontSizeParsed.unit,
}
);

/*
* Otherwise, if the passed or calculated minimum font size is lower than `minimumFontSizeLimit`
* use `minimumFontSizeLimit` instead.
*/
if (
!! minimumFontSizeParsed?.value &&
minimumFontSizeParsed.value <
minimumFontSizeLimitParsed.value
) {
minimumFontSizeValue = `${ minimumFontSizeLimitParsed.value }${ minimumFontSizeLimitParsed.unit }`;
}
if ( fontSizeParsed?.value <= minimumFontSizeLimitParsed?.value ) {
return null;
}
}

// If no maximumFontSize is provided, derive using max scale factor.
// If no fluid max font size is available use the incoming value.
if ( ! maximumFontSize ) {
maximumFontSize =
roundToPrecision(
fontSizeParsed.value * maximumFontSizeFactor,
3
) + fontSizeParsed.unit;
maximumFontSize = `${ fontSizeParsed.value }${ fontSizeParsed.unit }`;
}
}

// Return early if one of the provided inputs is not provided.
if ( ! minimumFontSizeValue || ! maximumFontSize ) {
return null;
/*
* If no minimumFontSize is provided, create one using
* the given font size multiplied by the min font size scale factor.
*/
if ( ! minimumFontSize ) {
const calculatedMinimumFontSize = roundToPrecision(
fontSizeParsed.value * minimumFontSizeFactor,
3
);

// Only use calculated min font size if it's > $minimum_font_size_limit value.
if (
!! minimumFontSizeLimitParsed?.value &&
calculatedMinimumFontSize < minimumFontSizeLimitParsed?.value
) {
minimumFontSize = `${ minimumFontSizeLimitParsed.value }${ minimumFontSizeLimitParsed.unit }`;
} else {
minimumFontSize = `${ calculatedMinimumFontSize }${ fontSizeParsed.unit }`;
}
}
}

// Grab the minimum font size and normalize it in order to use the value for calculations.
const minimumFontSizeParsed =
getTypographyValueAndUnit( minimumFontSizeValue );
const minimumFontSizeParsed = getTypographyValueAndUnit( minimumFontSize );

// We get a 'preferred' unit to keep units consistent when calculating,
// otherwise the result will not be accurate.
Expand All @@ -159,12 +135,9 @@ export function getComputedFluidTypographyValue( {
}

// Uses rem for accessible fluid target font scaling.
const minimumFontSizeRem = getTypographyValueAndUnit(
minimumFontSizeValue,
{
coerceTo: 'rem',
}
);
const minimumFontSizeRem = getTypographyValueAndUnit( minimumFontSize, {
coerceTo: 'rem',
} );

// Viewport widths defined for fluid typography. Normalize units
const maximumViewPortWidthParsed = getTypographyValueAndUnit(
Expand Down Expand Up @@ -205,7 +178,7 @@ export function getComputedFluidTypographyValue( {
);
const fluidTargetFontSize = `${ minimumFontSizeRem.value }${ minimumFontSizeRem.unit } + ((1vw - ${ viewPortWidthOffset }) * ${ linearFactorScaled })`;

return `clamp(${ minimumFontSizeValue }, ${ fluidTargetFontSize }, ${ maximumFontSize })`;
return `clamp(${ minimumFontSize }, ${ fluidTargetFontSize }, ${ maximumFontSize })`;
}

/**
Expand Down
Expand Up @@ -33,7 +33,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
fontSize: '30px',
} );
expect( fluidTypographyValues ).toBe(
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 2.704), 45px)'
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 0.901), 30px)'
);
} );

Expand All @@ -42,7 +42,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
fontSize: '30px',
} );
expect( fluidTypographyValues ).toBe(
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 2.704), 45px)'
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 0.901), 30px)'
);
} );

Expand All @@ -53,7 +53,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
maximumViewPortWidth: '1000px',
} );
expect( fluidTypographyValues ).toBe(
'clamp(22.5px, 1.406rem + ((1vw - 5px) * 4.5), 45px)'
'clamp(22.5px, 1.406rem + ((1vw - 5px) * 1.5), 30px)'
);
} );

Expand All @@ -63,7 +63,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
scaleFactor: '2',
} );
expect( fluidTypographyValues ).toBe(
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 5.409), 45px)'
'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 1.803), 30px)'
);
} );

Expand All @@ -74,7 +74,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
maximumFontSizeFactor: '2',
} );
expect( fluidTypographyValues ).toBe(
'clamp(15px, 0.938rem + ((1vw - 7.68px) * 5.409), 60px)'
'clamp(15px, 0.938rem + ((1vw - 7.68px) * 1.803), 30px)'
);
} );

Expand Down
Expand Up @@ -42,7 +42,7 @@ describe( 'getTypographyClassesAndStyles', () => {
style: {
letterSpacing: '22px',
fontSize:
'clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 2.885), 3rem)',
'clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 0.962), 2rem)',
textTransform: 'uppercase',
},
} );
Expand Down

0 comments on commit 9928e2c

Please sign in to comment.