0

For my webapp I'm attempting to create a div which maintains the same size regardless of zoom level. That is, if I measure the div with a real-world ruler and it is 3 inches wide, then regardless of how far I zoom in or out, it will always be 3 inches wide.

I've noticed that if I define the font-size of the root html document, then I can use the relativistic rem for that div and all of its child elements.

The closest I've gotten so far is setting font-size: 1vh; on the html element. Then, whenever I use rem units, the div and its contents stay the same size regardless of zoom level, which is perfect.

The only issue with this solution is that it scales with viewport height. That is, if you make your window shorter, the element will decrease in height. Similarly, if you make the window taller then the element will increase in height.

This is bad, because for all my users regardless of their monitor size I want this item to be the same size. That is, it should be 3 inches wide for everyone regardless of their viewport width, height, monitor size, or whatever.

The only thing I could think of to solve this is to somehow detect browser zoom levels and then use Javascript to modify the html element's font-size property, but that approach seems extremely finicky and not very cross-browser in how well it works.

Ryan Peschel
  • 11,087
  • 19
  • 74
  • 136
  • Hey, have you tried using the css to describe your div? – khushi Nov 27 '20 at 23:36
  • I don't understand your comment. I am doing such. – Ryan Peschel Nov 27 '20 at 23:39
  • I think you are confused. – Ryan Peschel Nov 27 '20 at 23:44
  • buddy, simple words, please try changing 'vh' to 'px' – khushi Nov 27 '20 at 23:48
  • Pixels scales with zoom level so that doesn't work – Ryan Peschel Nov 27 '20 at 23:53
  • Sorry about that, I can say your issue is with the vh because vh works with viewport (which technically also coincides with screensize). I found this page: https://stackoverflow.com/questions/13117175/keeping-all-my-divs-fixed-regardless-of-browser-window-size which has a similar question to yours and I saw some stuff that might be of use, hoping it helps! Good luck! – khushi Nov 28 '20 at 00:01
  • Unfortunately none of those answers in the linked question solve this problem. – Ryan Peschel Nov 28 '20 at 00:21
  • You have also : https://developer.mozilla.org/en-US/docs/Web/CSS/clamp() in CSS . you can set a min and max font-size and in between a vh/vw/vmin or vmax font-size to let resize in between those two min/max value. It won't be pixel perfect, but will allow the text to be readable at lower screen and avoid it to be so big at bigger screens. Have you try this to set a compromise ? – G-Cyrillus Nov 28 '20 at 10:14

2 Answers2

0

I figured this out and it seems to work. Likely going to use this unless someone comes up with a better solution:

function scaleFontSize() {
  let scaledFontSize = (16 / window.devicePixelRatio) + "px";
  
  document.documentElement.style["font-size"] = scaledFontSize;
}

scaleFontSize();

window.addEventListener('resize', scaleFontSize, true);
Ryan Peschel
  • 11,087
  • 19
  • 74
  • 136
  • i thought `max-width` could solve the issue but i am wrong. at the moment i cant think of any other solution. – Zia Ahmad Nov 28 '20 at 01:01
0

would clamp() be helping you here ? on its own or mixed with your window.devicePixelRatio ?

while awaiting for a feed back in the comment section, i set here a couple of example

html {
font-size:clamp(10px, 8vw, 0.35in); 
}
body {
width:20rem;
margin:auto;
text-align:justify;
}
<h1>HTML Ipsum Presents</h1>

<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>  Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis
  tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>

<h2>Header Level 2</h2>

<ol>
  <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
  <li>Aliquam tincidunt mauris eu risus.</li>
</ol>

<blockquote>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
    elit sit amet quam. Vivamus pretium ornare est.</p>
</blockquote>

<h3>Header Level 3</h3>

<ul>
  <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
  <li>Aliquam tincidunt mauris eu risus.</li>
</ul>

<pre><code>
#header h1 a {
  display: block;
  width: 300px;
  height: 80px;
}
</code></pre>
  • js

function scaleFontSize() {
  let scaledFontSize = (8 / window.devicePixelRatio) + "vw";
  let doc = document.querySelector('html');
 
  doc.style.setProperty('--Device',  scaledFontSize);
}

window.onload=scaleFontSize;
 
// window.addEventListener('resize', scaleFontSize, true); No need , pixel ratio remains the same .
html {
font-size:clamp(10px, var(--Device, 10vw), 0.35in); 
}
body {
width:20rem;
margin:auto;
text-align:justify;
}
<h1>HTML Ipsum Presents</h1>

<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>  Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis
  tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>

<h2>Header Level 2</h2>

<ol>
  <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
  <li>Aliquam tincidunt mauris eu risus.</li>
</ol>

<blockquote>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
    elit sit amet quam. Vivamus pretium ornare est.</p>
</blockquote>

<h3>Header Level 3</h3>

<ul>
  <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
  <li>Aliquam tincidunt mauris eu risus.</li>
</ul>

<pre><code>
#header h1 a {
  display: block;
  width: 300px;
  height: 80px;
}
</code></pre>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • I don't really understand this answer. I tried your code snippets and zooming in and out on the page in Chrome changes their perceived size. What I'm looking for is to have zoom not affect the physical size of elements. – Ryan Peschel Nov 28 '20 at 13:08