Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fluid typography: adjust font size min and max rules #45536

Merged
merged 9 commits into from Nov 10, 2022
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;
Copy link
Member Author

@ramonjd ramonjd Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed since we never need to compute the max size. We fallback to the incoming "size" or single/custom value. See issue: #45504

$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.
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
*
* @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.
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
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