I regularly wonder if it might not be better for the web if we got rid of pixels as a unit entirely. We can't realistically do that for a lot of reasons, and there are legitimate reasons to use pixels sometimes, but resolution independent font-size and container sizing should be the default. If you are using pixels on the web for font sizes, consider this a public intervention that you need to stop.
The fact that `em` units are not related to physical size attributes is intended. We don't want them to be related to physical size -- what `2em` is saying is that you want a piece of text to be twice as large as the "default" size of the specific font on the platform/device. That is a superior way to think about text size, because as a user I don't want you to try and figure out what the pixel density or screen ratio or resolution of my device is.
Size your fonts with `em` and `rem` units, and size your containers based on the number of characters you want to fit in each line. Don't use pixels. It doesn't matter if your fonts are bigger on Mac or Windows. It is intentional that platforms can size their fonts differently, and your interface designs should take that into account.
If anything, native platforms should be moving more in this direction, they should not be moving away from it. There was a period where you could decide to only care about responsive design on the web, but increasingly you should be thinking about responsive design on native platforms too. And resolution-independent font-sizes based on the user/platform are part of that process.
EDIT: Yes, I'm aware that pixels on the web are not necessarily 1:1 ratios with physical pixels on a screen. That doesn't change anything, pixels are still bad to use on the web. Tying font size to resolution, whether that's browser window resolution or physical resolution, is still equally problematic. And it certainly doesn't mean that we should move in the opposite direction on native devices -- the web's pixels are the way they are because the alternative, being tied to literal physical pixels, would be even worse.
I'm sorry, but you seem to be under some misconceptions about how pixel sizing works on the web.
> resolution independent font-size and container sizing should be the default
It already is. CSS "px" doesn't refer to physical pixels at all, they're called logical pixels. Which on old screens at 100% zoom may map 1:1, but these days are more likely to map 2:1 or even 3:1, and with OS and browser zoom levels may be things like 1.666:1 or 2.5:1.
> Size your fonts with `em` and `rem` units
In the browser, em/rem are necessarily defined by a parent/root element that is ultimately defined in either px or pt, so your suggestion doesn't achieve what you think it achieves.
Today, whether you write your CSS in "em" or "px" results in an identical user experience. It's really just whether you prefer to work with a baseline of something like "16px" and use larger round integers (8px, 1000px, etc.) or prefer to work with something like a baseline of "1em" and use small numbers with lots of decimals (0.5rem, 30rem, 0.05rem).
Ultimately we need some measure of consistency, and browsers have long defined that as a default legible body text size of 16 px = 12 pt (= 1 em by default).
> It already is. CSS "px" doesn't refer to physical pixels at all, they're called logical pixels.
Okay, yes, but when people ask what the current resolution of a page is on the web, most of the time they're talking about those logical pixels. You're correct, but also this doesn't change anything about my argument. It's still a mistake to tie layout to the resolution of a web page, regardless of what unit you're using for a pixel.
> Today, whether you write your CSS in "em" or "px" results in an identical user experience.
No it doesn't. Like you said, `em` units are based on the current container font sizes. Pixels aren't.
There's no way in the pixel world to say that you want a container that will always display 40 em-sized characters, and to have that continue to be true even as font size increases and decreases.
You can try this yourself[0]. Set Firefox to Zoom Text Only (View->Zoom), then zoom in/out on a container sized with pixels and a container sized with `em` units. Only the `em` sized container will change its size, because its width is being tied to the font settings so its width scales proportionally as the font size changes.
Just completely forget "resolution" when talking about CSS pixels as they have nothing to do with the actual resolution (virtual or physical) when it comes to layout. A CSS "pixel" is just another way of saying 1/96th an inch just like saying a pt is 1/72 an inch.
Em is indeed "font size * value" which is the difference, and only difference, vs using pt or px or pc or any other absolute sizing reference. Per CSS spec though this is only a difference for the _developer_ not the _user_ as the other person originally stated - either way on any screen at any zoom the results are identical to the user. Well negating the user only zooming portions of the design which, by definition, is not going to give a proportionately scaled design back. Also you can actually implement this in CSS using px you just need to tie it to calc() - though cleaner to just use em if that's all you wanted to do at that point. Like the original commentor said though, eventually em is going to read back to something which defines font size in absolute measures, such as px or pt, so for all of the debate either way eventually your font is all absolute measured based it's just a matter of what the original measure is currently set to (16px by default).
Which comes to what I really wanted to say after clarifying the above, I like defining the root font size in px and using rem everywhere else. In that way I can think in terms of "I want this header to be 3x as large as the base font on the page", easily change the base font to whatever px value I want (scaling all the page text accordingly), and I don't have to worry about inheritance if I change a parent's font size. Best of both worlds between em and px IMO. Like I said you could get the same thing, or something more advanced even, with calc() and a variable but no reason when rem has been built into browsers for ages.
> which is the difference, and only difference, vs using rem or pt or px or pc or any other absolute sizing reference
It's a difference for anyone who changes the default text size in Firefox. The "Zoom Text Only" option works the same way as Firefox's default text sizing. This is a difference that does matter for anyone who adjusts either the default or minimum font size in their browser, it's not theoretical.
> I like defining the root font size in px and using rem everywhere else
This is better than using pixels everywhere. I would not define a root font size in pixels, I would leave it as 1rem. BUT, what you're doing is much, much better than what the article is proposing, so I'm not going to be too critical.
Again by definition "zoom text only" is meant to change the proportions of the design, that the proportions of the design were changed accordingly is not proof the design method is wrong it's proof only text was zoomed. If you use em for everything as a "fix" for this you've actually just broken the whole point of "zoom text only" as it just became functionally identical to "zoom". I.e. there is no way to reconcile "zoom text only" not changing the proportions of the design and having a meaningful "zoom text only" at the same time. That something can't do both is therefore proof of nothing.
The same as above is true for the root font size discussion, if you set it relative and base the page layout on relative than the user's default font size setting also just turns into a proxy for a full page zoom. Again it's not proof in itself that one is right or wrong it's just that you're either going to stomp on the users default font preference by making it zoom everything instead or you're going to have a design that looks wonky for users with high custom font sizes because the layout wasn't made for big text.
> Again by definition "zoom text only" is meant to change the proportions of the design
Not necessarily. Zoom text only is meant to change the font size and by extension things that are based off of the font size. Full-page zoom pretends that the browser window is a different resolution (even reporting a different resolution to Javascript) and then scales the page up in the final rendering step. I don't know that the point is necessarily to preserve/change proportions one way or another, they're different algorithms that affect different parts of the page.
This is still a really, really interesting perspective, arguably the most interesting/compelling justification that I've heard on this entire thread as to why a designer might choose to use pixels for width in a normal layout. But even though you have an interesting and insightful take, I'm not sure I buy that the reason designers are ignoring `em` units is to preserve user choice. And in practice in the real world, I notice that the pages that follow an `em`/`rem` philosophy when thinking about column width tend to handle both resizing of text and full-page zoom better.
Let me ask a question; if the goal of full-page zoom is actually to keep the same proportions for its font-size, if that's really the main difference between font-only zoom and full-page zoom, then is it a problem that full-page zoom doesn't affect percentages or viewport width units? Why draw the line specifically at the ratio of font-size to container width? If the point of full-page zoom is to preserve proportions and ratios, shouldn't it act more like zooming a PDF?
The number of reference pixels reported to JS changes but so does window.devicePixelRatio. In JS this info is given for you to do your own logic with, in CSS it is not. As such it's not "scaled up at the last step" any more than at 100% zoom when CSS finds out that means foo inches at bar zoom is foobar physical px on a certain monitor. This is opposed to MacOS/iOS or Gnome where things are calculated against a reference scale and then that reference is scaled an integer amount and then that rendered bitmap is scaled by the dpi factor to be displayed - in CSS layout dimensions are always just passed to be directly rendered to the display and part of that direct pass is it always has to figure out how many device px the reference px is.
Not to preserve user choice in itself no but em isn't preserving user choice in the end either so it's not an argument to convince either side.
It's a problem in the same way your original example was a problem i.e. there is no way to reconcile all of these with good answers consistently so that a certain layout methodology doesn't is proof of nothing. And all options being imperfect leads to the simpler dimension based layout being popular. Of course that means a relative dimension based layout is no more inherently "wrong" just most find it harder to work with and get nothing new they couldn't have accomplished with any other dimension type + the describing CSS syntax.
Percentage/viewport based layouts independently may be an actual "wrong" choice depending what kind of content the page contains. The CSS spec actually reflects that percentage based layout is a unique design choice - em and px are both a "dimension" type and you can make either do the same thing with CSS if you wanted (that doesn't mean just replace em with px and call it a day but it's always doable) whereas percentage and viewport are their own special "percentage" type and you can't make them always behave like another unit type because they actually represent a unique concept.
At least once or twice a day I’ll find a comment on HN that just 100% completely humbles me. This is that comment. Where do you learn things like this?
Ironically I don't consider myself all that knowledgable at this kind of stuff for the most part - this just happens to be a very particular thing I went deep down the rabbit hole on in a passion project where I was trying to find out how to solve this exact "how should layouts render on different displays" problem. Turns out the web browser's approach to the problem is very elegant even if the specifications have a lot of complexity and warts from organic growth so I spent a lot of time looking at the specs to make sure I understood how I wanted to do my own thing.
In short do fun things you just want to understand and you too can sound much smarter than you are when a certain topic comes up :).
> As such it's not "scaled up at the last step" any more than at 100% zoom when CSS finds out that means foo inches at bar zoom is foobar physical px on a certain monitor.
Technically yes, but practically no. If you zoom in on a screen, CSS breakpoints based on resolution will trigger. As far as your actual CSS styling goes, you can basically think of the page as having a smaller resolution that then gets scaled up after layout is determined. CSS doesn't have access to the information you're talking about, so it's not valuable to a designer to think in those terms -- at least not unless you're planning to embed a bunch of interface logic in Javascript that doesn't belong there.
The end result is that if you zoom in 200% on an 800px wide viewport, from the perspective of the CSS you're writing you are effectively working with a 400px wide viewport.
> but em isn't preserving user choice in the end either so it's not an argument to convince either side.
This continues to be a compelling argument.
What I will say though is that the more I reflect on it, the more this seems to be an argument for using both `px` and `em` units based on the context of the individual component you are styling. It doesn't seem to be an argument for abandoning relative/point units entirely, as the original article advocates. From the perspective that scaling text alongside containers and scaling text inside containers are both valid ways to scale content, there are going to be some parts of your interface where it makes sense to respond to text size increasing, and some parts that don't.
So for example, I can buy that for a main paragraph, you might want users to have the ability to scale text independently of the column width. But while you're doing that, you probably still want labels to fit inside of buttons. Similarly, you probably don't want the text options on a dropdown menu to overlap with each other and make each other unclickable. And more typographically, you want margins between your paragraphs to remain readable.
So maybe in that scenario if you're maximizing user choice it makes sense to leave you main column in pixels and to only set menus, buttons, and paragraph spacing and margins in `em` units. I could see something like that being reasonable.
The ending of your comment confuses me. I've never heard someone say that percentage-based layouts are explicitly the "wrong" choice, sometimes it does make sense to have a 2-column 50% layout. More specifically:
> `em` and `px` are both a "dimension" type and you can make either do the same thing with CSS if you wanted (that doesn't mean just replace em with px and call it a day but it's always doable)
`em` is a relative size based on the current container's font. So a `4em` sized box means `4 * container_font_size_in_pixels`. There's no way to represent that logic with pixels unless you're using Javascript to change the CSS whenever the font changes. Because `em` units aren't a constant logical unit, they're dependent on the context of the container they're set on.
But if you're going to be updating your layout with Javascript all the time, then you can also absolutely use percentages to get the same layout as pixels as well, they're not a fundamentally different measurement in that scenario. You can have a 1000px container and set all of its children to use percentages, and do all the math to make them line up. You can have Javascript that catches page resizes and readjusts all of its styles.
But if we're talking about the underlying logic, both `em` and percentage units are defined in relation to another unit. They're not equivalent to a fixed value, they scale depending on where they are in the DOM and what those other units are currently doing.
If you're working in pure CSS, there are components you can build that will have behaviors that are impossible to replicate with pixels. If you build a dropdown menu that's using `em` units, it will act differently depending on where it's inserted into the DOM. Pixels won't.
> What I will say though is that the more I reflect on it, the more this seems to be an argument for using both `px` and `em` units based on the context of the individual component you are styling. It doesn't seem to be an argument for abandoning relative/point units entirely, as the original article advocates. From the perspective that scaling text alongside containers and scaling text inside containers are both valid ways to scale content, there are going to be some parts of your interface where it makes sense to respond to text size increasing, and some parts that don't.
Yeah I'd agree with this as well after all of the thought on it - if you want to really get to the full 100% mixing the units per part of the design as you describe is going to enable a more optimized outcome than any "pure" approach could get to.
The way to make px behave like em in pure CSS is to set dimensions based on a --custom-property so you can do things like width: calc(var(--parents-font-size * 2.5)) or what have you. Bit messier if all you literally want to do is font sized based scaling but also way more flexible to inject other logic into if you want to do more than that. Of course JS can give you even more freedom to change these kinds of things (no restrictions that types have to match and such) but that comes with it's own swath of problems not needed for most anything that isn't a true app-in-a-page.
I think you are missing the main point : default text size IS a size in pixel.
If my memory serves me right, the default text size is 16px for chrome (not sure about other browsers).
Be it rem, em they are sizes relative to an ancestor.
rem being the root ancestor (html selector or browser default), and em being the closest ancestor having an absolute value defined for its font-size property.
Em is great when you want to establish a font size hierarchy in some container for example.
You can test rem by setting media queries defining different font-size values.
You'll see that 1.75rem is always exactly 175% of root element's font-size value.
That is a point, but it's not a point that matters. It's no different then saying "oh, but browser pixels eventually resolve down to physical screen pixels, so it's the same thing."
The problem here isn't whether or not font size eventually at some point in the browser is getting set to pixels -- it's who sets it. Is the browser setting it? Is the user? And is your layout equipped to handle it when it changes?
I don't use Safari/iOS, so I don't know for certain, but AFAIK the answer is no.
However, I believe in the most recent version of iOS Safari there will be an option in the left-hand corner of the URL to adjust text size for any page you're on, and Safari will remember that setting on a per-domain basis.
But again, I don't own an iOS device, so I'm not sure exactly what algorithm it uses to resize. It says it's text resizing, but maybe behind the scenes it's doing something different.
> It's still a mistake to tie layout to the resolution of a web page
You've got to tie it to something. Your argument falls apart because "em" are still defined in terms of "px" at the root element. You're always defining layout relative to a logical resolution. Also, responsive design reports viewport widths in logical pixels, so logical pixels are still what everything is ultimately tied to.
> Set Firefox to Zoom Text Only (View->Zoom)
Nobody does that anymore. That was how browsers zoomed two decades ago. For a long time now, browser zoom defaults to zooming all content, i.e. logical pixel size. Heck, Chrome doesn't even have a text zoom option anymore. I'm actually surprised Firefox still does -- maybe it's a backwards-compatibility thing?
It's true that maybe two decades ago defining sizes based on em was a best practice, precisely because browsers only zoomed font sizes. But that ceased having relevance a long time ago, once browsers stopped using text zoom (except as an obscure setting).
Today, in the browsers and browser settings 99% of people use, px vs em has zero difference for the user. It's just a matter of programming taste. (Especially now that it's generally recommended to use rem over em anyways.)
> because "em" are still defined in terms of "px" at the root element
No they're not, they're tied to the resolved font size of the current element they're in.
That matters if someone overrides part of the CSS, so even from a pure engineering perspective this makes a real difference. It also matters if the user changes the font size of their browser.
`em` units define font size in relation to the current font size. That font size might be set elsewhere in CSS using pixels, it might be set by the browser. It might be set using viewport width, it might be set using percentages. It might be set in pixels and overridden by the user using the browser's minimum font size feature.
In all of those cases, as a designer you will be glad that you used `em` units for container width and child text rather than pixels.
> Nobody does that anymore. That was how browsers zoomed two decades ago.
This is how Firefox's default font sizing works today. I listed that zoom option so it would be easier for you to play with it, that's the only reason. But if you go into your settings and change the default font size of the browser (which is absolutely something that people who have bad vision still do today), then you will see the same result in the JSFiddle I linked.
> This is how Firefox's default font sizing works.
That's misleading. Firefox's default zoom sizing zooms fonts together with everything else. Virtually nobody uses font-only zooming. People with bad vision still overwhelmingly use page zoom -- because if your vision is bad you need everything enlarged, including things like icons and images.
Also, your description of how font size for em's is set is incorrect. It's always set ultimately relative to px. If set by the browser, it's a default stylesheet that specifies "body { font-size: 16px; }". It cannot be set as a percentage of viewport size using HTML/CSS, that doesn't exist as an option in font-size. If the browser sets a minimum font size, that too is ultimately in px.
Your whole argument hinges on people using font-zooming, when that died for all intents and purposes many, many years ago. There's no reason for web designers to accomodate nonstandard font zoom anymore -- forcing all UX units to be in ems just re-implements page zoom using text zoom, which is utterly redundant.
Use px or use rem, they're functionally equivalent -- it's just a matter of developer preference.
I don't know how you can claim this. I have set up multiple computers for elderly people and taken advantage of that feature. Heck, I have taken advantage of that feature on devices with weird aspect ratios like the older Surface Pros.
> It cannot be set as a percentage of viewport size using HTML/CSS, that doesn't exist as an option in font-size
What?
font-size: 1vw;
> If the browser sets a minimum font size, that too is ultimately in px.
This is being pedantic. If a user or a parent container is setting the font size, that is clearly a different scenario then setting it in the container itself.
If you're going to go down this route we might as well claim that browser fonts are set based on physical pixels as well, since ultimately the browser resizes its internal representation of pixels based on the device aspect ratio.
> it's just a matter of developer preference.
I don't know any experienced developer who writes CSS for a living that would claim this. Pixel-based CSS files are a nightmare to maintain when nesting components, this makes a tangible difference to how you architecture your CSS files.
Wow, you're right about vw. I've never once seen it in the wild, MDN's page for font-size certainly doesn't mention it, and I've never seen it listed anywhere as a best practice. But TIL, thanks.
It's clear you really like font-zoom, and also that your preference is extremely uncommon. I still don't know why you recommend writing CSS using "em" dimensions for UI elements to work with font-zoom, rather than just "px" with page zoom, when the end result is identical. I mean... why would you use font zoom when the rest of the world has moved on to page zoom?
And I also don't know why you say nesting pixel-based components are a nightmare. Dimensions work exactly how you think they will, relative to the page.
On the other hand, nesting em-based components is a nightmare, because they jump crazily in size. You never want your date picker jumping 2x in size just because you placed a button for it inside of a larger header row vs. inside of a smaller form line. In fact, that's the whole reason Bootstrap migrated from em to rem, precisely not to have that problem.
Em-based components are really only appropriate for the most trivial typographical "components" if you can even call them that, like a bullet or tiny badge or something that gets used in different sizes of text. Certainly not components you would usually nest.
> I've never once seen it in the wild, MDN's page for font-size certainly doesn't mention it, and I've never seen it listed anywhere as a best practice.
This is usually called “fluid typography” and in my experience is a pretty widely-known technique, but tends to be treated more as a “holy grail” because it’s difficult to get right and browser support for the various techniques hasn’t been great. Most people/teams tend to just aim for pixel-perfect design at a small number of breakpoints.
> and also that your preference is extremely uncommon
I'm still confused about this. You're commenting under an article that specifically calls out font-based zooming and differing font-sizes between devices as a problem in native environments. If it was as rare as you say, why is the writer upset about it? Do people only customize their fonts in Gnome/Mac, and never on the web? Nobody wants their browser to inherit system settings? Firefox didn't even have an option to set a default zoom on every webpage in the style you describe until early 2020.
I mean, you can say this is uncommon and I'm in a bubble, and maybe you're even right, but I feel like at some point I'm going to want to see some stats on that, because I'm not sure I believe you.
> On the other hand, nesting em-based components is a nightmare, because they jump crazily in size. You never want your date picker jumping 2x in size just because you placed a button for it inside of a larger header row vs. inside of a smaller form line.
Depends heavily on the component; this is why both `em` and `rem` units are useful. But it's not that uncommon to want nested elements like a date picker to scale.
My experience (doing a fair amount of front-end work in my day-to-day job, and writing a ton of CSS from scratch) is that (particularly when I'm writing in BEM style) I use `em` more often than `rem`, even for complicated components. But yeah, I do use `rem` sometimes, it's not that uncommon. It depends a lot on what you want the behavior of a component to be.
> In fact, that's the whole reason Bootstrap migrated from em to rem, precisely not to have that problem.
Two things. First, they didn't migrate to pixels, they're still inheriting their font sizes from user/browser preferences. In fact, Bootstrap in part moved to `rem` specifically to get away from pixel units in multiple parts of the codebase[0]. I don't see any sources online that claim they've abandoned the `em` unit entirely.
Second, I would very, very hesitantly suggest that maybe Bootstrap is not actually the best example of responsive design. I'm not going to get into an argument about it, it's a very impressive framework. It's just in my experience often a pain to work with, precisely for this kind of reason (among others). You nest an element in a static page and then dig through layers of classes to figure out why nothing adapts to the container it's put in. Bootstrap is very useful until you start to heavily customize anything. Just my opinion, and to be fair I have not tried out Bootstrap 5 yet.
The reason why nesting pixel-based components is a nightmare is because it forces you to care about every CSS class that sets a width in your component. It forces you to update every width and height in the component every time you want to make a change. For codebases you do control, this is sometimes merely annoying (depending on how clearly the CSS is written). But for 3rd-party styling systems, it can be a nightmare.
First, let me just push back on the overall idea here: if your philosophy for how the web should work and what features are worth supporting is solely based on Chrome's default behavior, that's not a philosophy I want to encourage on the web, and I'm less inclined to listen to your ideas about what the web should and shouldn't do.
But whatever, that doesn't matter because Firefox also isn't the only browser that has text scaling. If you go into accessibility options for the current up-to-date Chrome browser on Android, there are 4 options you'll see:
- Text scaling
- Force pages to allow pinch-zoom
- Request simplified views
- Enable captions
What you won't see is a default full-page zoom option.
Not only does Chrome's text scaling option not uniformly do a full-page zoom, it also appears in my tests to selectively target and resize fonts only in certain elements on the page based on whatever unspecified algorithm Google is using to decide what does and doesn't count as a "paragraph". This means that as a designer you're not just being forced to handle multiple font sizes when you lay out a mobile site, you're also being forced to handle font sizes that scale non-uniformly across your page.
Are we going to argue whether the accessibility options in the default Android web browser are a bubble? I don't see what data people have that is making them so confident that nobody uses text scaling, because as far as I can see text scaling is a feature in every mainstream browser and is predominantly advertised on mobile devices. Is it really, genuinely weird that some people might take advantage of it?
I just tried it on a few sites and it either doesn't change much/anything or breaks stuff -- either by overlapping text, or not increase the width of text zones so you end up with few words per line in the middle of the screen which was particularly bad on a newspaper site (along the ridiculously undersized article photo).
I thought it could save some space in headers and such if they don't zoom those, but if they used ems everywhere as might be best practice then there's no win to have.
So it's either the same or worse than full-page zooming in every test so far. This is not only a now-obscure feature, it should be considered deprecated imo -- zooming (or changing default) font size feels like hijacking a responsive web page source and hoping for the best.
> either by overlapping text, or not increase the width of text zones so you end up with few words per line in the middle of the screen
Those the problems that I mentioned. Those problems are why you don't use pixels instead of `em` units.
If you increased the font size in a PDF then columns, diagrams, and layouts would also break. But you wouldn't be surprised because you don't expect the PDF to be responsive. We expect the browser to be responsive.
The use-case for font-only zooming in general is that as a designer, there are elements that should scale with the font and elements that shouldn't. Full-page scaling works by acting like the browser is just a lower resolution, so everything scales upwards except percentage units and viewport units, including things like border widths, spacing between columns, etc... Sometimes as a user that's what you want. Sometimes it's not.
As a designer, it's useful to be able to have more control in the scenario where a user wants to scale only the font and not the border-width of an element to make something that genuinely feels responsive, rather than to be completely subject to a zoom method that is just pretending you're on a screen half as large and then upscaling before it renders.
It's also useful because we'd like to build the web into an extensible platform that users can interact with in creative ways. So maybe we'd like the ability to scale only part of a webpage. Maybe we have an extension that allows us to quickly zoom in and out of a paragraph.
Note that this is not completely theoretical, Firefox already lets users set minimum font sizes. If I set a minimum font-size of 14px, it doesn't matter if you say that your font-size is 8px, it will render at 14px -- but all of your bigger titles and headers will be unaffected. That's the kind of feature that works if browsers allow font-based zooming, and pages are built to accommodate that, but that is impossible to do if the only way we can resize a page is with full-page zooming.
What worries me is the testability. Too many variables, especially external unpredictable ones injected by browsers and user stylesheets, means accessibility testing combinations explode further than they already are.
Full-page zoom - something I imagine was less common in the past for performance reason - is much more in line with "how the site was made, intended to layout as, and tested for."
It's nice that the HN header bar doesn't grow on font-zoom, but it's hardly a killer feature (edit: and isn't even supported on my iPad where I'd want it). I always full-page zoom and was never bothered by it or even noticed it. But clearly half the web is broken for font zoom. I'd say don't fix it, leave it behind instead. Just like 14px doesn't really mean 14px anymore and that's ok.
Follow the rules, then to save save some time test with default settings in Firefox or Safari or iOS, the point is that the most usual problem I've seen the lastest few years are Chromeisms - non standard behavior that happens to work in Chrome.
>I just tried it on a few sites and it either doesn't change much/anything or breaks stuff
This tells you you're visiting a site who's designer(s) don't want the user to control their browser. Ask them and dollars to donuts they'll treat it like the "doctor, it hurts when I do this" joke.
Look at the vitriol in the comments here, there is unmistakeable antipathy toward the user. Nobody is going to say they pride themselves on a user-hostile approach to web design, but a duck is still a duck and the vast majority of designers are still going to think in terms of pixel-perfect.
"When you're slapped you'll take it and like it." --Sam Spade
I set my fonts larger in Android sepecifically... I can still double-tap/zoom if I need larger images. It's the reading that tends to be the most problematic.
I'm far sighted, so see most things without glasses fine.. I have glasses at my desk, but don't tend to have them on me when out/about and trying to use my phone.
Chrome on mobile absolutely has a text zoom, it's exposed as an OS function, but chrome respects it... my vision is not great, so in accessibility settings I have fonts set to largest. Chrome does a decent job (as most Android UI) of respecting this. The apps that don't, or don't do it well (Facebook) are the ones that are particularly annoying.
It may not be exposed in the browser directly, but the functionality is definitely there.
edit: and I'm frankly okay with using px/pt for the baseline font at the root level and using em/rem elsewhere. In the end, I understand that it should be 72pt/in and 96px/in as far as CSS goes... others may not... Devices that don't have their actual PPI set so browsers can properly calculate the CSS dimensions is slightly annoying though. But that's been a bit craptastic forever and a day.
In the end, nothing will ever be close to perfect. I do find it annoying that different fonts with the same size and line-height will render far differently... a 12pt font should render (roughly) 6 lines per inch.
> now that it's generally recommended to use rem over em anyways.
Whoa! Apparently I missed the note on that one. I very much favor using em over rem precisely because it is relative to the current font size. This is especially nice with SVG icons:
Your specific example is an exception to the "rule". The em measure is relative to the font size of the last containing element that specified an explicit font size. So with a heading, a 1em x 1em icon makes sense because it'll be the height of the container h1 element (which you set as 1.5rem).
The rem unit is relative to the base document font size. Your icon in an h1 set to 1rem x 1rem would be sized relative to the body's base font size. In your example a 1rem icon would be .66 the size of your h1.
When you use rem units consistently their size is more predictable throughout the document. If you've got a complicated stylesheet overriding sizes all over the place em units can end up inconsistently sized and tricky debug. I've seen rems recommended for probably the past ten years or so.
I think there are many of these “exceptions”. At the top of my head:
* Make inline code (say: `0.85em`) relative to fit equally nicely in a big heading or in a smaller `<aside>`.
* Margins and paddings so that larger font sizes have more spacing between them and more breathing room
* Column width where you want to fit a certain amount of character at most in a single column (say `grid-template-columns: repeat(auto-fit, 30ch)`)
* Max container width of a text heavy container is probably best specified in `ch` units (say `max-inline-size: 120ch` is a good one) as long tines are hard to read. If you later decide to use a larger font, you don’t need to change this value like you would have if you’d use `rem`.
I could go on... But I really doubt this is a good rule. And I am skeptical that any serious front end developer is recommending against units that are relative to the current font size.
A) there is no way for your OS to know what a millimeter is on the 3rd-party monitor you hooked up. So yes, they are in theory roughly tied to real-world dimensions, but in practice, regardless of what the spec says, a browser "pixel" is just another arbitrary unit of measurement that may or may not map to a physical width. This is especially true if you're mixing monitor resolutions on a multi-monitor desktop setup.
When I swap browser windows between my HDPI monitor and my normal monitor, both the reported resolution of the window and the physical size of a "pixel" change. It doesn't remain fixed to 96 pixels per centimeter.
And when I open Chromium, I get different sizes entirely, because Firefox is using a different scaling factor on my HDPI screen than Chrome is. The spec is great, and you're correct, browser pixels don't map to individual physical pixels on a screen. But no, in the real world it's not a completely independent logical unit. In practice pixel densities and screen sizes will affect the physical size of a browser pixel in some scenarios.
B) the effects of tying your layout and column widths to resolution are negative even if your resolution is defined in real-world logical widths. Even if every single browser pixel was perfectly sized on every device so that it was genuinely 96 pixels per centimeter, it would still be a problem to define all of your column widths and font sizes in centimeters.
People are debating the exact definition of the word "resolution" and it does not matter at all to the point I'm making; this is a useless debate. If people are really offended that I used the word "resolution", then fine, swap it out for some other word like "rulers". I don't care what word you use, it doesn't matter. It is still generally advised on the web not to define your layout based on "rulers". If CSS had an "inch" unit, it would be bad practice to make a static layout that set all of its widths in inches. It would still usually be preferable to set font size and to think about column widths/margins using `em` and `rem` units.
https://en.wikipedia.org/wiki/Extended_Display_Identificatio...
> 21 Horizontal screen size, in centimetres (range 1–255). If vertical screen size is 0, landscape aspect ratio (range 1.00–3.54), datavalue = (AR×100) − 99 (example: 16:9, 79; 4:3, 34.)
> 22 Vertical screen size, in centimetres. If horizontal screen size is 0, portrait aspect ratio (range 0.28–0.99), datavalue = (100/AR) − 99 (example: 9:16, 79; 3:4, 34.) If either byte is 0, screen size and aspect ratio are undefined (e.g. projector)
This is not perfect of course, may be defeated by cheap adapters, KVM switches, splitters that send image to 2 monitors, etc... And projectors can't know the projected size. More importantly, people sit far from a projector screen; absolute size is not very meaningful without knowing how far away people sit!
You're right that a window spanning multiple monitors has mixed physical size, but that's an edge case that doesn't invalidate taking physical size into account as a goal.
Some OSes do re-scale UI when a window fully moves into a monitor with different scaling.
And OSes do something with this? When was the last time you hooked up a 1920x1080 monitor to a computer and it changed the reported resolution from 1920x1080 pixels to something else because of the screen size? You're saying that if I hook a 16 inch 1920x1080 monitor or a 12 inch 1920x1080 monitor to a computer that `screen.width` in a web browser is going to report different numbers to make sure I maintain the correct physical dimensions of a browser pixel?
I'm in a weird position here, because obviously you know what you're talking about, but also very obviously if you hook a 1920x1080 monitor up to a desktop computer and full screen a web page, the CSS breakpoints are not going to act differently depending on the size of the monitor. I can observe that fact in front of me across multiple computers right now. So I'm not sure what's going on.
Maybe we're talking past each other or something? But I do know that in practice my smaller Macbook reports a higher screen resolution than my 19 inch giant Linux monitor. And maybe there are OS-level tools someplace to handle that, but they're not available in CSS anywhere that I can find. What you're saying doesn't pass the real-world test of "is it demonstrable on any of my computers sitting in front of me".
> a window spanning multiple monitors has mixed physical size, but that's an edge case
Is it? If I want my Linux box to scale differently on different monitors, that's something I need to manually set up as a user, at least from most distros I've used. Maybe Ubuntu or Windows does something else? The closest I've ever seen to this is my monitor scaling for different aspect ratios when I mirrored Gnome to a projector or a monitor of a completely different resolution.
---
But again, this entire topic ends up being kind of a weird thing to be arguing about because it does not matter if you're using real-world centimeters. It doesn't change anything about what I'm saying, and I almost regret even bringing up "pixels" in general because it seems like they're a giant distraction to everyone.
You should not be building layouts in centimeters. Centimeters will have all of the same problems with scaling fonts as any other fixed unit, the reliability of your measurement doesn't change that. People are fixating on the individual technical details of what's going on in monitor firmware instead of the broader point that in most cases container dimensions should be defined using relative units that scale correctly as browsers/users alter font sizes.
> It already is. CSS "px" doesn't refer to physical pixels at all, they're called logical pixels. Which on old screens at 100% zoom may map 1:1, but these days are more likely to map 2:1 or even 3:1, and with OS and browser zoom levels may be things like 1.666:1 or 2.5:1.
Yeah it's a nightmare if you're doing pixel-art-y games in the browsers, there's last time I checked no way in general to get access to physical pixels anymore, which makes integer-multiple upscaling AFAIK impossible in general. Hurrah. [ disclaimer: The browser rendering stack is complicated enough that I might be wrong. ]
I feel your pain about non-integer scaling ratios. The way I hack around it is to set the canvas context to an integer number of device pixels, and then set the CSS size of the canvas to a fractional size: device pixels / DPR.
We use this along with some other hacks on keep.google.com and some other sites to map 1:1 to display pixels to try to ensure hardware overlay promotion for the inking surface.
Doesn't always work (may work for your use case). There are edgecases in the browser where at an HTML level the browser computes a CSS size but at compositing level (where devicePixelRatio is used) it might have clip by pixel here or there.
And example, lets say your windows 99 device pixel wide and a DRP of 2.0 and lets say you ask for 2 side by side elements (via flexbox or whatever) each width:50%. At the HTML level the browser will compute there are 49.5 CSS pixels available. It will then compute the size of each 50% as 24.25 CSS pixels but in order to fill the 99 pixels, one of those 2 elements has to be 50 pixels and the other 49. There is no part of the spec that says which side gets 50 and which get 49. Most browser compute 50 for both sides, the pass it up their compositor which will use 50 pixels of one and 49 of the other. The point is, you can't know which one will get which by doing CSSpx * dpr.
This is why ResizeObserver device-pixel-content-box was added. So that you can ask the browser what it did.
TIL. Oh gosh I don't know if I have the brain power to work through all the necessary rendering layers logic to fix up my game engine to make the pixels as they should be, but if I ever do and figure it out, great thanks to you! (and even otherwise, thanks!)
I hack around it by taking the CSS size of the container, finding the closest smaller integer device pixel size, and set the canvas context to that and the canvas CSS size to the fractional size, which can be smaller than the containers CSS size.
Bugs filed for other browsers but AFAICT it's not a priority for them.
Note: For a pixelated game having this info useful. Also for diagrams, as the user zooms in you'd like to be able to re-render a canvas at native resolution the same way SVG and text gets re-rendered. But, a noticeable problem is static images. You make pixelated image say, 100x50 and display it 4x like this
At someone's recommendation a while ago I made a proposal for integer-multiple upscaling - https://github.com/w3c/csswg-drafts/issues/5967 . It feels very niche, especially given how complex the standards already are, but OTOH I'd use it if it were a thing...
(Also, that linked page is very cool, and shows how awfully tricky the problem is...none of the proposed solutions work on my iPad, especially not once one zooms in/out in the browser - oh it turns out it was related to browser zoom level - at normal zoom they work (sometimes when I resize the page at normal zoom it works, sometimes it doesn't...). So I guess it's 70% of the way there...but not all the way there).
The reason it doesn't work on iPad is because iPad doesn't support the required API. Without that API there is nothing you can except special case per browser and pray. And even then, Safari doesn't change DRP based on zoom level like Firefox and Chrome do so it's currently impossible on Safari period.
I've added an event in my calendar to go back to this topic again this day one year from now to see if things have improved any (I skirt with frustration-induced burnout every time it raises its head as relevant, so I need to limit my exposure). Thanks for knowing more than me about this cursed subject matter.
So, rather than using the traditional device-independant units, we should use another device-independant unit that pretends to be device-dependant, but isn't?
You don't want to be doing font-related things in px units. For instance, you don't want, say "margin-bottom: 10px" under a text element. The margin will stay the same if the font size is increased or decreased.
Absolutely agreed. The article laments things like "I have no good way of knowing how big my text is going to be when I say 16pt," and my response is "why would you ever need to know that? Do your containing elements not reasonably resize when their inner content gets bigger? How are you handling internationalization where strings will certainly be longer?"
It's ok for apps to look different on different platforms. We need to stop trying to design things pixel-perfect to the mockups - I thought we could have left that trend behind in the early 2000's.
OS font rendering can even provide info about the physical dimensions of the screen and give you an "actual size" unit you can use to match your screen to real world paper. So a lot of this article, to me, reads as a misunderstanding of why fonts render the way they do.
> It's ok for apps to look different on different platforms. We need to stop trying to design things pixel-perfect to the mockups - I thought we could have left that trend behind in the early 2000's.
Thank you, Yes Yes!
The web was much better when it was annotated text: You took a primarily text document, maybe decorated with a few formatting hints, and let the User-Agent take care of the rest. Over the years, browsers have handed way too much fine-grained control over to web developers, and the result is thousands of developers treating my HyperText browser as some kind of interactive graphic design canvas. This has really been a step backwards in web usability, even though it enabled nice fancily-designed blogs and "web apps" of dubious value.
> and my response is "why would you ever need to know that?"
The author wants to know, so this is simply the wrong question. I agree with the author that it is strange that a quantity which is in principle easy to compute behaves in such an unreliable way. It makes designing stuff more an iterative instead of a first-time-right experience.
Also, if you specify X and get Y instead, then that is a way for websites to fingerprint your browser, which is another reason to make the computation more reliable.
> It's ok for apps to look different on different platforms.
We've been all in the situation where you designed something for device A and it looks off when viewed on device B. A word that wraps in the wrong place, or a button that is 1px taller than the button next to it, etc. More control over what is shown in the browser is always better. (Of course, a user should be able to override everything, but that is another matter entirely).
> We need to stop trying to design things pixel-perfect to the mockups
This is the huge war that has left CSS and much of the web a battle-scarred crater-ridden minefield.
Users want to be able to buy a range of devices with different sizes and resolutions for different use cases.
Different users want different text sizes as an accommodation for myopia and age.
Manufacturers want to be able to bring out new devices that have a different screen size and resolution from the previous ones.
Designers (and clients!) want to know exactly what something will look like when they publish it. But insisting that you can predict the "pixel" output in all cases is to fight all of those use cases. It's just that sometimes they win.
Apple are the only vendor who've really got high-DPI and DPI scaling working consistently; Windows support is there but so widely ignored or broken by apps that you can't rely on it.
A problem I had and I could not find a solution (maybe someone could help me).
I want to show a button for the user to click. I respect my user and I want my button not to be too big or small, I would like it to be equal or similar to his preferred button size he configured his OS to use. If you search for the best practices you find studies that say that on mobile the button should be maybe 10mm real size , but good luck setting a css dimension on the button that will ensure either this default size on all devices. IMO there should be a css value for preferred font size and preferred touch button size so you don't get at the same time complaints that the button is too large or too small. (I do mostly bgackend so maybe I missed something when searching, maybe there is some hidden trick to do this...and I am referring at mobile devices)
Having another unit for "touch area" would be kind of nice, I can imagine uses for that. The device/browser/user could set how large a `ta` unit is for buttons/inputs.
Wouldn't just be useful for mobile, I can imagine even on a desktop a user with Parkinson's or something might have trouble precisely using a cursor and want bigger interaction areas when they visit a website.
The most common solution I see online is to swap layouts when the page drops below a certain aspect ratio or width, which can actually be kind of annoying on desktops. It's a hacky solution.
There are also some media queries you can do to detect the presence of a mouse in some browsers, which can work, but also doesn't really hold up in a world with convertible devices that can be simultaneously mouse-drive and touch-enabled.
> The most common solution I see online is to swap layouts when the page drops below a certain aspect ratio or width, which can actually be kind of annoying on desktops. It's a hacky solution.
In many scenarios, there is no way to interpolate between the ideal layouts for large and small screens. This makes it necessary to arbitrarily select some point where the layout is rearranged as the viewport changes.
I agree that this behaviour can be annoying on desktops as the window is resized, but it’s better than the alternative - a layout that needs to work the same way for drastically different screen sizes.
The problem I have presented in the grandparent comment could be solved either with:
- let me specify the button size in real world dimensions
- let me specify that my button should be the same size as Safari/Chrome buttons in the toolbar.
Then my users can't complain that on their device the buttons are too big or too small. The page was something like a map with a toolbox on bottom, if you make the buttons too big the map area is reduced, if the buttons are too small then are hard to use.
With native toolkits like Qt you have a toolbox widgets, you don't define any dimension or colors and the user theme will handle everything.
Right, the issue here is that we don't have enough semantic control over why an element is a certain size in CSS.
One of the underlying reasons why `em`/`rem` units tend to work better in CSS for container widths is because very often semantically you want to design a column in relation to how many characters of text it should display in a row before wrapping.
But not always; case in point touch interfaces where the reason everything is getting bigger is not because anything fundamental has changed about the user's text preferences, but because bigger elements are necessary for a bigger pointer.
So it does kind of make sense to me that we could have a semantic unit that is unrelated to text size and specifically related to a user/device defined touch size. And then you could have a mix of min/max widths and heights based on different semantic units to have something that responds equally well to both narrow windows on the desktop and mobile devices.
I am all for having more sizing units that are based on user-defined attributes that are applicable to a specific category of measurement (font-size, touch-precision, screen-brightness, whatever), not on trying to guess what specific device a user has.
A 5 inch wide page on a desktop and a 5inch wide page on a mobile device have different concerns because they're controlled by different pointer devices. It's a little irritating that they both collapse to the same touch interface.
That's the case for most ui/ux at a given point for responsive design, regardless of the ppi/size reporting.
Also, I'm refering to text/font rendering, not UX breakpoints, though I do understand the issue... the problem is, short of sniffing the user agent for "phone" or "mobile" there's no way to tell for sure... touch interfaces are unreliable as many desktops also have touch support.
Note: I have used the phone/mobile sniffing to do some things slightly differently for desktop vs. mobile before. For the most part, it's not too big/bad of an issue.. I do know people that don't like certain sites/apps on desktop as this practice has changed though (namely, skype and discord) as a friend liked to use about 1/4 the screen for chat, but the ux now changes to phone ux when too small.
Assuming the ppi is setup correctly, both px (1/96") and pt (1/72") will do that... however it's up to the device mfgs to setup the ppi for the OS correctly.
If I have two monitors with two resolutions and I put the two screens together the text is a different size. When I'm reading the text I want it to be consistent as I move it across screens. With this approach will the text be the same size?
The main issue I have as I get older is that as the resolution increases the text size seems to get smaller
This is exactly the problem that I'm getting at. The reason your font is getting smaller with higher pixel densities is because the font size is being tied to the pixel density.
In a better native world, your font size would be completely unrelated from the monitor(s) you're using. It is the attempt to tie font sizes to physical attributes of your monitors like their resolution that is giving you this problem. And it is the need for scaling to be based on resolution that makes multi-resolution monitor setups break.
There's no reason why your OS couldn't size text differently on each monitor based on monitor-specific settings that you control, and there's no reason why the applications you're using couldn't implement responsive design and accommodate that setup.
As designers we would just need to embrace responsive design and stop trying to control everything.
Any kind of user customization will have the same effect. Any preference that the user can edit can be a confounding variable in an A/B test.
I don't want to live in a software world where as a user I'm forced into a one-size-fits-all approach to every interface just because it makes A/B testing easier.
I would posit that if rendering differences in font display are affecting A/B testing a workflow, the A/B testing apparatus has failed to control for confounding factors and was probably invalid anyway. If OSX is known to render differently than Windows (and it's not just fonts), why are you comparing cohort A from Windows to cohort B from OSX? That is an analysis error.
The main point of the article, as I see it, is that the "em" used in fonts isn't the intuitively correct em size.
It's just a control box used by the font developer, and the result is that designers can't get a consistent font size. They can know, more or less, what something is going to look like given the font they want to load, but the fallback font might have a different concept of em size and look more different than it would need to be.
So having a different metric, which is exactly capital height, makes fonts look more similarly-sized to each other at the same capital-height resolution, which he demonstrates in the article.
It is about specifying sizes in a way that makes sense, i.e. based on visible quantities rather than abstract quantities that are difficult to understand.
It’s not just difficult to understand, the em height / character shape described by the article are total nonsense — they have zero relationship to the font itself, and no relationship between one font’s eg height and another.
Which ultimately means that font sizing is entirely nonsense: the only thing you can say is font size 1 is smaller than font size 2, but it’s impossible to say by how much, or guess the difference, except when talking about one, and only one font.
That is, a font with size 16 roughly corresponding to the same size in another font is entirely defined and enforced by nothing at all — it’s purely a “happens to be true”.
Thus, the only real way to handle font sizing predictably is to never switch them out, because you’re really dealing with undefined behavior
The article is mostly about switching two fonts with the expectation that the visual size of the characters remains consistent. That expectation fails because the em size is arbitrary with respect to the visible caps-height.
As it stands, fonts can have drastically different rendered sizes at the same specified font size. This leads to all sorts of problems, like ensuring fallback fonts have similar metrics to the one you expect to load.
> The article is mostly about switching two fonts with the expectation that the visual size of the characters remains consistent. That expectation fails because the em size is arbitrary with respect to the visible caps-height.
It would fail with caps-height, too, as other visible measures of characters (not just abstract ones like em) have no guaranteed consistent relationship to caps-height, so, as such, there's no guarantee that fonts with the same caps-height have the same “visual size”, or even visual vertical size, since cap height doesn't i close descender and ascender height.
Typography is a specific skill set, nobody said that it should be 'easy to understand'. Makes sense to whom - to web developer? He is not the intended audience.
If the font size would be specified using only cap height then the work of font designer on specific relationship between negative and positive space and line height would be thrown out. That would be a net negative for the state of typography on Web.
Again putting things into fixed size containers that do not adjust based on different font face is not a good practice and it is not what Web meant to be.
Fix the OS and CSS to make it possible to define "real physical sizes". When you are printing a book, you are not printing a text with font size of 24 pixels. Forget about pixels, pixel density of modern displays is so hight that you rarely see individual pixels anyway and pixels are irrelenevant. But OS and web standards are still broken, frozen in time where XGA 19" CRT with 1024×768 px were common.
Other comments (not to your specific one) have already pointed this out, but again: the "px" in CSS is as much a device-independent, physical length unit as "pt" is. It only means 1/96 in = 0.0275 cm.
Agreed... would love to see fonts consistently defined sizing... not sure it should be based on the cap-height, but with a line-height of 12pt, I definitely expect to see 6 lines per inch, and that's not what you get.
Hey just a heads up, on the web (or at least in CSS) px is resolution independent. It represents 1/96th of an inch [1].
The web has physical, font-relative, and viewport-relative lengths which all serve slightly different purposes. Like you, I find font-relative to be super useful much of the time, but the others have their place as well. I just want to point out that CSS specifically doesn't have a resolution-dependent measurement.
Using pixel (1/96 in) sizes for a font is fine if you care about the physical size of the font being displayed. Starting from the system default font-size as you suggest will also work, but you'll need to test it on all the platforms (especially if you use a custom font).
Yes, completely correct, and it's good that you pointed that out.
However, you also shouldn't be sizing fonts based on 1/96th of an inch units. That will also break responsive design in many cases. Not all of them, like you said there are legitimate use-cases, but most of the time you should not be trying to make a font be a specific physical size.
The are independent of the screen but also of the user preferences. Using rem or relative sizes bases your sizing off of the user's selected font size. As soon as you size something in px you have just thrown away the user's font size choice.
Ctrl++ is only necessary because you've "thrown away the user's font size choice".
As a user, I have my font preferences set to what I want to read. If you maintain main body text size = 1em, then those preferences are respected. If you start arbitrarily specifying font size in px (whether CSS px or physical px), then you destroy that. This can still happen with 1em, too, by opting for a font whose em box is screwed up, as described in the article, but that's the _easiest_ thing to test for, because it will be apparent on all screens (including the designer's).
The resolution of the webpage as reported by the webpage, even if it doesn't line up with the literal number of pixels in a screen, should not be used for font sizing in most scenarios.
I fail to see a convincing argument here. The "px" unit has a well-defined relation to devicePixelRatio and works predictably across many devices.
> It doesn't matter if your fonts are bigger on Mac or Windows. It is intentional that platforms can size their fonts differently, and your interface designs should take that into account.
You're going to mess this up, guaranteed. I see it all the time. Font size strongly relates the sizing of all your other interface elements, which are naturally defined in logical pixels (or "px"). You can't design your way around that.
> Font size strongly relates the sizing of all your other interface elements, which are naturally defined in logical pixels (or "px"). You can't design your way around that.
A huge part of responsive design is the art of designing your way around that. In most cases (not all, but most), don't define your interface elements in pixels (or any other logical unit that is unrelated to font size).
I also see native apps fail at this, but it's not because it's an unsolveable problem, it's because a lot of native apps are behind the times on responsive design.
Normally I'd criticize native UI toolkits here as well, but the truth is that for many toolkits (including GTK and QT) this hasn't been a problem for a while; most popular UI toolkits support font-based widths for layout. Designers just have to take advantage of those features.
The operating system sizes everything according to the equivalent of devicePixelRatio, not font size. Device manufacturers choose this value according to screen size and pixel density. It is reasonably predictable. The em-size however could be anything.
If your intent is to drive the layout with font size, using units such as "em" does the exact opposite of what you want: you're simply adding another unpredictable factor into your size calculations.
> A huge part of responsive design is the art of designing your way around that.
Using "px" for responsive design works just fine. What exactly is the advantage of "em" in this regard?
> The operating system sizes everything according to the equivalent of devicePixelRatio, not font size.
You just finished telling me that "font size strongly relates the sizing of all your other interface elements". And I agree with that, which is why it's preferable to use a unit that's tied to font size.
> The em-size however could be anything.
The `em` size is a constant based on the current font and font scale that the user/OS has selected that will scale predictably as that specific font scales.
> What exactly is the advantage of "em" in this regard?
It scales predictably alongside the currently displayed font. It almost completely solves the problem of Mac and Windows displaying fonts at different sizes. Again, you just finished telling me that handling OS font-size differences was a task that I was guaranteed to mess up. Well, `em` and `rem` units make it so you won't mess that up.
When a user changes their fonts to be 1.5x as large, you don't want to be using a logical unit for your layouts and popup window widths that completely ignores that change.
> You just finished telling me that "font size strongly relates the sizing of all your other interface elements". And I agree with that, which is why it's preferable to use a unit that's tied to font size.
It is not preferable, because em-size is decoupled from the size of other UI elements.
> The `em` size is a constant based on the current font and font scale that the user/OS has selected that will scale predictably as that specific font scales.
Anything in this chain could change em-size: The OS, the OS setting, the UI toolkit, the browser, the browser setting - independently of the rest of the UI elements. Those changes could have been made by the OS vendor, the device vendor, the browser vendor or the user. That's what makes it unpredictable and that's why it breaks.
> Again, you just finished telling me that handling OS font-size differences was a task that I was guaranteed to mess up. Well, `em` and `rem` units make it so you won't mess that up.
They don't. You probably just don't know you messed it up, because you haven't tested all the devices out there.
> When a user changes their fonts to be 1.5x as large, you don't want to be using a logical unit for your layouts and popup window widths that completely ignores that change.
Here's how you actually achieve that: Use "px" everywhere. The only reason I see for using "em" in place of "px" is that you want to decouple the scaling of fonts/labels from the overall scaling of the UI. However, you probably shouldn't want that, because it's going to mess things up.
> It is not preferable, because em-size is decoupled from the size of other UI elements.
Only if you make it that way.
You're arguing that I should size my layout in pixels because... I size it in pixels? If your em-size is decoupled from the size of your other UI elements, that's a choice you made, it's not the OS forcing you to do that. We're talking about the decision not to decouple em-size from the size of other UI elements. There are tons of popular, modern desktop UI toolkits that give you the ability to do that.
> Anything in this chain could change em-size: The OS, the OS setting, the UI toolkit, the browser, the browser setting - independently of the rest of the UI elements
No, any of those things could change the base em size of the font. Which will then scale linearly and predictably as long as you're using `em` and `rem` units everywhere, including for your layout.
> Here's how you actually achieve that: Use "px" everywhere.
You're commenting this underneath an article that explicitly complains that the pixel approach doesn't work today because OSes define fonts in points, because users can override your choices for font sizes, and because these units are not a uniform size across different operating systems.
Meanwhile, if you build a QT app and use `em` units, it just works.
And of course it works, because regardless of whether or not you think that pixels would be great for fonts, users still get to override your font choices on native devices. The only way to solve that problem is to tie width to font size. You're complaining that anything can change the base `em` value of a piece of text, and I'm sorry to tell you this but on most modern UI Toolkits users can also change the font and size of your text content even if you set it in pixels.
Unless you're advocating that Gnome/iOS/Android/Mac should get rid of their current text scaling accessibility options, which... good luck. Pixels won't save you from that stuff, container widths based on current font size will, because for very good reasons you increasingly don't get the option on modern computers to force font to be a specific size.
> is that you want to decouple the scaling of fonts/labels from the overall scaling of the UI
I worry we're talking past each other. Don't decouple anything. Use `em` units to scale how large a container, button, margin, image should be. Use them everywhere, not just on your fonts.
If you just use "em" scale for everything, you simply add another factor into the size calculation. It's the same as just using "px" directly, except it's now also larger/smaller depending on the font-scale, on top of the UI scale. Most of the time, on most devices, you won't notice that, but on some devices it will make everything unexpectedly larger or smaller, usually due to some vendor setting not matching well with devicePixelRatio.
> You're commenting this underneath an article that explicitly complains that the pixel approach doesn't work today because OSes define fonts in points, because users can override your choices for font sizes, and because these units are not a uniform size across different operating systems.
If you specify font size in "px" (instead of "pt"), font size will roughly match pixels/devicePixelRatio, which is as consistent as it gets across platforms. Using "em" instead would be less consistent.
> Unless you're advocating that Gnome/iOS/Android/Mac should get rid of their current text scaling accessibility options, which... good luck. Pixels won't save you from that stuff, container widths based on current font size will, because for very good reasons you increasingly don't get the option on modern computers to force font to be a specific size.
The intended behavior of changing the font size is to not scale the whole UI, just the fonts. If you use "em" for everything, you just defeat that feature. You might as well use "px" directly, it's more predictable and easier to think about.
Essentially, you've made svg text a special case. So diagram-based languages and frankly any graph-drawing framework that let you specify text labels go out the window.
I think svg `<glyph>` was meant to be the answer to this question, but that was an answer for people who don't care about readability. So now it is rightly deprecated.
Unfortunately, that leaves essentially no answer except guessing and checking with pixel-sized fonts to make sure font-rendering-stack development troglodytes haven't screwed up my diagrams.
> Essentially, you've made svg text a special case. So diagram-based languages and frankly any graph-drawing framework that let you specify text labels go out the window.
Hear me out on this: a graphics format that is specifically designed to scale losslessly as it's biggest selling point, should have support for scaling `em` units.
It's absurd that building responsive SVGs is currently harder than building responsive web pages. Instead it's got some kind of messed up, obtuse system where we either do viewport scaling and break all of our line-widths, or do percentage-based scaling and break all of our custom paths.
You can use `<foreignObject>`[1] in your SVGs to wrap text inside a nice HTML rendering (with word wrapping and other superpowers). However I’ve found that there is always some issues (e.g. I need the graph to shrink in the inline direction when text is longer then X; or this rect should flow lower when I have multiple lines). I’ve never actually found my self using <foreignObject> in the SVG diagrams I write, and usually just listen to a resize event and manipulate everything that way (shrug).
Again, em's don't solve the problem of having to guess and check across the results of every rendering system. There are plenty of cases where I want text to be written between two vertical lines without overlapping either of them.
> There are plenty of cases where I want text to be written between two vertical lines without overlapping either of them.
Which is a problem in svg only because you can't space those vertical lines using `em` units.
I'm not only talking about text, SVG is terrible for responsive design in general even for charts/diagrams that contain no text at all. The entire spec is locked into a world where everything is going to be a fixed aspect ratio that never changes, where zooming in should zoom everything including both text and border widths, where the idea of spacing elements responsively but not having the elements get bigger as the viewport resizes is impossible -- which just isn't an accurate representation of how modern SVG diagrams are used outside of PDFs.
You have basically two options for responsive design[0] -- viewport units (which are terrible because many SVG engines and browsers don't have the ability to avoid applying viewport scaling to path widths), and percentages (which are flat-out unusable in paths). Don't even get me started on that, there's zero reason for paths not to have the ability to specify points using percentages. Heck, I should be able to specify paths using a mixture of viewport units and percentages in the same path.
But whatever, at this point the rant getting off topic. The point is, we're not talking about setting font using `em` and every other part of the SVG in viewport units. You should have access to `em` everywhere, including when positioning other elements and drawing paths.
[0] Okay, 3 if you do a bunch of hotlinking and embedding and nested viewports and garbage that nobody should have to think about.
In fact, I think I'm underselling it. Because I think the gaming industry essentially says, "fuck it," to this same problem and simply uses images for the text.
The gaming industry isn't doing responsive design. For multiple reasons, some legitimate and some not, but the point is that I would consider them to be a separate category.
Most games on the web are going to be using Canvas I suspect -- in my experience at least, they usually won't be rendering to the DOM or using CSS at all.
I strongly disagree with this general philosophy. One should be able to use an absolute, non-relativistic unit of measure that requires no external knowledge at all. Not even to other parts of the same layout.
Relativistic units are inadequate if they are free to cause non-pixel perfect transformations of designers intent from platform to platform. It is no more reasonable to re-layout a carefully designed UI then it is to reposition objects and people in a movie scene played on devices of different resolution, in fact it is much less reasonable.
Perhaps, in some circumstances this will call for platform specific design, and that is correct and appropriate. Perhaps a UI will look like a postage stamp on a high pixel density display. Adjusting for that difference is the domain of the operating system and the user. Even the OS may be unaware of the actual physical size of the display, for example when using a projector.
Automatic layout is a convenance, but it works against not for good design.
It doesn't mean compromised useably, it is a guarantee of usability. Dynamic layout, re-flow and responsive design compromise usability. The utility of responsive design is not improved usability, its improved designer productivity at the cost of usability.
> Perhaps a UI will look like a postage stamp on a high pixel density display. Adjusting for that difference is the domain of the operating system and the user
... how? If you've fixed the layout, there's no way to do this other than zooming the whole thing.
Nobody wants to re-layout movies because they generally aren't trying to read text off the screen.
Text is displayed on the movie screen all the time, so I'm unclear what your argument is here. Yes zoom the whole thing, as apposed to zooming only the text and then changing the layout to accommodate. As a user I do this all the time in browsers, in video games, and even in display settings. It works great, because everything stays locked together, and there are never any unanticipated interactions between elements. The absolute worst case scenario is the aspect ratio doesn't fit the device perfectly.
You know what doesn't work great? When I resize my browser window and the responsive designed threshold decides my 3k monitor is a phone. So much engineering effort to achieve a bad user experience, when zooming the entire UI is superior in every way.
Just use pixels, they are unambiguous units that are consistent across all digital media, scaleable without changing layout, and understood by both designer and user alike.
If you have two fonts at size X, they should both display the same number of lines in Y space... The problem is the relativistic measure isn't even consistent between fonts.
> It is no more reasonable to re-layout a carefully designed UI then it is to reposition objects and people in a movie scene played on devices of different resolution
Is this unreasonable? We don't have the ability to design this kind of responsive control over video streams, but we do have the ability to speed up and slow down videos, embed captions that use native device fonts rather than bake themselves into the video file, adjust contrast and brightness, skip over segments and timestamps, and to adjust audio balance. And many players also have the ability to zoom in and cut off black bars. None of that seems like a problem?
I'm regularly thankful for the ability to auto-skip intros and adjust playback speed. Every single video player should have the ability to play at 1.5x speed.
I think in general it's important to separate practical design from art. I don't think any user has any obligation to worry about whether or not it's "reasonable" for to adjust an interface in whatever way works best for them. The goal of design is to make it easier to accomplish a task; the designers individual vision doesn't take precedent over that.
> Adjusting for that difference is the domain of the operating system and the user.
That's exactly why we have semantic units that are tied to a specific meaning/purpose, not ones that just represent abstract concepts like pixel width. The purpose of an `em` unit for widths is to describe the design of a column based on its intended use -- to show X characters in a line. The more specific we are about not just the width of an element, but also the intent behind that width, the easier it is for an OS and a user to adjust for size differences in specific scenarios.
If I drop a page to 300 pixels, did I do that because I want the font to be bigger? Am I scaling the entire window down including the font? Do I want the same design and font-size in a single column? Semantic units allow me as a user to communicate the context a page is in, which allows the page to respond to that context.
Absolutist design is anti-customization; it imposes the designer's will over the user's will. This matters because even in a single device/platform, it can often be impossible to design a single interface that always works. I use i3wm, so when I open a program it opens in tiled mode. You might get half of the screen, you might get 1/3rd, you might just get the upper left corner. The websites and programs on my computer that are designed responsively handle that, and the ones that aren't, don't. Thankfully, native programs have (slowly) started to get better about things like dropping out of 3-column views when they only have 300 pixels to work with.
But the answer to that problem can not be that from now on I'll just open every program in full screen mode so the designer can perfectly position every element. The answer is responsive design, and if that means that a few pixels are out of place when I jam the design into a 328x451 pixel box, then that's fine. I want the interface to work inside the box first, to fulfill its functional requirements, and then to look pretty second.
> Size your fonts with `em` and `rem` units, and size your containers based on the number of characters you want to fit in each line.
AFAIK this is not a good solution in most situations. The number of characters that you can fit on a fixed container varies greatly depending on platform / font / settings. By consequence, you'd lose a whole lot of control over you layout if you were to scale the containers in this way.
I realize this is going to come off as dismissive, but don't use fixed container widths.
Responsive design is a paradigm shift away from perfect pixel-level control over every container size on a static-width document. It's not print design, it's a different medium.
Stop making fixed layouts that break whenever I snap a window at half-width to the side of my screen; there are legitimate reasons why someone on a computer might want their fonts to be bigger or smaller, and your column widths should adjust to accommodate that.
I recently had lasik and went through a period of a few weeks where I couldn’t read small text on screens. It’s absolutely infuriating that you can’t just increase the text size on most websites. Most websites when you increase the text size it balloons the entire design as well. I had to do so much swiping left and right every line because text doesn’t reflow the way most designers code for the web. Em units should only be used for text, not for other aspects of your design. Let the text reflow within a fixed-size design!
I agree with pushing all aside to size by "Cap height" and "distance between baselines", but like you: totally disagree with using pixels.
Font size is a ridiculous nonsense land with so many gotchas that it deserves it's own University semester, but pixels are a clear, specific, and-tangible thing.
It would simply cause more issues as a certain number of designers would forget or not even be aware of physical pixels, and further cloud the space as they communicate with peers, bosses, subordinates, and the public.
We could probably get to exactly where the author (and I) want to be by changing `em` and `rem` to use cap height and distance between baselines, or by using a new measurement altogether (although: https://xkcd.com/927/)
Agreed, I would have no objection to having more typographic tools on the web around stuff like line height.
I don't want to get rid of `em` units, because they represent the font designer's vision of how the characters are best sized and positioned. I regularly do want to defer to that in my interfaces.
But yeah, lining up fonts is a pain in the neck. The author is right, it would be nice to allow line-height to be defined more consistently. It would be nice to allow me to somewhat size two fonts to be the same height or width as each other without eyeballing things.
So no, not pixels, but sure, have more ways of talking about font size based on concepts like baseline and cap height.
If the font designer's vision is for the character baseline to be above or below other font's baselines 'within the em', I want to override that vision.
As well: I feel like this type of standardization could actually free designers to make more interesting typographical layouts as they could freely mix fonts and sizes without cascade effects on the rest of the text.
Right. In a lot of ways it's the same principle we're talking about on the web with using `em` units. Give users control (except in this case the layout designer is the user).
I want font designers to be able to define a basic box and baseline for their font, and I want to be able to respect that if I'm just throwing the font onto a page without thinking about it. But I also want to be able to easily override it if I'm mixing fonts, and to be able to override it without manually adjusting a bunch of margins by trial and error that are specific to that font -- margins that will then immediately break if my users sub out their own fonts again.
It's good that we have controls in CSS for stuff like line height, ligatures, character spacing. Having more of those controls would be useful, and having quick options for them that can kind of "standardize" different fonts to all act the same would be very useful.
I feel like combined with https://tonsky.me/blog/font-size/ that these comment threads are fleshed out enough to go the HTML and CSS groups for discussion, refinement, and eventual implementation.
Clear, useful, reasonable, game-changing, and able to be opt-in.
This will fit approximately 30 characters at most on your aside and the font size will be 80% of the font size of the parent container (which is probably an `<article>` or a `<section>`).
Using em and ex is definitely the best way of doing relative font sizing, but the reason is something I don't think people properly understand.
1em is the width of a capital M character. 1ex is the height of the capital X character (of the font currently in use).
If you specify block element dimensions using em and ex values, then the margins and paddings will be relative to the font and it will look really nice (in my opinion).
1em as used in fonts and browsers has nothing to do with the size of a capital M character (though the name as used historically means it should). A font is drawn using a design size box (typically 1000x1000 units in OTF, 2048x2048 in TTF) and this box is scaled to the 'em' size. How big the glyphs inside the design box are drawn varies from font to font (which is the problem that the article is talking about).
The ex unit is supposed to be the height of the _lower case_ X character (not the upper case) -- but typically is just 1ex = 0.5em
A couple people have brought this up, and I'll admit I don't really get what they mean. The article is pretty clearly critical of non-pixel based rendering.
Three of the four problems the author sees with fonts:
> Unpredictable: you can’t guess what you’ll get. 16 pt means how many pixels, exactly?
> Not practical: you can’t get what you want. Want letters to be 13 px tall? Can’t do it.
> OS-dependent. Get different rendering when opening a document on a different OS. Can’t share editor config between macOS and Windows.
Most of those complaints are relevant to what I'm talking about:
- A pt measurement unit might be different between computers, which the author considers a serious problem to solve, and the web considers to be a fact of life to be embraced.
- There's no way to specify exactly how many pixels a font takes up, which is not necessarily a problem people should be trying to solve.
- Different OSes might display your font at different sizes, which is, again, not a problem that most native apps should be worried about.
The author does have a (somewhat) legitimate complaint that `em` units are somewhat arbitrary. It's a little bit weird because it doesn't acknowledge that in this case "arbitrary" means specifically chosen by the font designer to incorporate the best spacing for their font. But whatever, I can get behind an effort to make it easier to compare fonts to each other, and it doesn't seem like there's a compelling reason to force everyone to follow the font designer's choices.
But the author's solution is to use pixels (or some other unit-based non-relative measurement that will be guaranteed to render at the same size across OSes):
> Specify cap height, not em square size.
> Specify it in pixels.
In short, I share the author's frustration that there's no way to relate different fonts to each other in a reliable way, I share their frustration over working with line-heights, but I don't see how their criticism of pts and need to have font size perfectly synced between Windows and Mac works into that. In a responsive world, it should not be an issue for your app that font size might be a different number of pixels than you set it as.
No thank you.
I regularly wonder if it might not be better for the web if we got rid of pixels as a unit entirely. We can't realistically do that for a lot of reasons, and there are legitimate reasons to use pixels sometimes, but resolution independent font-size and container sizing should be the default. If you are using pixels on the web for font sizes, consider this a public intervention that you need to stop.
The fact that `em` units are not related to physical size attributes is intended. We don't want them to be related to physical size -- what `2em` is saying is that you want a piece of text to be twice as large as the "default" size of the specific font on the platform/device. That is a superior way to think about text size, because as a user I don't want you to try and figure out what the pixel density or screen ratio or resolution of my device is.
Size your fonts with `em` and `rem` units, and size your containers based on the number of characters you want to fit in each line. Don't use pixels. It doesn't matter if your fonts are bigger on Mac or Windows. It is intentional that platforms can size their fonts differently, and your interface designs should take that into account.
If anything, native platforms should be moving more in this direction, they should not be moving away from it. There was a period where you could decide to only care about responsive design on the web, but increasingly you should be thinking about responsive design on native platforms too. And resolution-independent font-sizes based on the user/platform are part of that process.
EDIT: Yes, I'm aware that pixels on the web are not necessarily 1:1 ratios with physical pixels on a screen. That doesn't change anything, pixels are still bad to use on the web. Tying font size to resolution, whether that's browser window resolution or physical resolution, is still equally problematic. And it certainly doesn't mean that we should move in the opposite direction on native devices -- the web's pixels are the way they are because the alternative, being tied to literal physical pixels, would be even worse.