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

[core] Fix MenuItem text clipping #2265

Merged
merged 13 commits into from
Mar 20, 2018

Conversation

reiv
Copy link
Contributor

@reiv reiv commented Mar 17, 2018

Fixes #2177

Reviewers should focus on:

Does this break anything that uses MenuItem?

Screenshot

fix-clipping

Edit: The font shown here, Segoe UI (Windows default), seems to have a weird baseline, causing it to appear slightly off-center compared to other fonts. This isn't fixable without replacing the font altogether.

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

Merge branch 'develop' into rv/fix-menuitem-clipping

Preview: documentation | landing | table

@giladgray
Copy link
Contributor

this causes menu items to render at 32px height by default, which is going to be very obnoxious to fix. all the padding logic assumes 16px height of icons and text.

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

yeah, also breaks the grid. @reiv any thoughts on how to preserve 30px height for menu items here?

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

Are menu items intended to be single-line? I'm asking because the pt-menu-item style is also applied to the nav links in the documentation, which wrap on longer lines:
menu1
For single line, the obvious solution is to set an absolute height of 30px. Otherwise, we could remove the vertical padding and set line-height to 30px, but that causes multi-line menu items to have too much spacing between lines:
menu2
@llorca Not sure which grid you are referring to here. Is it a design requirement that the height of menu items be a multiple of $pt-grid-size?

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

yes, it's gotta be a multiple of $pt-grid-size ($pt-grid-size * 3.2 doesn't count)

IIRC, by default they're one-liners, but it should be able to override that behavior to get a multiline item with correct line-height

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

removing .pt-text-overflow-ellipsis from the text within .pt-menu-item makes it nice and multiline, can be turned on and off with the multiline prop

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

Oh, so if there's an explicit multiline prop, then couldn't we just style the menu item based on that? For single line, set height: 30px or line-height: 30px and remove vertical padding. For multiline, well, don't. Would that work?

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

I think that could work yes, it's a 2.0 thing

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

Add CSS class for single-line menu items

Preview: documentation | landing | table

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

now the text is down 1px :( looks vertically misaligned. we're going to need at least an 18px line-height then I suppose?

also the multiline mode looks broken?
image

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

@llorca That's weird, considering the change shouldn't affect multiline menu items whatsoever (it only adds a class when multiline == false). What did you do so I can reproduce?

@llorca
Copy link
Contributor

llorca commented Mar 19, 2018

I was just turning pt-text-overflow-ellipsis on and off in the inspector

@reiv
Copy link
Contributor Author

reiv commented Mar 19, 2018

No, you need to use React dev tools to explicitly toggle multiline (or remove the pt-menu-item-single-line class from the outer <a> element as well).

Should look like this:
menu3

Edit: looks like the label icon is off-center in single line mode as a result of line-height: normal.
menu4

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

Apply line-height directly to menu item label

Preview: documentation | landing | table

@@ -45,6 +45,15 @@ $dark-menu-item-color-active: $dark-minimal-button-background-color-active !defa
color: $pt-text-color-disabled;
}

&.pt-menu-item-single-line {
Copy link
Contributor

Choose a reason for hiding this comment

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

😢 sad we need an extra class just for that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alternatively we could define a class for multiline instead. Would that be preferable?

// to be clipped. Instead, we set the height directly to adhere to the
// grid.
height: $pt-grid-size * 3;
line-height: normal;
Copy link
Contributor

@llorca llorca Mar 20, 2018

Choose a reason for hiding this comment

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

normal makes the text misaligned, vertically not centered by 1px. unset seems to work, although I have no idea why?

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 can't see the misalignment on my end, so I'm assuming this is font-specific. Can you post a screenshot please?

Copy link
Contributor

Choose a reason for hiding this comment

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

The misalignment appears in your own screenshot:

Notice how "Settings..." is 1px down

Copy link
Contributor Author

@reiv reiv Mar 20, 2018

Choose a reason for hiding this comment

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

Hm, I thought that was due to Segoe UI's baseline. Here it is with sans-serif (Arial):
menu5

What's odd to me is that changing it from normal to unset has no effect on Firefox*, but on Chrome it does actually fix the misalignment with Segoe UI.

* That is, the computed line-height changes from 20px (normal) to 18px (unset), but visually it's all the same for some reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another problem with unset: Firefox, zoom level 140%, clipping still occurs:
menu6

Copy link
Contributor Author

@reiv reiv Mar 20, 2018

Choose a reason for hiding this comment

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

Had to look up the difference between normal and unset:

normal uses the browser default, whereas unset inherits the nearest parent's value. In this case it would be <body>, which gets its line-height from here:

// a little bit extra to ensure the height comes out to just over 18px (and browser rounds to 18px)
$pt-line-height: ($pt-grid-size * 1.8) / $pt-font-size + 0.0001 !default;

So unset gives us an 18px line height. Furthermore, it seems that in Chrome, odd pixel values for line-height shift everything down by 1px, as shown here:
2018-03-20 05-11-44 flv

This affects most fonts, Arial being one of the exceptions. I'm guessing normal ends up producing an odd pixel value (inspector doesn't show the actual value), causing the misalignment.

@llorca
Copy link
Contributor

llorca commented Mar 20, 2018

@reiv I assume the original clipping was due to the overflow, have we considered going for overflow-x instead of overflow?

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

@llorca Yes, overflow-x was the first thing I tried and it did not work; clipping still occurred. See also this comment from @giladgray.

@llorca
Copy link
Contributor

llorca commented Mar 20, 2018

@reiv going back to the previous 18px line height try, what about:

// no need for single line class
.pt-menu-item {
  line-height: 18px; // math?
  padding: 6px 7px; // with the right variables math
}
.pt-menu-item .pt-icon {
  margin-top: 1px;
}
.pt-menu-item .pt-menu-item-label {
  align-self: flex-start;
}
// maybe some kind of `$vertical-padding-adjustment-size: 1px` variable to do the math above?

this seems to be working solidly on my end, albeit ugly. but if that solves the clipping 🤷‍♂️

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

Set explicit line-height value based on font size

Preview: documentation | landing | table

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

@llorca Ok, cool. 18px might not work for all zoom levels, but I get the idea.

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

Add $menu-item-line-height-factor variable

Preview: documentation | landing | table

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

Add comment

Preview: documentation | landing | table

@llorca
Copy link
Contributor

llorca commented Mar 20, 2018

that looks like progress! I like the fact that we don't need an extra class

a couple of issues to address:

  • text is still misaligned in Chrome, because of the uneven line-height (21px). let's get the math to make it even?
  • it looks like we're having some float padding (4.5px) and float margin (2.5px) which will render blurry on low res screens. let's get the math to round these as well, hopefully it's as easy as tweaking the line height factor variable?

@@ -61,6 +61,7 @@ Styleguide pt-menu
&::before,
.pt-icon {
align-self: flex-start;
Copy link
Contributor

Choose a reason for hiding this comment

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

that flex-start works for the icon on the left side, but not for the item label on the right. can you also add flex start for .pt-menu-item-label on line 69?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@reiv
Copy link
Contributor Author

reiv commented Mar 20, 2018

Ensure line-height is an even value

Preview: documentation | landing | table

Copy link
Contributor

@llorca llorca left a comment

Choose a reason for hiding this comment

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

Ok, I think this is sane. @giladgray for final approval.

Separately, we'll have to fix large menu item style regressions (#2281)

@llorca llorca requested a review from giladgray March 20, 2018 21:11
Copy link
Contributor

@giladgray giladgray left a comment

Choose a reason for hiding this comment

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

this actually looks really good! math is frightening at first, but the change is small and end result is perfect.

one final refactor.

color: $pt-icon-color;
}

.pt-menu-item-label {
align-self: flex-start;
Copy link
Contributor

Choose a reason for hiding this comment

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

seems we can just change .pt-menu-item to align-items: flex-start now, rather than overriding with align-self here and line 63.

Copy link
Contributor

@giladgray giladgray left a comment

Choose a reason for hiding this comment

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

actually, i'm going to merge this so I can work on a fix for #2281 and i'll make the align-items change there.

@giladgray
Copy link
Contributor

@reiv thanks for your hard work on this! end result is 💯 🔥

@giladgray giladgray merged commit 6b107df into palantir:develop Mar 20, 2018
@reiv reiv deleted the rv/fix-menuitem-clipping branch March 21, 2018 01:33
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.

[Core/Menus] pt-text-overflow-ellipsis cuts off descenders for menu items
3 participants