Best measure unit for web developmentis a combination of pixel and rem

| In Articles | 30th July 2024

Read bellow to find out how to use px and rem as measure units in the best possible way

As a web developer, web designer or if you work in the IT department, you definitely heard about pixels.

Pixel is a measure unit for screens and is the number that is defining the screen size.

The inch measure that you are used with when you are looking at a display size is the physical measure of a display, but it's real size that will define how many elements you will see on a screen at one time and at what quality is given by the number of pixels on horizontal and vertical.

Sure this is not all, because is also the density of the pixels per square inch, but is is not something to discuss under this article because is irrelevant for the thematic I choose.

The intention of this article is to give a clear image about what the pixel is, how is used in the real world and why measure units like rem or em are not helpful in the development phase of a project or in testing/debugging phase.

A bit of context

Pixel as a measure unit exist from the moment the fist display was built. No matter if we speak about a digital watch display a monitor or a TV. They are all built of pixels from left to right and from top to bottom.

One pixel display will only be able to show a dot. And a dot is a dot. We will not be able to divide a dot in 2 or more (technically). A dot is considered to have a perfect proportion shape, as a square or a circle, so we can't divide a square or a circle in 2 and still have the same shape on both sides.

On displays a pixel is considered to be the smallest unit we can get. Depending on the density of the display per square inch a display can have more or less pixels which will make the elements that you will watch bigger or smaller. For this reason, a small screen with a big density or pixels can fit into the view many elements but it will be hard to read them because they will be very small.

On such type of displays, the user ends up by changing the resolution or zooming in anything is looking at, defeating the need of having more pixels per square inch.

What the design software are using as measure unit

Designers will know best here

Photoshop, Gimp or any other design software is using pixels as a measure unit.

Even Illustrator is using pixels and is a design software that is creating vector elements. For the development phase the pixel is used to give the item shape and one the shape is given the final product is vector.

The reason the pixel is used in the design phase is because a pixel is the most precise thing that a user can report to when creating and aligning elements.

A similar logic is on the development/coding phase

On a browser we can also have em and rem as a measure unit and these two are working in a tight relation with the global font size that is set on the body of a webpage or if this is missing, the device default font size.

More in details, if a webpage body font size is 14px, a 40px font size that was defined in a design software by a designer, will translate in rem as 40/14 = 2.85rem.

Because the human mind is not trained to generate these numbers automatically a calculation as the one above is needed.

A web developer needs transparency when coding a website to make things easier.

If a font size in the design software is created with a size measured in pixels, this has to replicate in the code still as pixels.

We know that the benefit of using rem or em consist in the result that they generate (a font size or a shape) which will change proportion depending on the global font size of the website or of the machine, as explained above. If the global font size is increased or decreased by the user the font size or the shape created by using rem or em will increase or decrease proportionally, when this effect can't be achieved if pixels will be used instead.

Utility tools as Tailwind are using rem measure unit as default and they give the possibility to switch to pixels if needed, but this is not enough and this is the reason I am writing this article.

Having rem as default will guaranty the best result in the browser but it will be hard to write when the design is generating measures in pixels and a website has to be perfect pixel built.

Tailwind is saying that is not forcing the user to use rem and pixels can also be used, but in this case pixels will be generated in the browser so any font size or shape that should change proportions when the global font size is changed, will not happen anymore.

The best approach that I didn't find yet without extending or adding new utilities is to define a size in pixel but have it generated in rem or em.

With SASS or other CSS pre-processors you can create a mixin or a function that will take a size in pixels and generate the same property in pixels first and in rem or em after. The second property will overwrite the first one so the first one will only be there as a reference to what actually the font size is. As example

@calculateRem($size) {
	$remSize: $size / 16;
	@return $remSize + rem;
}

@mixin font-size($size) {
	font-size: $size + px;
	font-size: calculateRem($size);
}

With Tailwind this thing is not possible without creating new classes or extending existing ones as you can see bellow

module.exports = {
	theme: {
		extend: {
			fontSize: {
				xs: pxToRemPair(10),
				sm: pxToRemPair(12)
			}
		}
	}
}

But what if I want the same thing for margins and padding and top, right, bottom, left properties? Apparently, at this moment in time with my Tailwind knowledge is appears that the only way to see both sizes in pixels and rems is to do something similar with that I did above.

A sad ending of seeing just rems or ems

Testing and debugging a website that is only showing measure units in rems or ems is very difficult to change and time consuming because is not transparent with what the design is showing plus it does not translate the sizes that people are used to use.

When a client is asking a web development agency to change a font size, because the client is not used with the development tools and even if he will be, he will see a measure given in rem or em when people are in general used to see font sizes in pixels as from Office Word or other utility tools. The process will generate frustration.

Let say the client can use the development tool and inspect the font size of an element only that is in rems. He can't know what is pixels equivalent value of that rem value so he is thinking to increase the font size with 1 or 2 points, but starting from what? Is that font size a 18px? a 20px?

Now, lets say that the client does not know how to inspect an existing element font size and he is just requesting an increase in size but he can't be precise again in what size to be next because he doesn't know the actual size.

So the web developer is involved and the code in inspected, being discovered that that font size in rems is actually an x amount of pixels. The clarification is getting back to the client and the client is able to take a decision with how much to increase the font size.

Font size is then increase and the webpage is sent to the client to be checked if is looking good but the client again can't check if that is the font-size he asked because is still in rem. The trust level might decrease at that moment a bit because is no transparency in the work done.

And look at the time spent to clarify with the client a size that is in rem or em and how many back and forwards are needed to achieve a small change.

The best solution is to set things in pixels but have them translated to rems or ems with the pixel property set first to be overwritten by the rem or em one. The browser will show in this way

    font-size: 16px;
    font-size: 1rem;

In the same manner for a font size used in rem it should be for a padding of the element that has the font size set in rem. Imagine that for accessibility reasons, a user with an eye condition is increasing a a device global font size from 16px to 40px. Because the padding around that text remains as 10px and is not translated to rem it will stay as a 10px padding and it will not change the proportion as a rem unit does. The whole view will be disproportionate and we will end with a large text cramped in a small space.