1

Why calc function doesn't work in height with position relative, but work in witdh?

It works:

#div1 {
    position: absolute;
    left: 50px;
    height: calc(100% - 100px);
    border: 1px solid black;
    background-color: yellow;
    padding: 5px;
    text-align: center;
}

It doesn't:

#div1 {
    position: relative;
    left: 50px;
    height: calc(100% - 100px);
    border: 1px solid black;
    background-color: yellow;
    padding: 5px;
    text-align: center;
}

But it works too:

#div1 {
    position: relative;
    left: 50px;
    width: calc(100% - 100px);
    border: 1px solid black;
    background-color: yellow;
    padding: 5px;
    text-align: center;
}

P.S.: Tested on https://www.w3schools.com/cssref/tryit.asp?filename=trycss_func_calc

Jimmy Porto
  • 109
  • 1
  • 15
  • can you show your html too please - see [mcve]. Also your last two styles - one that you say doesn't work then the one immediately following that does - they look exactly the same – Pete Oct 30 '18 at 12:06
  • 1
    @Pete the second uses height and the third uses width. – Mr Lister Oct 30 '18 at 12:10
  • 1
    Ah could have done with OP pointing that out rather than this works, this doesn't and then expecting us to spot the difference. Anyway as there isn't an [mcve] I am voting to close as off topic, but I'm guessing this is a precentage height issue then – Pete Oct 30 '18 at 12:12
  • 1
    Percentage values are evaluated based on the element's bounding box. That bounding box changes with `position: absolute`. Are you looking for `100vh` instead of `100%`? – str Oct 30 '18 at 12:13
  • @str It works corretly! Thanks. – Jimmy Porto Oct 30 '18 at 12:18
  • @Pete The OP actually does say "doesn't work in height (..) but works in width" in the opening sentence, and the examples were just clarifications of that. – Mr Lister Oct 30 '18 at 12:21
  • @Pete The tryit editor they link to is self contained. Yes, it's not a snippet here in the question, but it's enough in my eyes. I don't close questions that have proper jsfiddles or codepens either. You're right about the duplicate though; didn't think to check. – Mr Lister Oct 30 '18 at 12:27
  • @MrLister the code must be in the question itself: Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it **in the question itself**. – Pete Oct 30 '18 at 12:28

1 Answers1

3

Absolutely positioned elements are positioned with regards to the nearest positioned ancestor, or if there is none, to the document itself. The document is as high as the viewport, so the height property works.

Relatively positioned element however are part of the document flow and take their height from their immediate parent, in this case, the body. Since the body is not sized, the element doesn't know which height to choose, so it ignores the property.

With width, there is no such distinction, since the body also is the entire width of the viewport, like the document.

Solution (thanks to @str): use 100vh instead of 100% to do height calculations with.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • Thanks for the explanation! – Jimmy Porto Oct 30 '18 at 12:21
  • I Don't agree with the explanation ... percentage height will always work with position:absolute whatever the ancestor is so it has nothing to do with the fact that it's the viewport. Here is the precise explanation `Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.` – Temani Afif Oct 30 '18 at 13:53
  • and for width we have this `Specifies a percentage width. The percentage is calculated with respect to the width of the generated box's containing block. If the containing block's width depends on this element's width, then the resulting layout is undefined in CSS 2.1. Note: For absolutely positioned elements whose containing block is based on a block container element, the percentage is calculated with respect to the width of the padding box of that element.` https://www.w3.org/TR/CSS2/visudet.html – Temani Afif Oct 30 '18 at 13:54
  • @TemaniAfif True, but my explanation still stands. If in the tryit editor you set the absolutely positioned #div1's height to 100%, it will be as high as the viewport. But if you then give the body a positioning (by adding `body {position:relative;}`) then the height of #div1 will drop to zero! Because then, the problem will be that body doesn't have a height yet. If body isn't positioned, that problem isn't there. – Mr Lister Oct 30 '18 at 14:26
  • In other words, what the div's containing block is, depends on the positioning of the body (if the div is positioned absolutely). If the div is not positioned absolutely, the containing block is always the body. But if you think you can explain the results better, you should post an answer of your own. – Mr Lister Oct 30 '18 at 14:29