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

Refactor back link and breadcrumb chevrons to use ems #2998

Merged
merged 7 commits into from
Nov 29, 2022

Conversation

querkmachine
Copy link
Member

@querkmachine querkmachine commented Nov 10, 2022

Currently the back link is measured in pixels. This prevents the arrow from changing size when text zooming is used. Changing this to em units allows the arrow to scale along with the text.

em units have been calculated by taking the previous pixel value and dividing it by the text's pixel size (16).
e.g. 7px ÷ 16px = 0.4375em

Fixes #1717.

100% zoom 400% zoom
Before Screenshot 2022-11-10 at 11 51 45 Screenshot 2022-11-10 at 11 51 53
After Screenshot 2022-11-10 at 11 51 19 Screenshot 2022-11-10 at 11 51 11

A side effect of this is that the chevron now also scales down on small screens, where text is displayed at 14px, which it didn't do previously.

Narrow view
Before Screenshot 2022-11-10 at 16 26 34
After Screenshot 2022-11-10 at 16 26 26

Screenshots from Firefox 106 on macOS 12.6.

Also tested in Chrome 107, Safari 16.0, and Internet Explorers 9 through 11.

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 10, 2022 12:47 Inactive
@querkmachine querkmachine requested a review from a team November 10, 2022 14:25
@querkmachine querkmachine self-assigned this Nov 10, 2022
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 10, 2022 14:56 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 10, 2022 16:20 Inactive
Copy link
Contributor

@colinrotherham colinrotherham left a comment

Choose a reason for hiding this comment

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

Thanks @querkmachine

Looking good 🎉

I've got some suggestions if they make sense?

  1. Keep the border-width at 1px or set min(1px, …)
    On small screens the 14px font size gives a faint 0.875px 0.0625em border

  2. Use ems for the arrow position offset
    We still set a fixed left: 3px

  3. Use ems for the top/bottom pixel offset
    Only used with $govuk-use-legacy-font

Regarding 1) I've noticed we use exact pixel border-widths everywhere.

Is this reason enough to continue with $chevron-border-width: 1px for now? Perhaps holding off until other borders are also ready to adopt ems too?

That said, the "Start now" chevron icon (albeit SVG) scales already

@querkmachine
Copy link
Member Author

Whilst it dipping below 1px equivalent on smaller screens is a concern (and something that should be fixed) I don't think enforcing a 1px border on all sizes makes sense here. The disparity between the visual weight of the arrow and the text starts to look pretty goofy at higher zoom levels, and the lack of relative contrast probably makes this a usability issue.

image

I also think our existing use of absolute pixel borders doesn't apply in this instance—as here we're using borders to graphically hack together a chevron icon, rather than as an actual border around something. I've made it so that the arrow thickness is clamped to a minimum of 1px on browsers that support the CSS clamping functions.

I've implemented the two other suggestions. Notably, there seemed to be duplicated top and bottom declarations being made if $govuk-use-legacy-font was enabled, so I've removed that too.

@querkmachine querkmachine force-pushed the kg-back-link-text-zoom branch from a22d9e5 to 08f162a Compare November 11, 2022 12:43
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 11, 2022 12:43 Inactive
@querkmachine querkmachine force-pushed the kg-back-link-text-zoom branch from 08f162a to 708c422 Compare November 11, 2022 12:47
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 11, 2022 12:47 Inactive
@colinrotherham
Copy link
Contributor

Fab, thanks @querkmachine

Whilst it dipping below 1px equivalent on smaller screens is a concern (and something that should be fixed) I don't think enforcing a 1px border on all sizes makes sense here. The disparity between the visual weight of the arrow and the text starts to look pretty goofy at higher zoom levels, and the lack of relative contrast probably makes this a usability issue.

Yep totally agree as an end goal, just wondered if we'd want to delay it until we fix all borders/outlines/shadows at the same time? Are we happy with the chevron border being scaled relative to the root font size but these ones not?

$govuk-page-width: 960px !default;
$govuk-gutter: 30px !default;
$govuk-border-width: 5px !default;
$govuk-border-width-wide: 10px !default;
$govuk-border-width-narrow: 4px !default;
$govuk-border-width-form-element: 2px !default;
$govuk-focus-width: 3px !default;
$govuk-hover-width: 10px !default;

Regarding max() escaping, do you think we should stick with the unquote("max(…)") approach here?

// Use max() to pick largest margin, default or with safe area
// Escaped due to Sass max() vs. CSS native max()
margin-right: unquote("max(#{$govuk-gutter-half}, #{$gutter-safe-area-right})");
margin-left: unquote("max(#{$govuk-gutter-half}, #{$gutter-safe-area-left})");

bottom: 1px;
$offset: govuk-em(1px, $govuk-root-font-size);
top: $offset * -1;
bottom: $offset;
} @else {
top: 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

@querkmachine You've got me looking at this more now 🙈

Do you think we should let browsers calculate the vertical position instead of assuming top: 0?

For example, applying the old 50% vertical offset trick puts the chevron about 1px lower on mobile. I've added an example from macOS Safari 16.1 with 2x window.devicePixelRatio—looks better aligned?

1st animation frame — original top: 0
2nd animation frame — 50% offset (suggestion)

Back link animation showing 1px vertical shift

Suggested change
top: 0;
top: 50%;
margin-top: $chevron-size / -2

Copy link
Member Author

Choose a reason for hiding this comment

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

This might be a question for the designers, but I think the intent is that the chevron is aligned with the text baseline, rather than being exactly vertically centred?

Copy link
Contributor

@colinrotherham colinrotherham Nov 11, 2022

Choose a reason for hiding this comment

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

Yeah best check, Percy shows it well?

As in, small screens are now (correctly) showing a smaller chevron but it's too high

See how it shifts up ꜛ (not down ꜜ to the baseline) at the new smaller chevron size:

Back link animation showing 1px vertical shift (Percy)

@querkmachine
Copy link
Member Author

Yep totally agree as an end goal, just wondered if we'd want to delay it until we fix all borders/outlines/shadows at the same time?

I don't see any reason to delay it. The implementation here is pretty much entirely self-contained to the Back Link and Breadcrumbs components. Expanding the scope of the initial issue to cover changing every fixed pixel value in the project doesn't seem useful.

Are we happy with the chevron border being scaled relative to the root font size but these ones not?

I'm kinda iffy with these chevrons being scaled based on the root font-size in general. It produces some undesirable outcomes when $govuk-root-font-size is changed, when compared to using em units local to the component.

Using the methodology in my initial commit (though using govuk-em rather than hardcoding values) produces more consistent results in that instance.

$govuk-root-font-size: 16px
html { font-size: 16px }
$govuk-root-font-size: 28px
html { font-size: 28px }
ems using root font-size1 Screenshot 2022-11-11 at 14 20 27 Screenshot 2022-11-11 at 14 21 25
ems using component font-size2 Screenshot 2022-11-11 at 14 29 17 Screenshot 2022-11-11 at 14 29 01

Regarding max() escaping, do you think we should stick with the unquote("max(…)") approach here?

Yeah, that makes more sense. Will update.

Footnotes

  1. Using govuk-em(pixel-value, $govuk-root-font-size).

  2. Equivalent to govuk-em(pixel-value, 16px), based on 16px being the 'default' font-size of the Back Link component.

@querkmachine querkmachine force-pushed the kg-back-link-text-zoom branch from 708c422 to e3c6f35 Compare November 11, 2022 14:41
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 11, 2022 14:42 Inactive
@colinrotherham
Copy link
Contributor

Yeah component font size is 100% what we want (using ems)

But the 16px is adjusted against $govuk-root-font-size in govuk-px-to-rem() via govuk-typography-responsive()

So you'll want a tiny tweak to your example

Before

Component font size only

govuk-em(pixel-value, 16px)

After

Component font size adhering to (potential) $govuk-root-font-size override

govuk-em(pixel-value, 16px / (16px / $govuk-root-font-size))

Feel free to tidy it up, plus 14px small screen variations too 🙈

@querkmachine
Copy link
Member Author

Sorry, but I'm failing to see why we need to concern ourselves with what $govuk-root-font-size, govuk-px-to-rem() or govuk-typography-responsive() are doing.

The text of the back link text is always 14px/16px. That number is converted into a rem-unit equivalent for browsers that support it, but no matter what $govuk-root-font-size is set to, the outcome is always a font-size that is 14px/16px in the browser's rendering engine.

We are then separately using em-units to scale the arrow relative to the back link text—we are always scaling relative to that computed 14px/16px, and (if we stick to basing it on the 16px scale) the resulting conversion will always be 1px = 0.0625em. What we're doing with em units is entirely independent of $govuk-root-font-size, from what I can gather.

@colinrotherham
Copy link
Contributor

Don't worry, I was thinking we were going down the mapped $size: 16 typography scale route

Doubt many people override $govuk-typography-scale do they? If we're using 16px literal pixels, all good!

Here's what I was chucking into the review app's app.scss

html {
  font-size: 62.5%;
}

$govuk-suppressed-warnings: (
  "allow-not-using-rem",
  "compatibility-mode"
);

$govuk-typography-use-rem: false;
$govuk-root-font-size: 10px;

All working nicely with govuk-em(14px, 16px) 👍

@36degrees
Copy link
Contributor

Please don't merge until after v4.4.0 has been released 🚀

@querkmachine querkmachine force-pushed the kg-back-link-text-zoom branch from e3c6f35 to 421b0c6 Compare November 11, 2022 17:17
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 11, 2022 17:17 Inactive
@querkmachine querkmachine changed the title Change back link arrow measurements to use ems Refactor back link and breadcrumb chevrons to use ems Nov 11, 2022
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 14, 2022 14:27 Inactive
@querkmachine querkmachine requested a review from a team November 28, 2022 11:35
@colinrotherham
Copy link
Contributor

@querkmachine Did we get design feedback on the smaller chevron appearing too high in #2998 (comment)?

Percy shows the visual diff

Perceptual alignment

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2998 November 28, 2022 14:55 Inactive
@querkmachine
Copy link
Member Author

@colinrotherham The chevon now maintains a minimum size on browsers that support max(), for consistency with the existing components.

The spacing between breadcrumb items is still different to previous (being em-based), but the total difference is a couple of pixels at most.

@colinrotherham
Copy link
Contributor

@colinrotherham The chevon now maintains a minimum size on browsers that support max(), for consistency with the existing components.

Brill, thanks 🎉

The spacing between breadcrumb items is still different to previous (being em-based), but the total difference is a couple of pixels at most.

On this one, the Percy build shows a bigger change than our Diff sensitivity setting

That said, I'm happy that the spacing is consistent with the font size. Let's check again with @Ciandelle as consistency here might apply to the horizontal spacing too

Spacing changes

@Ciandelle
Copy link

Looks great to me, I don't believe that the horizontal spacing needs to be looked at but worth running past @christopherthomasdesign

@christopherthomasdesign
Copy link
Member

I mean I think it looks fine and doesn't make a huge difference either way.

Sorry I know this is annoying cos I've only just swooped into this... just looking at the horizontal spacing in the preview, where does padding-left: 0.97844em come from? Seems a v specific number, and outputs 15.655px. Mostly just curious really – you could make an equally good argument for that spacing to be 16px (cos it's 1em) or 15px (cos it fits with our spacing scale).

@querkmachine
Copy link
Member Author

@christopherthomasdesign

Sorry I know this is annoying cos I've only just swooped into this... just looking at the horizontal spacing in the preview, where does padding-left: 0.97844em come from? Seems a v specific number, and outputs 15.655px. Mostly just curious really – you could make an equally good argument for that spacing to be 16px (cos it's 1em) or 15px (cos it fits with our spacing scale).

Maths 🙈

The padding calculated from 2 on the spacing scale (10px) plus the "chevron altitude" of 5.655px (calculated with some funky trigonometry here), which totals 15.655px. This is then converted to ems with 16px as the base font-size, resulting in the highly-specific padding value we have currently.

@christopherthomasdesign
Copy link
Member

Gotcha, thanks @querkmachine

Anyways, all looks good to me 👍

Copy link
Contributor

@colinrotherham colinrotherham left a comment

Choose a reason for hiding this comment

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

Fab thorough work here 🎉

Currently the back link is measured in pixels. This prevents the arrow from changing size when text zooming is in use.

Changing this to em units allows the arrow to scale in size with the text.

em units have been calculated by taking the previous pixel value and dividing it by the text's pixel size (16). e.g. 7px ÷ 16px = 0.4375em.
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.

Back link's arrow and border do not scale
7 participants