6 ms·
> 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
> 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/ https://jsfiddle.net/jbwf6um4/
> 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.
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.
>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 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.
> 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.
> 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 https://github.com/twbs/bootstrap/issues/19943
> 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.
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.
deleted 6y ago
[deleted]
> 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.
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.
A) monitors do report physical size to the OS!
https://en.wikipedia.org/wiki/Extended_Display_Identification_Data 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.
> 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.