3

I have a div that is centered on the page and scales with viewport in a way that its aspect ratio (16:9) is maintained. The problem is, I want the font and content inside to scale with the div as it resizes, as well. Vmin works, for the most part, without issue. It would work perfectly if the aspect ratio of the div is 1:1 because vmin checks for the lesser value between height and width of the viewport directly, and you can't set a custom aspect ratio.

<!DOCTYPE html>
<html>
<head>
<style>
body {
  background-color:white;
}
.wrapper {
  width: 95vw;
  height: calc(95vw * 9/16);
  max-height: 95vh;
  max-width: calc(95vh * 16/9);
  background: center;
  background-color: blue;
  background-size:contain;
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
#lorem {
  color: aqua;
  font-size:10vmin;
  text-align:center;
  position:absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  margin:auto;
}
</style>
</head>
<body>
<div class="wrapper">
  <p id="lorem">
    This text should scale with div only.
  </p>
</div>
</body>
</html>

https://jsfiddle.net/Addictorator/70fq44sv/2/

Resize the window vertically to see what I'm talking about.

I don't believe there is a way in pure css (but if there is, that would be most preferred), but I think it is possible in javascript using an event listener onresize of the div and scaling each element down separately by a ratio comparing original (or previous - storing it as a var) div height/width to current div height/width. Or it could try and replicate vmin behavior but with height set to a ratio in a way 16:9 is considered instead of 1:1, like what was done on div using css above. I would prefer pure js and no jquery if at all possible. I've tried doing this myself, but I'm rather amateurish when it comes to javascript.

Thanks in advance!

Terrornado
  • 793
  • 3
  • 9
  • 21
  • This is a [duplicate](http://stackoverflow.com/questions/16056591/font-scaling-based-on-width-of-container#19814948). Your looking for viewport fonts, an all CSS solution. `9vw` for fontsize may be good for you. – kabanus Jan 01 '17 at 12:45
  • No, no it isn't. I'm already using viewport units, and if you read it, you can see why it is bugging out in my particular case. – Terrornado Jan 01 '17 at 12:48
  • It works on your js fiddle for me. I changed `font-size: 10vmin` to `font-size:9vw;`. Note this is in the font size. – kabanus Jan 01 '17 at 12:48
  • Sorry, still works for me. Note you need to base the font-size on viewport units. Text remains the same 'percentage' of the rectangle. Which browser are you using? Maybe that's the issue. On firefox looks fine. – kabanus Jan 01 '17 at 12:52
  • Have you even tried resizing the window lower with that? Vmin is used because at least that works reliably in most cases. With vw, resizing the window down means that font size remains the same despite changes in viewport height constraining the div size. Try resizing the window to make it smaller vertically. – Terrornado Jan 01 '17 at 12:53
  • And I'm using the latest version of Chrome. – Terrornado Jan 01 '17 at 12:54
  • 1
    No, the question is not based on vw or vh units although the results are similiar. Currently, you are asking purely based on the container div's width. Should the div resize it's height according to the browser? – Matthew Brent Jan 01 '17 at 12:57
  • is there are a reason you are using vw for the container size and not %? – Matthew Brent Jan 01 '17 at 13:07
  • No, the div works perfectly as I want it to. The width/height ratio is 16:9. The problem is the content, such as text. Using vmin means that font will decrease, scaling with whichever is the lesser value of viewport width or height. But the div is 16:9 aspect ratio size, not 1:1, which makes vmin unreliable sometimes when say the window is scaled up from 16:9 into a square. Div size remains same, but viewport height increases and is less than viewport width so font will scale. Using vw/vh is even more unreliable. – Terrornado Jan 01 '17 at 13:09
  • I'm calculating max-width in terms of vh, or viewport height. This kind of scaling while retaining aspect ratio is not possible with %, which relates max-width directly to viewport width and vice-versa – Terrornado Jan 01 '17 at 13:33

1 Answers1

1

Please see a working codepen here.

The solution is quite simple. On window resize we return the clientHeight of the parent. by dividing the returned value we achieve an integer that is usable as a font-size. We then assign this to the p element.

I hope this solves your problem.

//assigns font-size when document is ready
document.onreadystatechange = () => {
  if (document.readyState === 'complete') {
    var wrapperHeight = document.getElementById('wrapper').clientHeight;
    var relativeFontSize = wrapperHeight / 10 + 'px'; //change 10 to any  integer for desired font size
    document.getElementById("lorem").style.fontSize = relativeFontSize;
  }
};
//then on window resize
window.onresize = function(event) {
  var wrapperHeight = document.getElementById('wrapper').clientHeight;
  var relativeFontSize = wrapperHeight / 10 + 'px'; //change 10 to any integer for desired font size
  document.getElementById("lorem").style.fontSize = relativeFontSize;
};
body {
  background-color:white;
}
#wrapper {
  width: 95vw;
  height: calc(95vw * 9/16);
  max-height: 95vh;
  max-width: calc(95vh * 16/9);
  background: center;
  background-color: blue;
  background-size:contain;
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  font-size:60px;
}
#lorem {
  color: aqua;
  text-align:center;
  position:absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  margin:auto;
  
}
<div id="wrapper">
  <p id="lorem">
    This text should scale with div only.
  </p>
</div>
Matthew Brent
  • 1,366
  • 11
  • 23
  • Yes, it works perfectly, thanks! This is exactly what I was looking for! Would it still work if I set a font-size in css (vmin) as a fallback for any browser that may have javascript disabled? – Terrornado Jan 01 '17 at 15:05
  • 1
    yes that should work. As far as i'm aware document.readyState === complete waits for all sub-resources which should include your css files. Therefore the function should always be applied after the css loads. – Matthew Brent Jan 01 '17 at 15:14
  • For future users needing a similar solution, you should change your question title to "How can I scale font-size relative to it's parent's height using Javascript?" or something along those lines. I think that's why some people were confused with what you were asking. Try to be as clear as possible. You'll get the best answer that way. – Matthew Brent Jan 01 '17 at 15:17