Kim K.
Kim K.

Reputation: 121

Calc() pixel height dynamically based on dynamic width and ratio with CSS

Been trying what seems to be an uphill battle.

I have an image, 768px x 411px. It must be fixed because it is part of a javascript scratch game. It can be resized though, but it must have fixed values.

My idea is the set the width to 100vw, then calculate the aspect ratio of the image and then base don that ratio, calculate the height from the current image width value.

I've been reading up a lot but no luck thusfar. Is this not possible with CSS alone? Here's part of my code:

        :root{
            --defaultWidth: 768px;
            --defaultHeight: 411px;
            --widthMain: calc(100% - 5px);                 
            --perspective: calc( var(--defaultHeight) / var(--defaultWidth) );
        }
        .scratchpad {
            width: var(--widthMain);
            height: calc( var(--widthMain) * var(--perspective) );
        /* also tried variations of this
            height: calc( calc(var(--widthMain) * var(--perspective)) ); */
        }
        .scratch-container {
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            width:100%;
        }

Thanks.

EDIT: Can't say I'm proud but I hacked myself into a temp solution by mixing it up with PHP

        <?php
    // Calling getimagesize() function 
    list($width, $height) = getimagesize("cover.png");
    $ratio   =  $height/$width;
    ?>

    <style type="text/css">
        :root{
            --defaultWidth: <?=$width?>px;
            --defaultHeight: <?=$height?>px;
            --widthMain: calc(100vw - 15px);                 
            --perspective: calc( var(--defaultHeight) / var(--defaultWidth) );
        }
        html {
            box-sizing: border-box;
        }
        *, *:before, *:after {
            box-sizing: inherit;
        }
        .scratchpad {
            width: var(--widthMain);
            height: calc((100vw - 15px) * <?= $ratio; ?> );
            border: solid 2px #fff;
            margin: 0 auto;
        }

Upvotes: 0

Views: 3883

Answers (1)

coreyward
coreyward

Reputation: 80140

You can do this by exploiting the fact that padding-top and padding-top reference the parent width when using relative units (e.g. 50% is half the width of the parent):

.container-a {
  width: 180px;
}

.container-b {
  width: 100px;
}

.image-wrapper {
  position: relative;

  /* Image aspect ratio as a percentage */
  padding-bottom: 50%;
}
 
img {
  position: absolute;
  width: 100%;
  height: 100%;
}
<div class="container-a">
  <div class="image-wrapper">
    <img src="//placehold.it/200x100" />
  </div>
</div>
<br />
<div class="container-b">
  <div class="image-wrapper">
    <img src="//placehold.it/200x100" />
  </div>
</div>

See how the image resizes, but it and the .image-wrapper element maintain the correct aspect ratio?

Upvotes: 1

Related Questions