What does 100% mean in CSS?

One of the CSS units I use most is the wonderful % — so handy for positioning elements on the page.

Unfortunately, the rules aren’t exactly straightforward. One question I’m always asking myself is:

Percent of what?

Hopefully this guide can help clear things up.Just give me the gist!#

The basics: width & height

In these examples, the purple box is our lovely self element — this is the element we’re trying to position using CSS properties. The surrounding blue box is the parent element.It’s important to note that the self element is absolutely positioned, to take it out of the normal flow and prevent moving things as we’re poking around.

Let’s start with our most basic, and most straightforward, example: width and height. Move the sliders around to get a feel for how the width and height of our self element changes with different percentage values.height50% (100px)width50% (300px)200px600px.self { position: absolute; height: 50%; width: 50%;}

We can see that our element’s width and height are based on our parent’s width and height (respectively).#

top & left

Great! Seems pretty straightforward — let’s move on to left and top:height50% (100px)width50% (300px)top0% (0px)left50% (300px)200px600px.self { position: absolute; height: 50%; width: 50%; top: 0%; left: 50%;}

These values are also based on our parent’s width and height. If an element has a left value of 50%, its left side will sit halfway across its parent component.#

margins

What about margins?height50% (100px)width50% (300px)margin top0% (0px)margin left50% (300px)200px600px.self { position: absolute; height: 50%; width: 50%; margin-top: 0%; margin-left: 50%;}

margins work similarly to our last example — they are based on the size of their parent. However, there is one weird thing here that is important to note:

margin-top is based on our parent’s width, not height (and the same goes for margin-bottom). In other words, all margins are a percent of their parent’s width.#

padding

And what about padding? Should be the same as margin, right?height50% (100px)width50% (300px)padding top0% (0px)padding left50% (300px)200px600px.self { position: absolute; height: 50%; width: 50%; padding-top: 0%; padding-left: 50%;}

And it is! For the most part.

Something interesting you might notice here is that padding-left (for example) won’t change the width of our self element, unless the padding-left value is greater than our self element’s width. This is because I use the border-box box-sizing model. Unfamiliar, or need a recap? Read more on MDN.#

transform: translate

Okay! Here is where things get a bit… weird.

Let’s take a look at transform: translate:height50% (100px)width50% (300px)translate top0% (0px)translate left50% (150px)200px600px.self { position: absolute; height: 50%; width: 50%; translate-top: 0%; translate-left: 50%; transform: translate(50%, 0%);}

The box moves a lot more slowly this time, right? That’s because transform: translate percentage values are based on our self element’s width and height.#

TLDR

Let’s recap what we’ve learned:heightparent’s heightwidthparent’s widthtopparent’s heightleftparent’s widthmargin-topparent’s widthmargin-leftparent’s widthpadding-topparent’s widthpadding-leftparent’s widthtranslate-topself’s heighttranslate-leftself’s width

Now let’s put what we’ve learned to the test!#

Centering elements

How could we center an element inside its parent, no matter its own dimensions?

Try centering our self element inside of the parent. Make sure it doesn’t move around when you tweak its width and height.height50% (100px)width50% (300px)top0% (0px)left50% (300px)translate top0% (0px)translate left50% (150px)200px600px.self { position: absolute; height: 50%; width: 50%; top: 0%; left: 50%; translate-top: 0%; translate-left: 50%; transform: translate(50%, 0%);}Show me!

See how this works? We’re moving our self element:

  • down by 50% of our parent’s height using top: 50%
  • right by 50% of our parent’s width using left: 50%
  • up by 50% of our self element’s height using transform: translate (top): -50%
  • left by 50% of our self element’s width using transform: translate (left): -50%