Skip to content

USWDS - Card: Fix $theme-card-border-width calculation errors #5325

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

Merged
merged 7 commits into from
Aug 11, 2023

Conversation

mahoneycm
Copy link
Contributor

@mahoneycm mahoneycm commented Jun 7, 2023

Summary

Fixed a bug that prevented $theme-card-border-width from accepting 0 or string tokens.

Breaking change

This is not a breaking change.

Related issue

Closes #5162

Related pull requests

Changelog entry →

Preview link

Card storybook preview →
Test repo →

Problem statement

Setting $theme-card-border-width to zero

This caused errors when setting the card radius using the calc() function because calc() cannot take unitless numbers1

Screenshot 2023-02-23 at 11 20 30 AM

Setting $theme-card-border-width to a string token

Exdent variants of card use the variable to set a negative border width the following calculation:

@include u-margin-x(-$theme-card-border-width);

When using a string token like "05", this results in u-margin-x(-"05") which breaks the margin function because it is not a valid USWDS token

image

Solution

  1. Update $system-spacing.special 0 value from 0: 0 to 0: spacing-multiple(0)
    • This falls in line with other $system-spacing tokens
      • "05": spacing-multiple(0.5)
      • 1: spacing-multiple(1),
    • units() is the only function that references $project-spacing-standard
    • Resolves this issue anywhere units(0) is used within a calc() function
      • Across USWDS, sass interpolation (#{}) is used within calc() to maintain the rem unit passed in by the units() function
      • #{units($theme-card-border-width)} results in 0rem
      • Other references to units(0) still result in unitless 0
  2. Update method to get negative margins to work with string token values
    • Changed to a solution found in _footer.scss
    • Works with all width tokens mentioned in _border
  3. Swap u-margin mixins for native solutions where $theme-card-border-width is passed in.
    • The margin mixins expect USWDS tokens and will flag an error when it doesn't receive one
- @include u-margin-x(-$theme-card-border-width);
+ magin-inline: units($theme-site-margins-mobile-width * -1); 

Testing and review

  1. Confirm bugs exist
    • On develop, set $theme-card-border-width to 0
    • Inspect .usa-card__img and verify calc() is not working correctly
    • Set $theme-card-border-width to "05" (or another string token)
    • Inspect build error
  2. Checkout USWDS-Sandbox test repo →
    • Recent changes have been pushed to this branch, make sure you pull the latest
  3. $theme-card-border-width will be set to 0 by default
  4. Inspect .usa-card__img and verify calc() is working correctly
  5. Go to _uswds-theme.scss and set $theme-card-border-width to "05"
  6. Verify that there are no build errors
  7. Inspect .usa-card__media--exdent class and check negative margins are set correctly

Testing Checklist

  • $theme-card-border-width: 0 does not break calc() function on .usa-card__img
  • $theme-card-border-width: "05" does not cause build errors
  • No unwanted visual regression

Additional info

I discovered an existing visual bug when setting the border to a large value. I created a ticket at #5401


Before opening this PR, make sure you’ve done whichever of these applies to you:

  • Confirm that this code follows the 18F Front End Coding Style Guide and Accessibility Guide.
  • Run git pull origin [base branch] to pull in the most recent updates from your base and check for merge conflicts. (Often, the base branch is develop).
  • Run npm run prettier:sass to format any Sass updates.
  • Run npm test and confirm that all tests pass.

Footnotes

  1. https://sass-lang.com/documentation/values/calculations#:~:text=Other%20calculations%20don%E2%80%99t%20allow%20unitless%20numbers%20to%20be%20added%20to%2C%20subtracted%20from%2C%20or%20compared%20to%20numbers%20with%20units.

@amyleadem
Copy link
Contributor

Hi @mahoneycm,
I hit a series of warnings when I set $theme-card-border-width: 0 (They should be visible in your sandbox demo if you set $theme-show-compile-warnings to true).

Warning: `0rem` is not a USWDS `margin-horizontal` token. This is OK, but only components built with standard tokens can be accepted back into the system. Standard `margin-horizontal` values: 1px, 2px, 05, 1, 105, 2, 205, 3, neg-1px, neg-2px, neg-05, neg-1, neg-105, neg-2, neg-205, neg-3, neg-4, neg-5, neg-6, neg-7, neg-8, neg-9, neg-10, neg-15, 4, 5, 6, 7, 8, 9, 10, 15, card, card-lg, mobile, 05em, 1em, 105em, 2em, 0, auto

This happens with many of the accepted token values for the setting. Is it possible to resolve these?

@mahoneycm
Copy link
Contributor Author

@amyleadem
CC: @mejiaj

For context, the rem unit is caused by the spacing-multiple() function I added to the 0 value in $system-spacing.special. The functions that do not require the unit, drop the unit on output to just become 0 (example of this below)

how do we feel about resolving the warning by adding 0rem to the $partial-values map? The warning disappears when this one line is added.

$partial-values: (
  zero-zero: (
    0: 0,
+   0rem: 0,
  ),

or by adding a rem specific map similar to $system-spacing-em:

$system-spacing-em: (
  small: (
    "05em": 0.5em,
    1em: 1em,
    105em: 1.5em,
    2em: 2em,
  ),
);

I see a benefit in this because calc() functions require the unit to operate, so we need to be able to pass 0rem to these functions if we want to allow zero values. Functions that do not require the unit will still return a unitless value, such as

$theme-card-border-width: 0;

.usa-card__media--exdent {
  @include u-margin-right(units($theme-card-border-width) * -1);
  @include u-margin-left(0);
}

Returns:
image

Copy link
Contributor

@mejiaj mejiaj left a comment

Choose a reason for hiding this comment

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

I see the warnings Amy mentioned above. We should look at potential alternatives.

For context, the rem unit is caused by the spacing-multiple() function I added to the 0 value in $system-spacing.special. The functions that do not require the unit, drop the unit on output to just become 0 (example of this below)

Are you saying this is what's causing the rem warning on compile? The warnings point to examples like this:

  @include u-margin-left(units($theme-card-border-width) * -1);

Which makes sense because u-margin-left expects tokens, not the value of units().

how do we feel about resolving the warning by adding 0rem to the $partial-values map? The warning disappears when this one line is added.

Adding unit specific values, in this case rem seems like a can of worms. Because then we'd have to add in values for em, px, ch, and any other unit that could potentially fail.

Have we investigated the following?

  1. Swapping utility mixins for native properties so we can pass units().
  2. Using internal logic to check for border width values of 0 or none and then passing that to calc().
  3. Alternatively, we could get rid of calc(), but this doesn't seem like a long term solution.

@mahoneycm
Copy link
Contributor Author

@mejiaj swapping the utility mixins for native properties works. Should I follow that pattern throughout the card scss? Or only where calc() is used?

There also seems to be some general cleanup that can be done here. It references usa-card__header--exdent which isn't mentioned on the guidance page and doesn't seem to cause any changes to the placement of the header.

Let me know if you want me to go ahead and swap the native properties and I can push up a PR. I'll remove the exdent class definition as well and we can discuss from there

@mejiaj
Copy link
Contributor

mejiaj commented Jul 20, 2023

I was originally thinking only where calc() is used. Do you see any issues with this approach?

@mahoneycm
Copy link
Contributor Author

@mejiaj Nope! That sounds good to me and removed the errors in my initial testing! I was just curious on where you stood from a code consistency standpoint. I'll work on getting these updated.

@mahoneycm mahoneycm requested a review from mejiaj July 25, 2023 15:04
@mahoneycm
Copy link
Contributor Author

@mejiaj @amyleadem Updated and ready for review! I also updated the PR description and test repo

I also found a visual bug that exists in develop. Reported at #5401

Copy link
Contributor

@amyleadem amyleadem left a comment

Choose a reason for hiding this comment

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

I appreciate the test you built out, @mahoneycm . Always makes it easy.

Looks good to me!

  • Confirm no compilation or calc errors with string tokens
  • Confirm no compilation or calc errors with 0 value
  • Confirm no visual regression
  • Confirm no compile warnings

Copy link
Contributor

@mejiaj mejiaj left a comment

Choose a reason for hiding this comment

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

Looks good. I didn't find any visual regressions in USWDS or Sandbox branches.

I've tested and can confirm:

  • Zero visual regressions.
  • Zero compile errors.
  • Border width tokens work in $theme-card-border-width1.

Sandbox testing

Thanks for including a test sandbox branch. I made additional changes locally. Changes include:

  • Install and compare USWDS latest.
  • Updating flag default to use media exdent.

Footnotes

  1. ⚠️ Documentation for $theme-card-border-width shows units as token, but border width tokens only support $system-spacing maps for `smaller, small, and zero-zero. See _properties.scss, which depends on spacing.scss

.usa-card__img {
@include u-radius(0);
@include u-radius-right($theme-card-border-radius);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Note
The line change on 271 makes this safe to remove.

Tested with both flag exdent media variants in Sandbox. Example with $theme-card-border-width: "105":

image

@@ -99,7 +99,7 @@ $system-spacing: (
// 1400px
),
"special": (
0: 0,
0: spacing-multiple(0),
Copy link
Contributor

@mejiaj mejiaj Aug 2, 2023

Choose a reason for hiding this comment

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

Curious as to why this was changed? The commit message doesn't seem to mention why. I just see:

Update 0 spacing unit in system-spacing special map

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is outlined under the solution section of the PR description. Essentially, it passes the value as 0rem instead of a unitless 0, which is needed for calc(). SCSS does it's magic and drops the rem unit when it is not needed automatically so it'll remain unitless elsewhere.

  1. Update $system-spacing.special 0 value from 0: 0 to 0: spacing-multiple(0)
  • This falls in line with other $system-spacing tokens
    • "05": spacing-multiple(0.5)
    • 1: spacing-multiple(1),
  • units() is the only function that references $project-spacing-standard
  • Resolves this issue anywhere units(0) is used within a calc() function
    • Across USWDS, sass interpolation (#{}) is used within calc() to maintain the rem unit passed in by the units() function
    • #{units($theme-card-border-width)} results in 0rem
    • Other references to units(0) still result in unitless 0

Copy link
Contributor

Choose a reason for hiding this comment

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

@mahoneycm thanks for the reply and apologies for missing it. I must've confused it since the formatting is similar to the testing & review list 🤦.

Copy link
Contributor

@thisisdano thisisdano left a comment

Choose a reason for hiding this comment

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

Excellent discussion/review to get to a really good, consistent, and understandable solution

@thisisdano thisisdano merged commit 9e86c47 into develop Aug 11, 2023
@thisisdano thisisdano deleted the cm-card-border-width-0 branch August 11, 2023 16:34
@thisisdano thisisdano mentioned this pull request Aug 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

USWDS - Bug: $theme-card-border-width: 0 results in invalidate calc values
4 participants