opentable / design-tokens

A place where OpenTable engineers and designers openly work together

Home Page:https://opentable.github.io/design-tokens/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Proposal: Use Pixels, not rems. Automate Rem Conversion

cbeley opened this issue · comments

Before you Read: this is a proposal to automate rem conversion. Rems will still be used for deployed code.

I recently arranged a meeting with Jeff, Frances, Kellen, and I about using pixels. It's fairly widely agreed that, at the very least, using rems is an annoyance. Design also thinks mainly in pixels (probably in large part due to software working in pixels, but it's also just easier to reason about).

I propose we commit only pixel values to this repo and have design as a whole only work with pixels and not bother ever doing any conversion. Then, from an engineering point of view, we have two ways to work with this:

Option 1

Have all teams use https://github.com/cuth/postcss-pxtorem. Pretty much all teams have some sort of CSS build process where including this should not be an issue (and ultimately should be an improvement for most teams, since I doubt many teams have religiously used rems).

mobile-web-frontend has been using it for well over a year now with great success. It's simple and you can just forget about it after adding it.

Option 2

Do Option 1, but also publish rem variables as part of the build process for this repo. This really should just be a fail-safe for the rare possibility that teams can't use pxtorem, but are in a position to use the design tokens repo.

Option 2 I think should only be used if necessary. Also, depending on how certain components get published, it also may become moot.

TLDR: I don't think there are overtly compelling reasons to be messing with rems directly given the tools we have available. If people are generally on board with this, I'd like to move towards educating people and writing up the necessary documentation.

Also, one nuance that probally isn't a consideration, but just to add to the discussion: IE < 11 does not support rem. If for whatever reason we have a project that needs to support older browsers, they would not be able to use design tokens with rems.

I understand using rem is annoying, but pixels are not a good idea for font size and accessibility.

A couple of articles that describe the problem from the other side:
https://medium.com/@julienetienne_/pixels-are-dead-faa87cd8c8b9
https://engageinteractive.co.uk/blog/em-vs-rem-vs-px

Edit
I misunderstood the original proposal (apologies @cbeley 🤣) . I think that if pixels are a better unit measure to reason about for designers, which I expect to be the main maintainers for this repo, I would be in favour of delegating to automation the responsibility of converting back to rems. I actually think we could easily make it part of this build process so that modules would automatically be distributed with rems, if that's what devs would prefer :)

@matteofigus I would suggest re-reading the issue. This is not a proposal to remove rems, it is a proposal to automate the process of rem conversion.

If there's still confusion, come chat with me. Updated the issue to make it clearer though.

Split Option 1 and Option 2 into different comments so we can vote on them. That worked super well last time 😄

But definitely vote for option 1 from me.

Thanks @cbeley for the issue. To make sure I got it right:

  • option 1 = tokens => px; and in consumer-land (when building): import token + use postcss-pxtorem => rem

If that's right I'm for option 1 as well. (I also suggest tokens to expose the base in that case)

Thanks for writing this @cbeley. I agree that writing in REM is annoying and the build process should do this for us. We should use pixel internally end to end, REM only matters for the responsiveness of end result. I support a conversion tool like postcss-pxtorem.

I would just like to remind you one potential gotcha: some pixel values in CSS, such as border width, you would not want them to be converted to REM. postcss-pxtorem has a way to ignore this by writing capital "PX" in the declarations, which some people find unpleasant. It is an easily solvable problem though, we can write a simple postcss rule to ignore all pixel values inside certain declarations.

I've done this as a general policy for years and can't recommend it enough. The reasons being,

  1. That it is easier to reason about pixels, and at the end of the day pixels are the result, so generally pixels are what we think in terms of
  2. So, automatically converting to rem during build removes the burden of mentally converting during development
  3. It's easier to do math with two px measurements and since some measurements will be in px no matter what (e.g. 1px border) it's more consistent to store all tokens as px

In Sass I used a custom function for converting that had a threshold of 3px, so any value below 3px would be output in px. Maybe we can make this suggestion/PR such an option for the PostCSS plugin?

@karuto Could you go a bit more into why border width's shouldn't be converted to rems? I know design has already planned on using rems to specify their border widths (though, really, they were just blindly converting everything) and I havn't seen or heard of any visual issues on mobile web, which does use rems for borders.

I think there's only one place where we had to force pixels and I kind of forgot why now.

Because of sub pixel rounding issues. It's not uncommon for very small rems to end up calculating to fractions of pixels, such that borders either don't render (< 1px) or render too big (> 1px, < 3px). It's not guaranteed to happen, obviously, but in general I've found it happens often enough to code in the threshold and never regret it.

Speaking of which, all browsers changed their zoom models years ago and some people have since asserted it's not strictly necessary to use rems for accessibility anymore. I don't output rems for accessibility alone, I've found it makes code more resilient and flexible, going along with the principle that components should be fluid by default.

@morewry Thanks for the great explanation. Also, I lied about mobile-web-frontend changing border pixels to rems. From the pxtorem documentation:

With the default settings, only font related properties are targeted.

Looks like pxtorem's defaults are rather sane, but tit has other options to deal with exactly what you described.


Anyway, I'll make the two voting options below (though, they are both the same in a way). I think everyone is on board with using pixel values though. I'll start communicating this to design so they can update their pages and I can also help update this repo where necessary.

Vote For This With Thumbs Up: Switch to pixels, require teams to use pxtorem themselves

We'll add documentation about what teams need to add to their build pipeline as well as any special settings they should use if we ever feel the default isn't good enough.

If we later find out option 2 is a hard requirement for teams, we'll just add it, but won't add it until someone really pushes for it.

Vote for this with Thumbs Up: Encourage teams to use pxtorem, but let people import rem values from the get go and modify the build process in this repo to do the conversion.

Same as option 1, but we'll provide a rem module from the get go for those who cannot use pxtorem (or a similar tool).

Alright, it's looking pretty unanimous in regards to people being ok using pixels and in regards to encouraging people to use pxToRem. I'll work with Kellen to help drive this on the design side and try to get some PR's out to document this (and make the switch to pixels if possible).

Closing this, as a PR has been created.

Please take a look at #56.