I've never read anything to suggest that the overflow property of an element would have the strange effect on element positioning that I'm seeing here:
https://codepen.io/kshetline/pen/ZEzLVxN
Toggle the toggle button in the example, and watch how somehow the background of a <div>
mysteriously slides upward, covering previous content, while its contents stays in the same screen-relative place (meaning the content is moving lower relative to its parent's background).
The example is a very simplified version of something I'm trying to do with an Angular component that's meant to scale its <ng-content>
— but the example is only CSS and HTML with a tiny touch of JavaScript, no Angular, since I'm trying to isolate the relevant variables.
The content of an HTML element can be scaled down using transform: scale(
less-than-1 scaling factor )
, but even though the content of the element is rendered smaller, by default the element's pixel dimensions remain the same, with the content (unless otherwise specified) shrinking toward the center of the element, and blank space left around that content that leaves the element at its original unscaled dimensions..
You need to compute negative margins that match the degree of scaling in order for the element itself to be considered smaller. I've done that, but I've found that unless the container for the scaled element has CSS overflow
set to hidden
, some weird positioning can occur, as if the extra blank space required that's supposed to be removed by the negative margins is still having some partial, hard-to-explain effect on the overall layout of other elements.
I'm seeing this behavior in Chrome, Firefox, Safari and Edge -- so I'm guessing it's "proper" CSS behavior, but it makes no sense to me, and I'm hoping someone can explain what's going on. I'd like to be able to keep overflow
set to visible
so that scaled content can still do things like show floating dropdown menus that don't get clipped at the boundaries of the element.
let hidden = true;
const inner = document.getElementById('inner')
function toggleOverflow() {
hidden = !hidden;
inner.style.overflow = hidden ? 'hidden' :
'visible'
}
html, body {
height: calc(100vh - 10em);
}
.page {
font: 32px Arial, Helvetica, sans-serif;
height: calc(100% - 1em);
}
.container {
background-color: #ACF;
height: 100%;
}
.outer-wrapper {
background-color: rgba(187, 255, 204, 0.5);
font-size: 2em;
margin: 0 1em;
position: relative;
}
.inner-wrapper {
overflow: hidden;
position: relative;
width: fit-content;
}
.ng-content {
margin: -18.75px 0;
transform: scale(0.5);
}
.container-text {
display: inline-block;
position: absolute;
bottom: 1em;
}
<div class="page">
<button onclick="toggleOverflow()">Toggle Overflow</button><br>
Content outside of the<br>
panel being scaled and its<br>
containing <div>, 32pt font<br>
<div class="container">
<!--Angular component start tag goes here -->
<div class="outer-wrapper">
<div id="inner" class="inner-wrapper">
<div class="ng-content">
50% scaled content goes here, 64pt font
</div>
</div>
</div>
<!-- Angular component end tag goes here -->
<span class="container-text">This is an absolutely positioned <span> in the same <div></span>
</div>
</div>