The problem with ‘pixel perfect’ design

Pixel perfect design worked well for about 100 years. But in 2025, with every screen being a different size and the ever growing need for accessibility, we need something better. In this talk, Craig will cover the pitfalls of using static measurements, and why designing in systems and math rooted in musical theory may be a better approach.

Craig Abbott

Craig is a Principal Accessibility Consultant at TetraLogical and the former Head of Accessibility at the Department for Work and Pensions. He is passionate about neurodiversity, and is an advocate of accessibility that goes beyond just compliance.

Links

Video Permalink

Transcript

Hi everyone. So yeah, I'm Craig. I'm a principal accessibility consultant at TetraLogical. Before

we start, I always like to just let everyone know that I have ADHD and I'm also autistic.

So depending on which side wins, the talk will either end up super clinical or like

super erratic. And I've got a lot to get through, so hopefully the ADHD wins. But yeah, I think

also as well, just to point out, when I was talking on the way in about what I'm about

to talk about, I think given the people who are in the room, I think, you know, hopefully

this will just be stuff that you already know. But then thankfully Matt did a talk all about

stuff that you already know, so I'm just going to ride with that. But yeah, I want to talk

a little bit about pixel perfect design. I've worked in a few organizations where this is

a thing still where designers get really hung up on everything being pixel perfect and everything

being exactly in the browser as it is in the Figma file and whatnot. And I find it a bit

bizarre that this is still a thing in, you know, 2025. So pixel perfect, basically just

making whatever's in the browser and whatever's in the Figma file or whatever design file

they're using just look absolutely identical. I mean, I've literally seen a designer screenshot

the browser and overlay it in a Figma file and be like, this is 10 pixels out or something.

And really only designers care if something's not pixel perfect. Users don't care, developers

don't care, product managers don't care, but we spend ages making it look pretty and we

want the final design to reflect our expertise. So often designers are the ones that are the

ones pushing it. But pixel perfect does cause headaches for developers. I lost my water.

Yeah, so developers with pixel perfect design, we find they write more CSS, they're often

having to use override utility classes or write custom CSS to override things that are

already there. The company that I previously worked at, we had a design system and there

was just loads of like inline styling being put on the components just to make everything

look exactly as the designer wanted it to look. And that creates inconsistencies and

it creates headaches for developers. But pixel perfect is an interesting term because perfect

is really subjective. Different designers have different opinions on how wide a margin

should be. If you ask the same designer on different days, they can have different opinions.

So like the term perfect is really subjective. So I think also when we talk about pixels,

yeah, so this again caveat I suppose for this talk is that I find a lot of designers don't

necessarily understand pixels. We often think that a pixel is a pixel on a screen like a

tiny square or something. I'm assuming everybody in this room knows what I'm about to talk

about. But yeah, so pixels are basically picture elements. So if we take a picture or pix and

then we take elements and Ls, we end up with pixels. The digital pixel is the smallest

element of a digital picture. So if we take this awesome picture of a cat and we zoom

in in Photoshop or Figma or whatever it is and we keep zooming in, we eventually get

to a pixel which is the smallest element of the image which is a solid block of color.

Then we have physical pixels which are the smallest element on a modern display. So again

if we took a nice picture of a cat on a monitor and we zoomed in and zoomed in and zoomed

in, we eventually get to a red, green, blue pixel element. And this worked really well

for about 80 or 90 years because all screens use the same 4 by 3 ratio and there was roughly

a 1 to 1 mapping. So when they were firing electrons at the screen, you know the RGB

area was roughly a 1 to 1 mapping. So everything kind of just worked. Content just scaled up

and down. It didn't need to adapt. It didn't need a reflow. It didn't need to do anything.

If you put it on a small telly or a big telly, it just looked the same but bigger. But these

days screens are not consistent. So we've got different dimensions, we've got different

aspect ratios, and we've got different pixel densities. Physical pixel densities I suppose

it should clarify. And then to complicate Matt as further, we have CSS pixels which

are abstract units which are calculated by the browser. And these can be made up of any

number of physical pixels. So you know when you say 10 pixels, it might not be 10 pixels

at all. It could be whatever the algorithm is trying to work out, you know, how big to

draw it. But CSS pixels do help us make things roughly look the same size on different screens.

So you know if something's roughly arms length away, it should all look the same size regardless

of how many physical pixels there is on the screen, which is helpful but it means this

whole term of pixel perfect becomes a little bit tricky. And this is why pixel perfect

design is hard is because pixels are not perfect. Like one physical pixel is not one digital

pixel, one digital pixel is not one CSS pixel, and one CSS pixel is not the same on every

screen. So it becomes really difficult when you're trying to explain to a designer why

you know they're 10 pixels isn't 10 pixels. And so moving on to the problem with pixels.

As I've just said, you know like you can draw something out to be 10 pixels on a screen,

it might not necessarily be 10 physical pixels wide, but it will always be the same size

on a particular screen. So if you in your browser say I want this thing to be 10 pixels

wide, every single time the browser draws that it'll be the same physical length on

the screen. And static measurements by definition are not variable. So for example, if you are

instructed to drive a car at 60 miles an hour, you will always drive 60 miles an hour. It's

just a static unit of measurement. And the same with the 10 pixels variable, sorry, the

10 pixels measurement. But user preferences are not static. So in Chrome, for example,

the font size can be medium, which will be 16 pixels by default. But then you can go

into the browser settings and you can change that. So you can have very small text, which

will be 10 pixels. You can have small text, which will be 13. You can have large, which

will be 20. Or you can have very large, which will be 24. If you're like my dad and you

need everything to just be massive all of the time, you'll go straight in them settings,

bag it on 24, and then you'll probably find nothing changes. And this is where static

measurements can actually cause some accessibility issues. So things like font sizes and margins

and patterns, which are set using pixels, will never actually react to the user's browser

settings. So this is an example of Facebook, which does set everything in pixels. And basically,

if you go into your browser settings and you change small or medium or very large, like

nothing happens. I think in the dev tools, you can see the font size change slightly,

but that's the only thing that changes. Now, using pixels as a static size is not actually

a WCAG failure on its own. The web content accessibility guidelines, they care if you

can zoom in at 200% and then everything doesn't break. But they don't necessarily care whether

the content responds to the browser settings. But in situations like my dad, for example,

where he has the font size on very large, if he's on his phone and he goes on a website,

the font size always just -- if it's set in pixels, it's just always the bare minimum.

Then he has to start trying to zoom in on his phone, and then he ends up starting to

scroll around in two dimensions and everything's just kind of off. Whereas if it just responded

to the browser settings, he'd just be able to scroll up and down and everything would

work. So it's not a technical accessibility failure, but in real life situations, I've

definitely seen it where it affects people trying to kind of get around this. And also,

it means that when you're zooming in on the browser, if you're using manual zoom, like

my view shown earlier, it's not a great experience. Like, this puts an additional burden on the

user. So every time they go to a website, because it doesn't persist across domains,

so every time you go to a website, you can zoom in at 200% and you can navigate around

that website. But then as soon as you go to a different one, you've got to zoom in at

200% again, so the whole thing becomes really tedious.

The other thing that is a problem is that it just makes everything bigger. Like, when

you zoom in on the browser, like borders, on inputs, like everything just gets bigger.

If you zoom in far enough, you can be filling in a form and you've got like a 30 pixel border

on you and everything just looks a bit trash, really. So using relative measurements creates

a more accessible experience. And relative measurements use a reference point. So now

if we talk about the car example, if you're told to drive 1.2 times the speed limit, I

realize now this is terrible advice. Don't do that. Drive at the speed limit. It should

have been like 0.5 of the speed limit. I realize now, yeah, don't do this. But yeah, if you

drove a car 1.2 times the speed limit, if you were on a 50 mile an hour limit, you'd

drive 60 miles an hour. If you were in a 60 mile an hour limit, you would drive 72 mile

an hour. So common relative units we can use in the browser are percent, ems, rems. But

percent and ems can be challenging. So when I've tried to explain these concepts again,

normally to designers or people who don't necessarily know the ins and outs of browsers

and things, their reference points change, which, depending on which CSS properties they're

used on, means that you can essentially end up with different sizes. So for example, 1M

is not 1M. If you set your font size to 1M, the font size will use the parents element

font size to then set itself. But if you use it on a margin, it'll use the font size of

itself to set the margin. So you end up with these sort of variations in what size you

might actually get in your design. And ems and percent also suffer from a problem called

compounding, where because they are using their parent elements, when you nest them

under themself, you can end up with exponential results. So if you, for example, had a child

that was supposed to be 2M and the parent was 16 pixels, you'd want the font to be 32

pixels. But if you nest a child within a child, the first child becomes the parent. So now

it's doing 2M of 32 pixels, which would be 64 pixels. And if you nested it again, you'd

end up with 100 and I can't do math, 28 pixels. I don't know. So yeah, this compounding problem

can be challenging. So then we've got rems or root ems, which is the font size of the

root element, the HTML tag, if you like, and that inherits from the browser settings. So

this time, if we use rems, then we can get a nice, we can get access to those user preferences

and we can use this to our advantage. So a rem is whatever the user chooses in the settings.

So we said before that could be 16 pixels at medium, it could be very large at 24, it

could be very small at 10. And one rem does equal one rem. So if you set the font size

in the browser to be 16 pixels, and then you use it on font size or margin, then it will

emulate whatever it's set in the browser. So everything will be as you kind of expect

it to be. So rems don't compound either, the same way that ems and percent do. So we can

nest them as deep as we want and it will always kind of work out the way that we expected

it to. So this is an example where, you know, things of margins and font sizes and things

have been set up using rems. And now when we change the settings in the browser, you'll

see that everything just kind of responds to those things. So you don't have to actually

zoom in on the website anymore. You come to this website and your font size is set to

very large, it will just respect it off the bat and you don't have to then zoom in and

do all of that stuff. And rems are great, but we still need a system. So we can replace

pixels with rems and things will scale, but we still shouldn't just be sitting squinting

at Figma and like eyeballing values and just going, "I think that's about two rems." Like,

we still need a system in place. So I'm going to talk a little bit about harmonic scale.

And this is about to get a little bit weird, but it is design related, I promise. And people

might have heard of harmonic scale or modular scale. There's a really good book called Every

Layout by Hayden Picker and Andy Bell, where they talk about this in more depth and they

give a lot of, it's a really good book. If you have not read it, I imagine everyone probably

has to be honest in this room, but yeah, if you haven't, it's definitely worth looking

at. So when we talk about harmony, if we look at the Oxford dictionary, it says it's the

combination of simultaneously sounding music notes to produce a pleasing effect. So good

music is not random, like harmonies only exist because of the physics of sound waves. So

if you put waves together where the high and low points meet up, they will create harmony.

And humans can sense harmony. Like even if you don't understand musical theory, you just

know when a note is off. It just feels wrong. So we have these things called harmonic scales,

which is a defined set of notes that mathematically complement each other to create harmonies.

So if you're learning to play a guitar or whatever and you learn your scales, then you

know you can play, if you've got to knock a solo out, then you can just play any of

them notes and they should just work together, in theory. So for example, some notes in the

C major scale are C, G, C, E and G. And hopefully the sound will come out, but you can play

any of the notes in the scale and they'll work because science.

So you can play them in order, you can play them all together, but mathematically, because

those waveforms line up, they just sound quite nice. If a single note is not part of the

scale, hopefully you'll realize that it just feels not, it's a bit, makes you feel a bit

uneasy.

So yeah, without harmonic scales, making good music would be a lot of trial and error. I

mean, you'd literally just be sitting there going, nope, that feels wrong, that feels

wrong, that feels wrong. And we can apply the same logic to visual design. So if we

design using a harmonic scale, or it's also known as a modular scale, we start with a

base size or a fundamental and then we use a ratio to calculate the harmonic sizes off

the back of it.

And choosing, when you're looking to choose a base size or a ratio, it can depend on the

kind of style you're looking for. If you've got quite a, like a plain website, you might

have a bigger fundamental or you might have a bigger ratio. If you've got a really content

dense one, you might want to choose something smaller, but ultimately it doesn't really

matter what fundamental or what ratio you choose, but it is normally better to pick

one that's based on a little bit of logic. So 16 pixels can be a good fundamental because

that's the default font size in the browser. And 1.5 can be a good ratio because that's

the minimum line height that's used to assess text space in WCAG 2.2. So that could

just be two reasons why you picked those, but you could pick anything that you wanted.

Then we multiply and divide each increment to create the scale. So if we start with 16,

we would do 16 times 1.5 because that's our ratio, we'd end up with 24 pixels. So the

next size up would be 24. Then we would take 24 and we would multiply that by 1.5 again

and we would get 36. And if we went the other way, we'd take 16 divided by 1.5 and we'd

end up with 10.67 and so on and so forth. So we'd end up with this harmonic scale for

design where essentially our waveforms would line up based on the sizes that we used. And

the scale is not linear, so choosing sizes becomes easier as a designer. Like if it looks

too big, then we just use the next size down and we don't have to sit and eyeball things

anymore. And the whole idea of it being not linear means that you don't end up just with

increments of like 10 pixels, which is what I assume some designers would try and do just

to maintain some semblance of control. And I think this is a good point to make is that

you know your scale should only need two or three sizes in each direction most of the

time. If you end up with too many options, then you're probably trying to cling to too

much control and you just need to relinquish it. So in Figma, we can use variables to create

a harmonic scale in pixels. So you can actually go into Figma, you can set up a whole bunch

of number variables. So the only annoying thing about Figma is you can't calculate off

another variable.

That's the only thing annoying about Figma.

Sorry, the only annoying thing in this context about Figma. Yeah, God, that would be an entire

talk in itself that we wouldn't get through in 30 minutes. But yeah, in Figma you can

do this and you can do math in the input when you are setting your variables, but you can't

use other variables to calculate off, which is annoying. I'd rather just be able to set

a variable like scale zero and then do 1.5 times scale zero, but you can't do that in

Figma. But you can set them up and then once they're set up once, you can then just use

them in all of your margins and your font sizes and all that sort of stuff. And in CSS,

you obviously can use variables. So we can create our harmonic scale in REM. So we can

just use the calculate function and we can pass in the variables from previously. So

we can literally just set the ratio and the kind of base scale at the top and then everything

else is just done automatically.

And if designers and developers are using the same scale, everything ends up automatically

in sync. So the designers are in Figma, they're using variable scale one and the developer

has variable scale one and then nobody has to really worry about eyeballing those pixels

and screenshotting the browser and overlaying it in Figma and whatnot. We just trust the

system.

So a wrap up. Like pixel perfect is an outdated way of thinking about design. Like in 2025,

we shouldn't be squinting at Figma and just trying to work out if the pattern looks better

at 10 or 12 pixels. Like we should just trust the system. I mean, the amount of times where

you know, I've literally been in conversations where two designers are arguing over two pixels

and that just, I cannot grasp why that is a thing in 2025. There's obviously better

ways to solve this problem.

But designing in systems is better for everybody. Like designers spend less time visually balancing

designs and developers spend less time writing custom CSS and overriding all of the stuff

that's kind of already in the system. And I think as Jerry alluded to earlier, there's

a lot of time that gets wasted prepping for dev where a designer's job is literally to

go through that Figma file and eyeball all of the margins and everything so that the

handover is as smooth as possible. And I mean, you know, it takes up to a day sometimes to

go through all, you know, how inefficient can you get really.

And scale, scale. If everyone just started using bigger screens tomorrow, you can just

go in and adjust your ratio and your base size and then everything will just work if

it's set up properly. Everything will just scale. Even if the spacing changes, the balance

will remain because the scale has been set up to work mathematically.

Pixel sizing is still useful for some things though. And these are things which shouldn't

scale. So if you are putting a border on something and you want it to be three pixels, that's

perfectly acceptable. That means that when somebody comes in with their 24 pixel very

large size, the border still stays the same. Whereas obviously if you'd set that in rems

or whatever, it would scale with it. So pixels in some absolute positioning, like if you

want something to be at the top right of the screen, for example, and it's like 50 pixels

down, you don't want to necessarily be using a scalable size there because then when people

come in, it'll push everything over. So there is still some uses for pixels, but it should

only be things where everything, you want it to remain static.

And I guess if you take nothing away from this talk, take this away and that's that

nobody needs an app or a website to be pixel perfect, but everyone needs it to be usable.

And that's everything. Thanks.