Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.

[0]: https://jsfiddle.net/jbwf6um4/


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’ve not checked: I change the default text size on my iPhone. Does that impact Safari?


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.


If pixels and points are the same thing, don't all the arguments in the OA apply to pixels, then?


> 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.


> Virtually nobody uses font-only zooming.

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.

[0]: https://github.com/twbs/bootstrap/issues/19943


> I mean, you can say this is uncommon and I'm in a bubble

If you use Firefox, and several people around you use Firefox, then you are definitely in a bubble


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?


What is the use case for font-only zooming?

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.


> What worries me is the testability.

This is why you should keep it simple :-)

This is the web, not print publishing.

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:

    <h1>
      <svg class="svg-icon"><use href="sprite.svg#my-icon" /></svg>
      Some Heading
    </h1>

    h1 {
      font-size: 1.5rem;
      color: rebeccapurple;
    }

    .svg-icon {
      fill: currentcolor;
      height: 1em;
      width: 1em;
    }
Do you care to tell me why em units are not recommended anymore, and who it is recommending rem in favor of em?


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.


>Nobody does that anymore.

It's used as an accessibility option for people with low visual acuity.


Nobody does that anymore. /s


> Nobody does that anymore.

I use Ctrl+'+' all the time to zoom text.


The default behavior of Ctrl-+ (and the only behavior in Chrome, Safari, Edge) is different from Firefox's "Zoom Text Only".

Just hitting Ctrl-+, it eventually switches to the mobile stylesheet https://i.imgur.com/E7rAR37.png

With "Zoom Text Only", the layout partially breaks and you get columns of text with only one word per line https://i.imgur.com/C5NiyFA.png


>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.

That's not what happens though. CSS pixels are independent of the resolution and logical.

https://www.w3.org/TR/css3-values/#absolute-lengths


Two things:

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.


A) monitors do report physical size to the OS!

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.


> A) monitors do report physical size to the OS!

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. ]


CSS px * devicePixelRatio = physical pixels

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.


> ResizeObserver

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 will check out that ResizeObserver property.

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.

Basically rounding down.



There is, ResizeObserver -> device-pixel-content-box But ATM it's Chromium browsers only.

Some examples on this page

https://webglfundamentals.org/webgl/lessons/webgl-resizing-t...

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

<img src="100x50.png" style="width: 400px; height: 200px; image-rendering: pixelated;">

But, what's the browser supposed to do with that on a screen with 1.25 devicePixelRatio? It will look like crap.


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.


Playing with xterm.js with several fonts trying to get some regularity is/was an exercise in frustration for sure.


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.


The benefit of rem is of course that if I want all fonts to be 1.5 times bigger, al I need is:

html { font-size: 150%; }

Then, 1 rem = 16 px will become 1 rem = 24 px etc.

With pixels, I will always be stuck with having to update every value in my CSS.


I understand why, but to outsiders it is odd that the one measurement you don’t specify is physical size.

12pt is ~4½mm.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: