2

The calc() function is not working as I expected it to in my code.

Instead of the height being calculated to 20% of the container's width, the height is collapsing.

html:

.box {
  width: 20%;
  height: calc(20%);
  margin: auto;
  background-color: olive;
}
<div class="box">
  
</div>

I've tried adding a calculation, like "height: calc(20% - 0px);" but the height is still just collapsing to zero.

Can anyone see if I am doing something wrong? Thanks!

Maiya
  • 932
  • 2
  • 10
  • 26
  • 1
    % in height is calculated based on the parent height – Temani Afif Feb 03 '18 at 19:09
  • Possible duplicate of [Maintain the aspect ratio of a div with CSS](https://stackoverflow.com/questions/1495407/maintain-the-aspect-ratio-of-a-div-with-css) – Temani Afif Feb 03 '18 at 19:09
  • @Temani Afif If % in height is based on the parent height, then why is the div's height still collapsing to zero? Thanks for pointing me to the other post, but I am not able to find the answer to my question there. I'm trying to figure out why calc() specifically is not working. – Maiya Feb 03 '18 at 19:28
  • simply because the parent height is not set thus % have no effect .. the parent in this case is the body, specify height to body and you will see ;) – Temani Afif Feb 03 '18 at 19:30
  • and calc has nothing to do here ... calc(20%) is exactly the same as 20% – Temani Afif Feb 03 '18 at 19:31
  • you may read about calc https://developer.mozilla.org/en-US/docs/Web/CSS/calc to understand that it has nothing to do with your logic whataver you will use with it. And then you need to understand how % value work with each property – Temani Afif Feb 03 '18 at 19:37
  • Hi @ Temani Afif. Can you please place your answers in the answers section, so that people can vote and comment on it? Thanks! – Maiya Feb 03 '18 at 19:37
  • am not answering :) am commenting to help you understand your issues ;) and am also convinced that your solution can be found on the link i shared ... you need the height to be linked with the width and this is aspect ratio – Temani Afif Feb 03 '18 at 19:39

3 Answers3

2

As i commented above % in height is relative to the height of the parent element and using calc() will not change the behavior as calc(20%) is the same as simply 20%.

This function will simply do some calculation to provide a result used by your property so the logic will always be the same with or without calc().

You need to set a height to parent container in order to your element having a height:

.container {
  height: 100px;
}

.box {
  width: 20%;
  height: calc(20%);
  /* same result with the below
  height: calc(20% / 1);
  height: calc(20% - 0px);
  */
  margin: auto;
  background-color: olive;
}

.box-1 {
  width: 20%;
  height: 20%;
  /* same result without calc*/
  margin: auto;
  background-color: red;
}

.box-2 {
  width: 20%;
  height: calc((50% + 20px) / 2);
  /* 50% from parent height = 50px
     50px + 20px = 70px
     70px / 2 = 35px*/
  margin: auto;
  background-color: yellow;
}
<div class="container">
  you will see this element because height is set to container
  <div class="box">
  </div>
  <div class="box-1">
  </div>
  <div class="box-2">
  </div>
</div>
you will not see these elements because no height set to parent container (the body)
<div class="box">
</div>
<div class="box-1">
</div>
<div class="box-2">
</div>

Now if you want to have relation between height/width of your element you may consider using variable BUT it won't work with % values:

:root {
  --size-box:200px;
}

.box {
  width: var(--size-box);
  height: calc(0.2 * var(--size-box));
  margin: auto;
  background-color: olive;
}
.big {
   --size-box:400px;
}
.per {
   --size-box:40%;
}
<div class="box">
</div>
<div class="box big">
</div>
we don't see the below one because of the same issue, using % in height and no height specified in parent element
<div class="box per">
</div>

And if you want to maintain aspect ratio of your element you may check this question: Maintain the aspect ratio of a div with CSS

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Okay, so it seems that you are saying that there is *no way* to capture the width of a div and pass that as a parameter to its own height. As in height: calc([thisDiv'sWidth]) – Maiya Feb 03 '18 at 20:11
  • @Maiya with pure CSS no :) but you can always find some workarounds to do this like i did with variable or like you will find in the link i shared – Temani Afif Feb 03 '18 at 20:12
2

just put

height:0; padding-top:100%; 

The padding is taking it's calculations from the width of the element.

Barry
  • 3,303
  • 7
  • 23
  • 42
1

Try using view-port width

The viewport is the visible part of the html page on your device.

The size of a page you can see is 100vw * 100vh, where vw and vh are the viewports size units.

.box {
      width: 20vw;
      height: calc(20vw * 0.02);
      margin: auto;
      background-color: blue;
     }
ben_fluleck
  • 44
  • 2
  • 8
  • hi @ben_fluleck. Thanks for the solution! But, I would like to apply this solution, even if the containing element is not the viewport. For example: If a containing div is 100px width. And I set .box{ width: calc(20%)} How can I get calc(20%) evaluate to be 20px in that case? – Maiya Feb 03 '18 at 19:33
  • This code would work, if I was depending on the viewport width, but I would like it to work based on any containing element's width. Thanks! .box { width: 20vw; height: calc(100vw * 0.2); margin: auto; background-color: blue; } – Maiya Feb 03 '18 at 19:54