Home > front end >  Store height of element in css variable
Store height of element in css variable

Time:07-03

I'm trying to maximize the size of an element (embedded video player iframe) within particular constraints:

  1. it should not be taller than 2/3 the height of its parent.
  2. it should not be wider than its parent.
  3. it should maintain its 16:9 aspect ratio

I'm currently achieving this with Javascript (0.5625 and 1.778 are decimal representations of the 16:9 aspect ratio):


function updateDimensions () {
    const video = document.querySelector('#video-player')
    const parentRect = document.querySelector("#parent").getBoundingClientRect()

    const maxHeight = parentRect.height * 0.667
    const maxWidth = Math.min(maxHeight * 1.778, parentRect.width) 

    video.setAttribute('width', maxWidth   'px')
    video.setAttribute('height', maxWidth * 0.5625   'px')
  }

This code is run once on mount, and (debounced) on every resize.

It really seems like this should be CSS' job though, it would probably be more efficient as CSS, and feels like something that should be achievable with calc(), min(), custom properties (variables) and aspect-ratio in CSS, but I just can't work out how.

This is how far I got:

#video-player {
  --parent-height: ???
  /* 1. should not be higher than 2/3 of its parent */
  --max-video-height: calc(var(--parent-height) * 0.667)
  /* 2. should not be wider than its parent */
  --video-width: min(calc(var(--max-video-height) * 1.778), 100%)

  width: var(--video-width)   
  /* 3. should maintain its 16:9 aspect ratio */
  /* height can be calculated with either: */
  height: calc(var(--video-width) * 0.5625)
  /* or: */
  aspect-ratio: 16 / 9 
}

The way that I've written it, it all hinges on getting the parent height into a variable.

Is there a way to do so? Or is there another way to write this in CSS to achieve what the Javascript code does?

NOTE: I had previously been using a wrapper div and the #video-container { padding-top: 56.25% } hack to maintain the video's aspect ratio, but having the container set to position: relative seemed to conflict with my attempts to align it with align-self: center; justify-self: center; (it's a grid item). I guess I could wrap the wrapper in another wrapper and put that in the grid, but the Javascript code does exactly what I want to the element in question, without the need for extra divs.

CodePudding user response:

Depending on how your video is being added (<iframe> or <video>), this should be all you need:

#video-player { height: 100%; max-height: 66.6667%; aspect-ratio: 16/9; }

Working sample on codepen

Also worth being aware of how well supported aspect-ratio is. You can see that here on the caniuse website.

  • Related