12

I've noticed that when I use large images, and use CSS to show them at small sizes, they look much better quality than images that are the correct size. Why is this the case?

Is CSS loading the full image, which just appears better on screens with higher resolutions? If that is the case, what is the best practice with approaching this problem in web design? Am I simply compressing images incorrectly?

I'm just a little confused how I can visually shrink a large image to fit in a small space with it looking great, but I cannot seem to replicate that quality when exporting to the same size.

3 Answers 3

20

It's most likely due to viewing images on retina and high density screens.

Before the introduction of Retina-class displays, the average screen density was far lower. Web-based images included enough pixels to cover a certain height and width at a standard 72 ppi. Many included no more pixels than that, because they had to conserve bandwidth.

Increasing pixel density affects the quality of those images because it crams all their pixels into a smaller space. Displaying the image at the same size as before stretches it, putting gaps between its pixels. The result? A fuzzy picture with jagged edges that jars the viewer and detracts from your brand.

https://marketing.gettyimages.com/optimizing-your-images-for-retina-displays/

If you're needing further guidance on working with images, I'd suggest reading this article by Jake Archibald called Halve the size of images by optimising for high density displays.

11
  • 4
    "Gaps between its pixels"? No, that's not what happens. What's in the gaps? Can you see through to the inside of the computer? Jaggedness (aliasing) is because pixels are boxes (squares or rectangles), and those shapes don't lend themselves to smooth curves unless they are extremely small.
    – user8356
    Commented Nov 29, 2023 at 21:37
  • 5
    @justhalf - "retina" is just some marketing nonsense Apple made up. There is nothing special about it except it being higher resolution than "standard" cheap screens. It's most certainly not "displaying each pixel as 2x2 smaller pixels".
    – Davor
    Commented Nov 30, 2023 at 16:19
  • 2
    @MooingDuck - that's just the difference between physical pixels and virtual pixels. Again, nothing special about "retina', which is a marketing gimmick, additionally evidenced by the fact that "retina" is a trademark and not a patent.
    – Davor
    Commented Nov 30, 2023 at 17:52
  • 2
    @Davor The difference between image pixels and physical hardware pixels is what developers/designers are talking about when they talk about retina displays. I understand that it is also an Apple marketing term but it is also a term used by developers as shorthand for the phenomena. Saying "you need to adjust your image for retina displays" is easier than your preferred way of "you need to adjust your image in cases where the browser's pixel resolution is lower than the hardware's pixel resolution because the hardware will render each browser pixel using more than one pixel"
    – slebetman
    Commented Dec 1, 2023 at 3:20
  • 2
    @Davor ah, so your issue was with the term? I was focusing on the concept, since I don't really care about the term "retina" that you object to. You can call it Apple display or "high DPI display" and I would still write all my replies to you as what I already wrote. There is a conceptual difference between screens that is 1:1 to the virtual pixels, and those that need adjustments. That's what I'm talking about.
    – justhalf
    Commented Dec 1, 2023 at 11:24
13

(This a basically the same as Pete's answer, just written from a different angle.)


Because CSS "pixels" aren't really pixels anymore (and haven't been for quite a while).

So what is a pixel, anyway?

Wikipedia starts off with the following definition:

In digital imaging, a pixel […] is the smallest addressable element in a raster image, or the smallest addressable element in a dot matrix display device. In most digital display devices, pixels are the smallest element that can be manipulated through software.

OK, that sounds reasonable enough: your images are stored as a grid of pixels, and your screen displays a grid of pixels, and if you want your image to look sharp then you need to draw it so that one pixel in the image matches one pixel on your screen. Right?


Well, that was right, until about the year 2010. For about the preceding decade, since the popularization of 24-bit true color super-VGA displays (and also, coincidentally, CSS and modern web design) around the turn of the millennium, computer display technology had kind of stagnated, with the pixel density of most consumer screens staying pretty consistently around 70–100 pixels per inch, or around 1000–1600 pixels per horizontal row. And web designers had learned to expect this pixel density and to design their pages to look good on it.

Meanwhile, the burgeoning smartphone field was stuck with much smaller screens and only slightly higher pixel densities per inch, leaving them often with just a few hundred pixels per row. So websites optimized for mobile use would use images with less pixels, which coincidentally also helped with the often glacially slow mobile download speeds at the time.


What happened in 2010 was that Apple broke the technological logjam with their new iPhone 4 and its "Retina" display technology, which literally doubled the pixel density from the iPhone 3GS's 163 ppi (pixels per inch) to the iPhone 4's 326 ppi. Competitors like quickly scrambled to follow suit with products like Samsung's Galaxy Nexus phone with a 316 ppi display (and a larger physical size, beating the iPhone 4 in total pixel count) launched in 2011, and a few years later 300+ ppi displays were common even in midrange smartphones. And competition and technological progress kept driving display pixel densities even higher, up to well over 500+ ppi and in some cases much higher yet.

And a few years later yet, in 2015, Apple brought their Retina technology to their MacBook laptops as well, nearly doubling the pixel density there as well, kickstarting the high-PPI competition in laptop and desktop computer displays as well, eventually leading to modern-day 4K+ monitors.

But this sudden jump in pixel density created a problem, because web pages designed using pixel measurements would suddenly become basically unreadable when the pixels were only half the size their designers had expected. Also, back when the iPhone 4 was introduced, a lot of mobile-optimized pages were using the number of pixels per row as a proxy for physical screen size to decide which version of their layout to use, and might choose to render a desktop-optimized layout that was all but unusable on a small phone screen.


Apple's solution for the iPhone 4 was as clever as it was ugly: they just had their new phones lie about the screen resolution, reporting only half as many "logical pixels" per inch (and per row) as the new screen actually had, and scaling all pixel-based measurements up by a factor of 2 correspondingly. That way, old apps and websites optimized for the iPhone 3GS would look exactly the same on the iPhone 4, just with slightly crisper text and vector graphics.

And all that designers had to do to make full use of the new iPhone's increased display resolution was to double the "natural" size (i.e. width/height in pixels) of their raster graphics (JPEG / PNG / GIF) images, and scale them down by 50% in CSS. Problem solved!

Other OS and browser vendors adopted the same strategy, and eventually it even got codified, to the point where modern CSS standards now simply define "1 px" as 1/96 inches, thus effectively emulating a traditional 2010 era computer display with 96 ppi, while the actual pixel density on a modern display is likely to be at least twice that, if not more.


Of course, in practice the CSS definition of 1 px = 1/96 inches is also a lie. It's a lot more likely that one CSS logical pixel is actually some fairly round number of physical pixels (often 2, but possibly 1.5 or 3 or even more, depending on the user's display settings), since that tends to result in cleaner graphics rendering. It just means that CSS "logical inches" (and centimeters, millimeters, etc.) won't match up with their real physical counterparts, either, since one "CSS inch" is just 96 "CSS pixels".

For example, the 16" 2023 MacBook Pro I'm typing this answer on claims to have a screen 1728 logical pixels wide (with twice that many actual physical pixels) at default zoom, and that's also the screen width Firefox reports. But I just measured the width of the viewable screen area with a ruler as approximately 345 mm, or about 13.6 inches, giving my screen a logical resolution of 127 ppi (or physical 254 ppi, which matches Apple's technical specs).

And of course, that's all ignoring browser zoom, which is a ubiquitous feature nowadays. A large fraction of desktop users nowadays keep their browser zoomed at anywhere from 75% to 150% or more, just depending on their eyesight and what text size they find most comfortable to read. And people browsing on mobile devices tend to zoom in and out all the time, since all it takes is a simple pinch gesture.


Anyway, the upshot of all this is that, for the time being, the basic recommended way to get raster images to look decently sharp on the web is to save them at (at least) twice the intended "logical" pixel size and scale them down with CSS.

If you want to spend time optimizing things further (or have automatic middleware to do it for you), you can use image source sets to serve multiple differently scaled variants of your images and have the browser choose which ones to download and show depending on the physical pixel density of the user's screen.

Or, better yet, use vector graphics where possible: they'll automatically render at the optimal resolution for each screen and can be freely zoomed without having to download additional versions.

1
  • Thank you for this answer. I think this complements the other answers very well, and give more practical context on how things work with CSS. I'd be interested to see what best practices different companies use to address this problem.
    – Sam Sabin
    Commented Dec 3, 2023 at 3:19
8

In addition to @Pete's excellent answer, it's also possible the images you are using are overcompressed. When you scale down a large image it has more information to work with and so it can appear better when scaled down. If, for example, you use JPEG compression to make a very small image it will tend to be quite blocky and have speckles. Reducing the size of the image will reduce the block size, and average out the speckels. The solution is generally to up the jpeg compression until it looks right at the desired resolution.

Also, I believe that Windows by default upscales pages to 120% - so if you have a correctly sized image it may upscale the image by 20% causing artifacts and loss - and having a bigger image to start with may look better (this is speculation as I do not use Windows).

CSS instructs a computer how elements (including images) should be rendered. It does not typically modify the image / image quality itself [although CSS can instruct the browser to modify the way the image is rendered] - that is to say the full size image is sent to your computer and CSS would not normally affect the quality of the image.

It may be worth adding more information (and maybe even a couple of images for us to look at. Particularly useful would be the image format, screen(s) you are using to look at them at etc.

6
  • 3
    It's also worth noting that css px are not actual pixels, they're defined as 1/96th of an inch.
    – marcelm
    Commented Nov 29, 2023 at 13:09
  • 1
    @marcelm very,very Interesting - only partially correct - because many devices (eg standard PC screens) cant tell actual resolution and this is all a bit "handwavy" - hacks.mozilla.org/2013/09/css-length-explained digs into it even more. Thanks again fir the comment -TIL...
    – davidgo
    Commented Nov 29, 2023 at 17:57
  • 1
    "Windows by default upscales pages to 120%" - do you have a reference for that? And do you really mean the OS, or rather a specific browser?
    – Bergi
    Commented Nov 29, 2023 at 20:47
  • @Bergi I confess to not having references for this and on reflection I was parroting something I was told and probably shouldn't have. (More research reflects different scaling defaults in Windows - but these are, I suspect, set by the Laptop vendor, and varies). The problem we had was similar to reddit.com/r/UXDesign/comments/x8w0dt/… - and stackoverflow.com/questions/58868613/… is relevant here and makes me think I'm only partially right.
    – davidgo
    Commented Nov 29, 2023 at 23:06
  • @marcelm You could also say that an inch isn't an inch since the same reference defines it as 96 px. I think on a standard display at 100% browser zoom, pixels are equivalent to px, and other measurements take their reference from that. Certainly a '1in' size will be different on the same resolution at different display sizes if viewed at 100%. Commented Nov 29, 2023 at 23:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.