Search code examples
csscss-gridcss-calc

Calc() outputting unexpected value


What I would like to do is make the #grid height 160% of the #grid width via calc(var(--grid-item-width) * 1.6), but it appears that --grid-item-width is being treated as a percentage of the viewport width instead of a pixel value.

The height of #grid is much larger than 160% of its width as can be seen in the screenshot below.

:root {
  --gap: 26px;
  --grid-item-width: calc(100% - calc(var(--gap) * 4));
}

#grid {
  width: 100%;
  height: var(--grid-item-width); /* does not match */
  overflow-x: auto;
  display: grid;
  grid-gap: var(--gap);
  grid-auto-flow: column;
  grid-auto-columns: var(--grid-item-width); /* does not match */
}

enter image description here

When I print the value of --grid-item-width to console, it returns calc(100% - calc( 26px * 4)), which obviously does not help.

One of the notes about calc() on MDN states:

Math expressions involving percentages for widths and heights on table columns, table column groups, table rows, table row groups, and table cells in both auto and fixed layout tables may be treated as if auto had been specified.

Is this why calc(var(--grid-item-width) * 1.6) has an unexpected output in this situation?


Solution

  • Both expression are the same BUT they will not resolve to the same value because they are applied to different porperties.

    So using calc(100% - calc(var(--gap) * 4)) with height means that we take 100% of the parent height (containing block) and we remove 4 gaps.

    Using calc(100% - calc(var(--gap) * 4)) with grid-auto-columns means that we take 100% of the element width and we remove 4 gaps. If your element is the only one on your code so it will be full screen width thus you will end using the width of the screen.

    The only way to have the same value is to be sure the height of the parent is the same as the width of the element OR avoid using percentage value and rely on different unit that will resolve the same way in both cases (px,vw,vh,em,etc)


    Note that the value used with height may fail to auto in case there is no height set on the parent element.