5

While specifying a percentage value in css calc, how does calc know whether I am referring to width or height?

.container {
    width: calc(100% - 2vw); // 100% here is width or height ?
}

One may assume that it is either width or height depending on the property you are accessing, (width in this case). If that were the case, what happens if you would like to do some calculation based on a different property? For instance, set the width based on some calculation of height? Say, set the container width to be 1.5 times height?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
binish
  • 109
  • 1
  • 6
  • If you set an elements width using percent, it is its parents width the percent is based on. – Asons Apr 12 '19 at 19:52

2 Answers2

6

From the specification

The computed value of a calc() expression is the expression with all components computed.

Where percentages are not resolved at computed-value time, they are not resolved in calc() expressions, e.g. calc(100% - 100% + 1em) resolves to calc(1em + 0%), not to 1em. If there are special rules for computing percentages in a value (e.g. the height property), they apply whenever a calc() expression contains percentages.

There is no magic when using percentage inside calc() they will simply behave as if you aren't using calc().

So using width:100% is exactly the same as width:calc(100%) which is also the same as calc(50% + 50%). when you add another unit like width:calc(100% - 2em) it's like calculating width:100% then you remove 2em from it.

Basically, calc() is useful when combining percentage and non-percentage value in order to have accurate and precise result like removing 10px from 50% of the total width by using width:calc(50% - 10px).


what happens if you would like to do some calculation based on a different property? For instance, set the width based on some calculation of height?

You cannot do such thing with calc(). CSS in general doesn't allow such thing. You can either consider JS, some hacks to preserve ratio between width/height or use CSS variable and assign the same value for different properties.


Related question where the use of calc() combined with CSS variable is missused: Calc() outputting unexpected value

Community
  • 1
  • 1
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • @LGSon but it's valid to use one value (https://jsfiddle.net/os7952rx/) as one value is also an expression that is syntaxically valid inside calc() (https://drafts.csswg.org/css-values-3/#calc-syntax) – Temani Afif Apr 12 '19 at 20:16
  • @LGSon there is the use of `*` in the expression which means `An asterisk (*) indicates that the preceding type, word, or group occurs zero or more times.` https://drafts.csswg.org/css-values-3/#mult-zero-plus – Temani Afif Apr 12 '19 at 20:48
2

To answer the second part of the question:

For instance, set the width based on some calculation of height? Say, set the container width to be 1.5 times height?

You can do this with the aspect-ratio property:

.container {
  text-align: center;
  height: 200px;
  /* width / height ratio */
  aspect-ratio: 1 / 1.5;
  background: lightgray;
}
<div class="container">
  some content
</div>
Jacob
  • 1,577
  • 8
  • 24
  • but the aspect-ratio property is not supported in some of the old browsers and even newer versions of Safari. – Kishan Jan 11 '23 at 09:57
  • 1
    `aspect-ratio` has [almost 90% support](https://caniuse.com/mdn-css_properties_aspect-ratio), the old safari browsers have ~0.7% global usage (while newer versions have ~2.5%). If that’s not enough for you then don’t use it. – Jacob Jan 12 '23 at 20:35