How Does CSS Scale Transform Affect Document Flow

How does css scale transform affect document flow?

CSS Transform does not affect document flow. The DOM element will occupy it's original position and dimensions within the page flow.

So if you have 3 square div's of identical size, displayed inline in a row and apply a -webkit-transform: scale(2) to the center square, this square will scale up to 200% larger, scale from the center of its original position, and overlap both other squares.

Reference example:

http://jsfiddle.net/ypnEk/

HTML:

<div class="square one"></div>
<div class="square two"></div>
<div class="square three"></div>

CSS:

.square{
margin-top:50px;
width:50px;
height:50px;
display:inline-block;
}

.one{
background:#222;
}

.two{
background:#888;
-webkit-transform: scale(2);
}

.three{
background:#ccc;
}

How to make a CSS transform affect the flow of other elements

For elements whose layout is governed by the CSS box model, the
transform property does not affect the flow of the content surrounding
the transformed element.

REF: Transform Rendering

You will have to use the max-height property (check this answer) to get the desired effect.

var button = document.querySelector("button");var box = document.createElement("div");
box.className = "box";box.appendChild(document.createTextNode("Click to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to delete"));
button.addEventListener("click", function(e) { var new_box = box.cloneNode(true); new_box.style.height = ( Math.random() * (200 - 30) + 30 ) + 'px';
new_box.addEventListener("click", function(e) { this.className = "box deleting"; window.setTimeout(function(e) { new_box.remove(); }, 1000); });
this.parentNode.appendChild(new_box);});
button {  font-size: 20pt;}.box {  overflow:hidden;  font-size: 12pt;  margin-bottom: 10px;  width: 600px;  max-height:1000px;  padding: 10px;  background: pink;  transform: scaleY(1);  transform-origin: top left;}.deleting {  transform: scaleY(0);  max-height:0;  padding:0 10px;  margin-bottom:0;  transition: padding 1000ms ease,max-height 1000ms ease, transform 500ms ease 500ms, margin-bottom 1000ms ease;}
<button>  Add Box</button>

Why does CSS transform influence Site width?

I was always under the impression, that CSS transforms are purely visual and don't influence the actual site layouting in any way

This is correct since transformation will not affect the position of any other element and the layout will remain the same.

What you are facing is related to overflow:

The scrollable overflow of a box is the set of things extending outside of that box’s padding edge for which a scrolling mechanism needs to be provided.

The scrollable overflow area is the non-rectangular region occupied by the scrollable overflow, and the scrollable overflow rectangle is the minimal rectangle whose axes are aligned to the box’s axes and that contains the scrollable overflow area.

.. the border boxes of all boxes for which it is the containing block and whose border boxes are positioned not wholly outside its block-start or inline-start padding edges, accounting for transforms by projecting each box onto the plane of the element that establishes its 3D rendering context. ref

So transform is a part of the Scrollable Overflow

You will find that some properties are part of the Ink Overflow and this one doesn't generate a scroll:

The ink overflow of a box is the part of that box and its contents that creates a visual effect outside of the box’s border box. Ink overflow is the overflow of painting effects defined to not affect layout or otherwise extend the scrollable overflow area, such as box shadows, border images, text decoration, overhanging glyphs (with negative side bearings, or with ascenders/descenders extending outside the em box), outlines, etc.

For example box-shadow will never create a scroll

.box {
width:100px;
height:100px;
background:red;
box-shadow:0 0 0 1000vmax blue;
}
<div class="box"></div>

Transform scale keeps the original space around the scaled element

A brutal way would be to virtually reduce space needed by element.

Your example shows a known width & height, so it makes it easy. else you would need a javascript method.

.box_1 {
width: 300px;
height: 300px;
transform: scale(0.5);
transform-origin: left top;
margin-bottom:-150px;
margin-right:-150px;
}

https://jsfiddle.net/0bc4sxk3/1/

Scaling up would mean positive margins.

Transform only happens at screen, elements still use initial room and place needed in the flow of the document.

Scale down big image doesn't update body size

Quick answer: the body (container) won't use the transformed size of the image. To prevent this container element size reflecting the original image size, either you define dimensions or restrict size without transforms, or you remove the element from the document flow with absolute positioning.

Transforms are a visual 'effect' applied to an element, and don't affect the underlying document layout. Basically the browser draws elements as they are before transforms, then applies the transform effect. This allows transformed elements to overlay other elements, push outside the window etc. without affecting other element layout.

More detail in this SO question.

Why do I continue to get a scroll bar when scaling down a large box?

transform leaves the original element untouched. It only affects how the element is rendered.

But the original element remains the same, hence occupying the same space in document flow. So the scrollbars will not go away unless you resize the element.

If you're looking for a solution to resize both the element and the space it occupies in document flow, have a look at this answer.

"use strict";var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var zoomFactor=function(){function e(t){_classCallCheck(this,e),this.el=this.q(t,document),this.b(),this.u()}return _createClass(e,[{key:"q",value:function(e){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.el).querySelector(e)}},{key:"b",value:function(){var e=this.el.innerHTML,t=document.createElement("z-1"),n=document.createElement("z-2"),i=document.createElement("z-3"),l=document.createElement("style");this.el.innerHTML="",this.el.appendChild(t),t.appendChild(n),n.appendChild(i),i.innerHTML=e,l.appendChild(document.createTextNode("z-1,z-2,z-3,zoom-factor{display:block}z-1,zoom-factor{position:relative;overflow:hidden}z-1,z-2{width:100%}z-1,z-2,z-3{color:#fff}z-1{float:left;overflow:hidden}z-2{position:absolute}z-3{transform-origin:left top;width:0}")),document.getElementsByTagName("head")[0].appendChild(l)}},{key:"v",value:function(){return this.q("input")?this.q("input").value:parseFloat(this.el.dataset.scale)||1}},{key:"u",value:function(){var e=this.v(),n=this.q("z-1"),i=this.q("z-2"),l=this.q("z-3");n.style=i.style=l.style="",i.style.width=n.clientWidth*e+"px",l.style.transform="scale("+e+")",n.style.height=l.clientHeight*e+"px"}}]),e}();new zoomFactor("zoom-factor");
.scaleme {  background: red;  height: 2000px;  width: 4000px;}
<zoom-factor data-scale="0.16666667">  <div class="scaleme"></div></zoom-factor>

Why float position Elements not move when the element scale down

A similar question was asked here and this quote from the accepted answer pretty much explains it:

CSS Transform does not affect document flow. The DOM element will
occupy its original position and dimensions within the page flow.

Answer by chrisgonzalez

So your DIV doesn't move because despite the scaling, the document still treats the element as being of its original size. To make the change affect flow you'll have to actually change its dimensions with width and height.

CSS Transform with element resizing

The problem I noticed is that when element scales, browser change its pixels ratio, not pixels amount. Element is smaller but it doesn't change its actual pixel size in DOM. Because of that I don't think that CSS-only solution exist.

I put scalable element into container which keeps the same pixel ratio as rest of elements. Using Java Script I simply change container's size. Everything is still based on CSS3 transform: scale. Maybe JS code could be simplier, but now it's all about the idea (just a proof of concept);) Fiddle with two examples: http://jsfiddle.net/qA5Tb/9/

HTML:

<div class="overall-scalable">
<div class="scalable" scalex='0.5' scaley='0.5'>
Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium. Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium.
</div>
</div>

CSS:

.overall-scalable {width: 350px; height: 150px; overflow: hidden; -webkit-transition: all 1s;}
.scalable {color: #666; width: 350px; height: 150px; -webkit-transform-origin: top left; -webkit-transition: all 1s;}

JS:

$('button').click(function() {
$('.scalable').each(function(){
rescale($(this));
})
});

function rescale(elem) {

var height = parseInt(elem.css('height'));
var width = parseInt(elem.css('width'));
var scalex = parseFloat(elem.attr('scalex'));
var scaley = parseFloat(elem.attr('scaley'));

if (!elem.hasClass('rescaled')){
var ratioX = scalex;
var ratioY = scaley;
}else{
var ratioX = 1;
var ratioY = 1;
}

elem.toggleClass('rescaled');
elem.css('-webkit-transform', 'scale('+ratioX +', '+ratioY+')');
elem.parent().css('width', parseInt(width*ratioX) + 'px');
elem.parent().css('height', parseInt(height*ratioY) + 'px');
}​

CSS Scale transform on child not affecting parent size

I missed a crucial part of CSS transforms: they do not affect Document flow, only the visual representation. Thus the original footprint of the element would remain. I was able to overcome by setting widths on the child and sibling, then manually shifting the sibling over to match the top corner of the child. More work would be needed for it to adjust to small screens.

.parent {  background-color: green;}
.parent .child-object { width: 10em; background-color: red;}
.sibling { color: white; width: 20em; background-color: blue;}
.SHRINK-ME { transform: scale(.80);}
.TRANSLATE-ME { transform: translate(-5%, 10%);}
<div class='row'>  <div class='parent SHRINK-ME'>    <div class='child-object '>CHILD</div>  </div>  <div class='sibling TRANSLATE-ME'>SIBLING</div></div>


Related Topics



Leave a reply



Submit