I have three div
with same heights equal to 1vh`.
My problem is they appear with different pixel size on screen. Sometimes they look equal but sometimes not, specially it happens after viewport resizing. Please run the snippet to see.
.samples {
display:flex;
}
.container{
display:flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
margin:10px 20px;
height: 20vh;
width:20vh;
}
.container div{
background: #000;
width:100%;
}
#set1 div{
height:.3vh;
}
#set2 div{
height:.7vh;
}
#set3 div{
height:.9vh;
}
#set4 div{
height:1.1vh;
}
<div class = "samples">
<div class="container" id="set1" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set2" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set3" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set4" >
<div></div>
<div></div>
<div></div>
</div>
</div>
<div>
<h4>Above are four samples, each sample includes 3 identical div.</h4>
<h4>But depends on your screen size you may not see what expected</h4>
</div>
I took some screenshot for demonstrating what really happening during resize, as you can see div
looks with different height despite all of them have 1vh
height.
If I calculate 1vh
manually in javascript and inject it as rounded 'px' to CSS then it works perfectly.(In snippet I have used .3, .7, .9, 1.1 vh for demonstration)
const set1Height = Math.round(document.documentElement.clientHeight * .3 / 100);
const set2Height = Math.round(document.documentElement.clientHeight * .7 / 100);
const set3Height = Math.round(document.documentElement.clientHeight * .9 / 100);
const set4Height = Math.round(document.documentElement.clientHeight * 1.1 / 100);
document.documentElement.style.setProperty("--set1-height", `${set1Height}px`);
document.documentElement.style.setProperty("--set2-height", `${set2Height}px`);
document.documentElement.style.setProperty("--set3-height", `${set3Height}px`);
document.documentElement.style.setProperty("--set4-height", `${set4Height}px`);
.samples {
display:flex;
}
.container{
display:flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
margin:10px 20px;
height: 20vh;
width:20vh;
}
.container div{
background: #000;
width:100%;
}
#set1 div{
height: var(--set1-height);
}
#set2 div{
height: var(--set2-height);
}
#set3 div{
height: var(--set3-height);
}
#set4 div{
height: var(--set4-height);
}
<div class = "samples">
<div class="container" id="set1" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set2" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set3" >
<div></div>
<div></div>
<div></div>
</div>
<div class="container" id="set4" >
<div></div>
<div></div>
<div></div>
</div>
</div>
<div>
<h4>Here, after calculating heights and round them to `px` they looks identical</h4>
</div>
My first thought was rounding floating point numbers cause this but if this is the case why CSS rounds a single float number to three different numbers?
My question is why this happening and is there any pure CSS solution to safely use viewport sizes and make sure they always appear as expected?