DEV Community

loading...

Percentages in CSS: you're using them wrong

maxart2501 profile image Massimo Artizzu ・2 min read

... if you do one of the things I'm going to explain.

The motivation for this post came after a colleague wrote something like this:

.foo {
  background-position: 83% 10%;
}

and I was like: "Huh, what?"

Of course, I had no clue of what was going on there. Only after I launched the project I had a hunch of the intent of the code: they were finely positioning an image in the middle of the right half of a container... and 10% from the top, because why not.

This led me to give them an advice I usually give to novices:

If you're using a percentage different from 100% and 50%, there's probably a better approach.

The point is that "100%" is commonly intended as "all the way" and "50%" as "half-way". (Note: I'm not including 0% as you should probably use 0 instead, but the idea is the same.) Any other value - including something apparently "easy" like 25%, 33% or 10% - is more difficult to recognize and understand.

What if I need that value?

Of course, that value could be totally legitimate and the result of a well conceived computation - although in my experience it's usually the result of trial and error 😅 (i.e.: "Does this value look good? Mmm, not quite, I'll add 1% more...").

Fortunately we have plenty of tools to write clearer code and convey the correct meaning. If you're using a preprocessor like SASS or LESS, you can avoid magic numbers altogether with a fine use of meaningfully named variables.

In the case above, the goal was to center horizontally an image on the right half of the container, with a with of 25% of the container. And that 10% was roughly the height of the header. So, ideally, the code would have been something like this:

$header-height: 8rem;
$image-width: 25%;

.foo {
  $bg-position-x: 100% - 50 * $image-width / (100% - $image-width);
  background-position: $bg-position-x $header-height;
}

This still could be improved (the way background images are positioned isn't as simple as one can imagine), but at least it's clear that the position depends on the image's width. And provides the correct value (83.3333...%).

If you're not using a preprocessor, you can still use plain-old CSS, as calc and CSS custom properties are now widely supported:

:root {
  --header-height: 8rem;
  --image-width: 25;
}
.foo {
  --bg-position-x: calc(100% - 50% * var(--image-width) / (100 - var(--image-width)));
  background-position: var(--bg-position-x) var(--header-height);
}

And if you need to support Internet Explorer... why aren't you using a preprocessor? 😱

Conclusion

Please use variables with meaningful names and have mercy on those who will maintain your code 😄

Discussion (9)

pic
Editor guide
Collapse
oenonono profile image
Junk

One quarter of my feedback in CSS code reviews is: make this a variable, name it meaningfully, and show the math.

Collapse
msarit profile image
Arit Amana

Interesting read! Personally I would probably use Flexbox to achieve the same. I'm just now getting into SASS and I am loving it! The more intuitive code is, the better (for me, anyways 😄)

Collapse
cutemaxi profile image
Oparaononaku maximus

Am hearing SASS for the first time, how does it operate?

Collapse
maxart2501 profile image
Massimo Artizzu Author

Basically, just like SCSS. Before SCSS there was SASS.

SASS is a preprocessor that introduced a new syntax that was fundamentally different from CSS. For example, there is no need of curly braces (it is "pythonic" in this sense) or semicolons at the end. But plain CSS can't be parsed as SASS, so they later introduced a new syntax that's compatible with CSS. And SCSS was born.

So SASS is SCSS with the older syntax. I don't know, though, if the new advancements in SCSS will be available in SASS too (i.e. @use and all the rest).

Collapse
jcpuxd profile image
John Park

I'm having a hard time understanding the type of background image this would be beneficial for... Do you have an example? I've used percentage for lifestyle shots where I want to position subjects into the element bounds in a specific way. The percentages are unique to that image, would this still apply?

Collapse
maxart2501 profile image
Massimo Artizzu Author

Yes, of course that would. Any time you don't know the size of a box, but you want something placed in the "same position", is a good fix for percentage positioning.

In my case, that was simpler. In the left half of the page we had the content; in the right, the disegner decided to have some padding from the boundaries, so there you go.

Collapse
skamansam profile image
Samuel C. Tyler

You don't need sass or less to take advantage of variables. CSS has native support.

Collapse
maxart2501 profile image
Massimo Artizzu Author

That's correct, as I've explained in the article 🙂

However, I usually rely very little on custom properties, as they're evaluated at runtime. This has advantages, of course, but with a (computational) price. If I know a value won't change during the lifetime of a page, and I can precisely fix the scope of it, I normally use preprocessor variables and all the nice tools and builtin functions preprocessors usually give.

That's why I won't stop using preprocessors any time soon.

Collapse
felipperegazio profile image
Felippe Regazio

in a perfect world, --header-height would exist on every css project out there ;P