Skip to content

USWDS - Utilities: Custom breakpoints #6048

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 20 commits into from
Oct 3, 2024
Merged

Conversation

mahoneycm
Copy link
Contributor

@mahoneycm mahoneycm commented Sep 5, 2024

Summary

Continuation of #5985. Thank you for your contribution @jamigibbs.

Added new $theme-utility-breakpoints-custom setting. This setting generates responsive variants of USWDS utility classes at custom breakpoints.

Being able to add a custom breakpoint to the utilities is useful for integrating USWDS with existing frameworks or other design requirements. Custom breakpoints will generate utilities alongside the default system breakpoints.

Sample implementation

To generate a custom breakpoint for your USWDS utilities, add custom breakpoint values to a Sass map for $theme-utility-breakpoints-custom in your USWDS settings configuration. Here is an example implementation:

@use "uswds-core" with (
  $theme-utility-breakpoints-custom: (
    "new-breakpoint": 800px
  )
);

Important

Custom breakpoints must be defined with px values.

Tip

Every breakpoint added to the system adds about 50kb to the compiled CSS. Be careful to only turn on the breakpoints you need for your project. You can turn off default USWDS breakpoints with the $theme-utility-breakpoints setting. More details about $theme-utility-breakpoints can be found on the Settings page.

Breaking change

This is not a breaking change.

Related issue

Closes #5984

Related pull requests

Continuation of #5985

Site documentation update →

Preview link

Preview link →

Problem statement

It is currently not possible for users to implement custom breakpoints and use them alongside our utility classes

Solution

Create new scss map for users to define their own breakpoints and build out utility classes with.

Major changes

  • Created $theme-utility-breakpoints-custom map for users to name and define their own breakpoints
  • Created px-to-user-em() sass function
  • Collect the breakpoints in system properties
  • Update _utility-builder.scss to take custom breakpoints
  • Update at-media mixin to create utility classes with custom breakpoints
  • At this time, breakpoints can only be set in px units.
  • Custom breakpoints follow the same em conversation methods as standard USWDS breakpoints
    • If $theme-respect-user-font-size is true, breakpoints are converted to em
    • If $theme-respect-user-font-size is false, breakpoints are output as px

Testing and review

Testing steps

  1. Checkout feature branch

  2. Visit settings-utilities.scss and add custom breakpoints with px and rem (or some other unit)

    • Ex:
    $theme-utility-breakpoints-custom (
      "bp-px": 64px;
      "bp-rem": 10rem;
    )
  3. Run npx gulp compileSass

  4. Confirm the non px breakpoint triggers Warning message in the terminal.

  5. View output USWDS css at dist/css/uswds.css.

  6. Search for your custom breakpoint by name.

  7. Confirm new media queries are built using values of your custom breakpoints.

  8. Confirm value is correctly converted to em.

  9. Confirm new utility classes are built using the name of your breakpoints.

  10. Confirm non px breakpoints were not built.

  11. Open _settings-typography and set $theme-respect-user-font-size to false !default

  12. Recompile sass npx gulp compileSass

  13. View output USWDS css at dist/css/uswds.css

  14. Confirm breakpoints are now output as px.

Update responsive settings test

Turn on a responsive utility class that is disabled by default and confirm that the custom breakpoints are created for the new utility.

  1. Visit _settings-utilities.scss
  2. Update background-color-settings-complete change responsive: false to responsive: true
  3. Compile sass npx gulp compileSass
  4. View output USWDS css at dist/css/uswds.css
  5. Find your custom breakpoint and confirm bg-(color) utility classes are created for your custom breakpoint

Testing checklist

  • Approve map merge method
  • Approve collecting custom breakpoints in extended system property
  • Confirm approach in the new px-to-user-em sass function is valid.
  • Confirm at-mixin and utility builder properly output breakpoints and utility classes
  • Confirm warning message appears when non px value is used.
  • Updated responsive settings respect new breakpoints.
  • No regressions updating standard breakpoints.

@mahoneycm
Copy link
Contributor Author

mahoneycm commented Sep 16, 2024

Additional consideration: Custom breakpoints + layout grid

This work currently does not build Layout Grid utility classes for the new custom breakpoints, but it would be possible to update _usa-layout-grid.scss to include the custom breakpoints.

Is that something we want to provide to the users with this update? Alternatively, it could be an additional enhancement after this work is merged.

@mahoneycm
Copy link
Contributor Author

@jamigibbs After some discussion, we've opted to only take custom breakpoints in px since it feels like a standard for breakpoints and a common language between designers and developers. We wanted to get your team's opinion on this approach! Do you think this is a valid decision? Are there substantial reasons we should also take in rem or any other units?

I'm unable to tag you as a reviewer for this work, but if you could test this PR to see if it works with your custom breakpoints the way you'd like, it'd be greatly appreciated! All feedback is welcome 👍

Copy link
Contributor Author

@mahoneycm mahoneycm left a comment

Choose a reason for hiding this comment

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

A couple notes on my approach here

Comment on lines +13 to +21
@function px-to-user-em($pixels) {
@if unit($pixels) != "px" {
@error 'This value must be in pixels';
}
$px-to-user-em: px-to-rem($pixels);
$px-to-user-em: rem-to-user-em($px-to-user-em);

@return $px-to-user-em;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I opted not to re-invent the wheel and use functions we already had to convert pixels to rem.

Alternatively, we could use the following sass math conversion if we don't want to rely on the other functions:

  @if unit($pixels) != "px" {
    @error 'This value must be in pixels';
  }
  $px-to-user-em: (math.div($pixels, root.$root-font-size-equiv)) * 1em;
  $px-to-user-em: math.div(math.round($px-to-user-em * 100), 100);

Comment on lines +14 to +16
@if unit($grid-in-rem) != "rem" {
@error 'This value must be in rem';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note: Added error to match other conversion functions

Comment on lines +8 to +10
$our-breakpoints: map-deep-get($system-properties, breakpoints, standard);
$custom-breakpoints: map-deep-get($system-properties, breakpoints, extended);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

note: Moved variable declaration out of mixin since they are used in both at-media and at-media-max

@jamigibbs
Copy link
Contributor

@jamigibbs After some discussion, we've opted to only take custom breakpoints in px since it feels like a standard for breakpoints and a common language between designers and developers. We wanted to get your team's opinion on this approach! Do you think this is a valid decision? Are there substantial reasons we should also take in rem or any other units?

I'm unable to tag you as a reviewer for this work, but if you could test this PR to see if it works with your custom breakpoints the way you'd like, it'd be greatly appreciated! All feedback is welcome 👍

@mahoneycm Thanks Charlie! px will be fine for us. I originally called that out just for visibility but I don't see any reason why it needs to be anything other than px.

I also tested your branch locally with our implementation and it seems to be working great! The custom breakpoints were generating and an error message displayed if I tried to using something other than px.

Screenshot 2024-09-18 at 2 55 37 PM Screenshot 2024-09-18 at 2 18 23 PM

mejiaj pushed a commit to uswds/uswds-sandbox that referenced this pull request Sep 23, 2024
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.

Thanks @mahoneycm. I've been able to successfully test following your instructions. I've created a branch on uswds-sandbox test-uswds-breakpoints-6048, so others can test as well. Links to that testing environment:

Confirming

  • New utils are generated for custom breakpoint
  • Breakpoint is available via at-media
  • Warning on passing non-px values
  • Additional utils are generated
  • Overriding root font size sets media queries with px

Non-pixel values

Confirming that passing non-px values give a warning.

Input

// _uswds-theme.scss
@use "uswds-core" with (
  $theme-utility-breakpoints-custom: (
    "desktop-custom-rem": 70rem // 1120px
  )
);

Output

Warning: Custom breakpoint `desktop-custom-rem` has the unit rem. Custom breakpoints must be set in px.
    ../../../@uswds/uswds/packages/uswds-core/src/styles/mixins/helpers/at-media.scss 35:7  at-media()
    ../../../../src/_styles/_uswds-theme-custom-styles.scss 11:1                            @forward
    ../../../../src/_styles/styles.scss 3:1   

Additional utils

Warning

Adding responsive variants has an impact on CSS compile size.

Confirming that additional utilities are output.

Input

// _uswds-theme.scss
@use "uswds-core" with (
  $theme-utility-breakpoints-custom: (
    "desktop-custom": 1100px,
  ),
  $background-color-settings: (
    responsive: true,
  )
);

Output

/* styles.css */
@media all and (min-width: 68.75em) {
  .desktop-custom\:bg-transparent,
  .desktop-custom\:hover\:bg-transparent:hover {
    background-color: transparent;
  }
  .desktop-custom\:bg-black,
  .desktop-custom\:hover\:bg-black:hover {
    background-color: #000;
  }
  /* … */
}

Overriding root font size

Input

// _uswds-theme.scss
@use "uswds-core" with (
  $theme-utility-breakpoints-custom: (
    "desktop-custom": 1100px,
  ),
  $theme-respect-user-font-size: false,
  $theme-root-font-size: 20px,
);

Output

/* styles.css */
@media all and (min-width: 1100px) {
  /* … */
}

Output CSS size

Output CSS file size after adding a single custom breakpoint. This issue is compounded when we're adding responsive variants on top.

File Before After
styles.css 524KB 572KB

We should create an issue to support at-media without generating utils for performance.

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.

Looking good @mahoneycm! (And thanks for your original work on this @jamigibbs!)

Important

Before I approve, I wanted to highlight that this PR does not generate custom responsive breakpoints for layout grid or icon-list-size classes. I have added additional details in the notes below.

Are we comfortable with this moving forward without these responsive classes?

Everything else is looking good!

Testing details

I tested in uswds-sandbox using the following config:

@use "uswds-core" with (
  $theme-show-compile-warnings: false,
  $theme-show-notifications: false,
  $theme-utility-breakpoints-custom: (
    "new-breakpoint": 800px
  ),
  $theme-utility-breakpoints: (
    widescreen: true,
  ),
  $left-settings: (
    responsive: true
  )
);
  • Confirm the $theme-utility-breakpoints-custom setting generates new style rules for each new pixel-based value in the map
    • Note: There are some gaps in what $theme-utility-breakpoints-custom generates vs $theme-utility-breakpoints
      • Turning on new-breakpoint in $theme-utility-breakpoints-custom generates 898 new references to .new-breakpointin the CSS. Turning on widescreen in $theme-utility-breakpoints generates 1060 new references to .widescreen\:
      • After some digging, discovered that difference was that the custom breakpoint was not generated for:
        • usa-icon-list sizes - for example, it did not generate .new-breakpoint\:usa-icon-list—size-1, but did generate .widescreen\:usa-icon-list—size-1 (In total, there were 90 references for usa-icon-list--size generated for widescreen)
        • layout grid classes - For example, it did not generate .new-breakpoint\:grid-container but did generate .widescreen\:grid-container (In total, 72 grid references were generated for widescreen)
      • For reference, here is the difference in CSS size:
        • with default breakpoints: 524kb
        • with only a new custom breakpoint: 572kb
        • with only an additional standard breakpoint (widescreen): 587kb
  • Confirm there is an appropriate warning in the console when a non-px unit is added to the $theme-utility-breakpoints-custom setting map
    • Note: I added a non-breaking suggestion below to add a bit more clarity to the warning message
  • Confirm that setting $theme-respect-user-font-size: false outputs new breakpoint in px
  • Confirm that setting $theme-respect-user-font-size: true outputs new breakpoint in em
  • Confirm conversion from px to em is accurate (eg, 800px outputs as 50em)
  • Confirm that turning on a responsive variant of a USWDS utility generates the custom breakpoint from $theme-utility-breakpoints-custom as well as the default breakpoints from $theme-utility-breakpoints (I tested $left-settings)
  • Confirm the code meets standards

@amyleadem
Copy link
Contributor

Update: I have opened PR #6083 as a candidate to add support for layout grid utility classes to this PR.

@mejiaj mejiaj requested a review from amyleadem October 1, 2024 15:14
USWDS - Layout grid utility: Custom breakpoints
@amyleadem
Copy link
Contributor

amyleadem commented Oct 1, 2024

Update: I have merged in #6083 after team approval. This adds support for generating custom breakpoints for layout grid utilities.

Will work on finalizing my review of this PR now.

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.

Looks good to me! I do have one suggestion to add detail to the warning message in the comment below, but I don't consider it to be a blocker

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.

Nice feature. Thank you @jamigibbs and @mahoneycm!

@thisisdano thisisdano merged commit 1fb7e32 into develop Oct 3, 2024
5 checks passed
@thisisdano thisisdano deleted the cm-custom-breakpoints branch October 3, 2024 04:17
@thisisdano thisisdano mentioned this pull request Oct 4, 2024
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 - Feature: Add theme setting for custom breakpoints
5 participants