Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fluid typography: adjust font size min and max rules (#45536)
* 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 authored and Mamaduka committed Nov 11, 2022
commit 7d5a6b1a8757123b4523ec9364df85486a0b21a3
55 changes: 25 additions & 30 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
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
4 changes: 4 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancement

- Fluid typography: adjust font size min and max rules ([#45536](https://github.com/WordPress/gutenberg/pull/45536)).

### Bug Fix

- `FontSizePicker`: Update fluid utils so that only string, floats and integers are treated as valid font sizes for the purposes of fluid typography ([#44847](https://github.com/WordPress/gutenberg/pull/44847))
Expand Down
1 change: 0 additions & 1 deletion packages/block-editor/README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading