Overflow behavior after using CSS3 transform - html

Please check the demo
I have two divs the first div is used for showing the scroll-bar and the second div is used for the rotation of inner contents of the div.
My question is why scroll-bar is showing even if there is no overflow of the inner contents.
Please check the demo and tell me what I am doing wrong here and how to overcome this issue or any alternative way to achieve this.
HTML
<div style="width: 1096px; height: 434px; overflow: auto; position: relative; border:solid 5px #555555">
<div id="RotationDiv">
<img style="left: 54px; top: 337px; width: 326px; height: 422px; position: absolute;" src="http://fc01.deviantart.net/fs70/f/2012/304/6/b/walfas_custom___vending_machine_2_by_grayfox5000-d5jljhe.png" />
</div>
</div>
CSS
#RotationDiv {
-ms-transform-origin: 539px 539px;
-webkit-transform-origin: 539px 539px;
width: 434px;
height: 1096px;
overflow: visible;
-ms-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
background-color:Red;
}

You are using transform so it changes visual formatting model of an element.
From MDN:
The CSS transform property lets you modify the coordinate space of the
CSS visual formatting model. Using it, elements can be translated,
rotated, scaled, and skewed according to the values set.
A line again from MDN:
By modifying the coordinate space, CSS transforms change the position
and shape of the affected content without disrupting the normal
document flow. This guide provides an introduction to using
transforms.
From W3C : 2 Module Interactions
This module defines a set of CSS properties that affect the visual
rendering of elements to which those properties are applied; these
effects are applied after elements have been sized and positioned
according to the Visual formatting model from [CSS21]. Some
values of these properties result in the creation of a containing
block, and/or the creation of a stacking context.
So you have a parent element with the dimensions below.
width: 1096px;
height: 434px;
Now you are transforming that element using
-webkit-transform: rotate(90deg);
So here, the element transforms visually, but not literally, in other words though you transform an element, it takes the space physically on a document just like a static element takes, it just visually transforms the element. I will share a diagram which will make you understand in a better way..
So though you transformed your element like this, but still the vertical space was taken up because of the height of your transformed element, which did transformed visually, but not literally...
So, now what's the solution? Use position: absolute; on the child element, and anyways you are using position: relative; on the parent.
Demo
#RotationDiv {
-ms-transform-origin: 539px 539px;
-webkit-transform-origin: 539px 539px;
width: 434px;
height: 1096px;
position: absolute;
overflow: visible;
-ms-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
background-color:Red;
}
Lets have a test case, I've the styles like below
.parent .transformed {
height: 200px;
width: 200px;
background: #f00;
-moz-transform: rotate(120deg);
-webkit-transform: rotate(120deg);
transform: rotate(120deg);
-moz-transform-origin: 300px 300px;
-webkit-transform-origin: 300px 300px;
transform-origin: 300px 300px;
}
.parent .static {
background: #00f;
height: 200px;
width: 200px;
}
Test Case
Here, I am transforming an element having class of .transformed so if you see, the element does transform and am also modifying the origin, but the next box won't move up, as the transformed element take up literal space in the flow, it doesn't get out of the flow like position: absolute; does, but well that's the separate concept.
So you need to use position: absolute; or your div will still take up space vertically and thus you see that scroll bar ...
Poopy IE Compatible Solution
As you commented, well, yes, IE will still show the scroll bar as the element which is positioned absolute still exists in the same dimensions, so what's the workout here?
Firstly, you are transforming the element to set in the parent container, also, you don't need the overflow so the first question is if you don't need overflow than why use auto? You can use hidden.
If not hidden to the parent, and you are looking forward to place some content beneath the transformed element, than better you wrap the transformed element inside another element with the same dimensions set to overflow: hidden; and make sure you move the position: absolute; property to this block. - Demo
If still not happy? Then why transform entire element? transform relevant image only - Demo

This is because it is still using the vertical properties (Just as hmore009 said in the comments).
If we take a look here you can see what its doing so you know this is true.
Example 1:
So your height and width for the container are as follows:
width: 1096px;
height: 434px;
Now you have done the right thing and swap them for the transform #RotationDiv:
width: 434px;
height: 1096px;
This works fine if we were to change the container to overflow: hidden; this means we cant see any extra height.
DEMO HERE
Example 2:
But I guess for some reason you don't want to do that, probably due to not knowing why the overflow is caused. So lets take a closer look at what is going on.
If we remove the height from #RotationDiv the overflow is no longer there. Thats a bit wired isn't it? Well no, the height was was being used for both the transform and the vertical height.
DEMO HERE
So how can we know it was the height causing this?
Now if we give #RotationDiv the same height as the container we can see there is no overflow.
DEMO HERE
Now if we add 1px onto that height we get the overflow kicking in. Hmm, so the height must be causing this. Even tho we are transforming the height seems to still be being used for the vertical height in the container.
DEMO HERE
How can we fix this?
Well we already have seen one option, give the container overflow: hidden; or just removing it altogether. This will stop the scrolling within the container.
DEMO HERE
Or you could just get an image editor (there are some free online ones) and flip the image like that. Would save a lot of trouble doing it this way.
Other then that you could flip the image only remove #RotationDiv and give the container background: red;
DEMO HERE
How I would do it still using transform:
I would take off the overflow: auto;, remove the unneeded div and set the transform on the img.
It's up to you how you want to do it, there are many ways. The best way I would say it don't use transform and just flip the image using an image editor (e.g. Photoshop).
DEMO HERE

Related

CSS3 - How to override the padding of a parent element?

I have a div element in the shape of a circle using this code:
#circle{
width: 320px;
height: 320px;
background-image: url('image.jpg');
border-radius: 50%;
background-position: 50% 50%;
transition: all 1s;
}
That expands on hovering using this code:
#circle:hover{
margin-top:-50px;
width: 400px;
height: 400px;
}
Now this div element is inside another div element in the shape of a rectangle, or a box as some might say, that has a padding of 50px.
When the circle expands, the top part of the circle gets hidden under the padding. Imagine it like, the top part of the circle gets cut off, while the 50px padding is there.
What I want is, it will override the padding. it'll simply show above the padding, I hope you get what I'm trying to say here... If not, i'll try to explain in a better way. Thanks in advance!
Unfortunately there is no css that can access the parent element of an item.
I found this thread which outlines how you might accomplish this task.
You can use "position" or "display". I hope this http://css-tricks.com/absolute-positioning-inside-relative-positioning/ may help you
How you tried with z-index?
The round element
z-index: 2;
and the parent element:
z-index: 1;

How to fit and center an unknown sized image in a div element with a relative size using only pure CSS

I am working on a CSS animated HTML block. I created a fully responsible grid, so these blocks have relative sizes. The block contains a big image to ensure to display the content on all screens correctly. The images in the blocks have 100% width to fit the content, and they also have CSS transitions and transforms.
I would like to center these images vertically, but using only pure CSS. I tried a lot of variations of display, position and vertical-align properties, but no one worked for me. I could easily achieve the proper animation with the background property, but I don't want to create a lot of css classes for all the images (not even with js or jquery).
So could you tell me how to solve this issue with pure CSS? I also created a jsfiddle to demonstrate the problem.
EDIT: I also would like to keep the ratio of the images inside the blocks.
I've created a codepen example of position centrally horizontally and vertically and if you resize it stays in the centre.
http://codepen.io/tom-maton/pen/oqsEJ
In the example I have
margin: auto;
position: absolute;
left:0;
right: 0;
top: 0;
bottom: 0;
This makes it h &v positioned centre if you just do
margin: auto 0;
position: absolute;
top: 0;
bottom: 0;
This will position just vertically
Hope this helps
I had a look around and found this link for you:
CSS Tricks - Absolute Center (Vertical & Horizontal) and Image
I hope this can be of some help to you
I have done it on your fiddle too:
Your Fiddle Link
I simply added margin-top: -100px;
EDIT
Sorry didn't realised it wasn't for a fixed size see this updated version:
Fiddle Updated
I used the following code:
position: absolute;
top: 50%;
left: 50%;
height: 100%;
width: 50%;
margin: -25% 0 0 -25%;
I found it here:
6 Methods For Vertical Centering With CSS
You need to define the height: 100%; as well.
demo
if you define the images with css then it could be as ratio as you wish by setting background-size: cover; but to the image it's not possible.
You can't do what you want both retaining the image ratio and your container DIV smaller than image size, you can even set the height:100% to fit image inside the DIV or set DIV to a bigger size (or use smaller image to fit in the DIV) and use line-height:100%
Here are demo for first solution:
Demo changing the ratio
And demo for second solution:
Demo not changing the ratio
(I also set the text-align:center to make sure it is centered even when you don't use width:100%)
Hope it helps you.
The most dynamic solution (in my opinion) is using translateY.
This will move the element from its current position:
see: CSS3 2D transforms
img {
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}

Aligning 270 degree oriented div (transform: rotate)

I have a div (tab) that I rotate 270 degrees like so:
-webkit-transform-origin: 100% 0%;
-webkit-transform: rotate(270deg);
(Example here: http://users.telenet.be/prullen/align.html)
When I want to align the tab with the top edge of the content box, it's pretty easy. i just set "top" to "3px" (the border size). However, for the bottom it's another story.
It appears I need to calculate this with jquery like so:
$tab.css('bottom', (Math.abs($tab.outerWidth()-$tab.outerHeight())
(Though for this example I'm just using a static value. It may not look exactly like I want it to in your browser, here's an image: )
I was wondering if there is a better way since this does not seem to work all that well in firefox for example (1 pixel shift). Is there an easier way by adjusting the transform-origin perhaps?
(Note that I need to keep the same div structure I have now)
Ideally it'd be as easy as setting bottom to: 3px (the border thickness)
Thanks.
When you want to put the tab at the top of the sticky, apply the class .tab-top to the .sticky-tab element.
.tab-top {
transform-origin: 100% 0%;
transform: rotate(270deg);
top: 5px; /*Border Size*/
right: 5px; /*Border Size*/
}
When you want to put the tab at the bottom of the sticky, apply the class .tab-bottom to the .sticky-tab element.
.tab-bottom {
transform-origin: 100% 100%;
transform: rotate(270deg) translateX(100%);
bottom: 0;
right: -18px; /*Height (appearing as width once rotated) of the tab*/
}
Essentially you want to change the transform origin to be at the bottom right-hand corner of the element and then attach the element to the bottom of its parent. This will place the element exactly below the .sticky. Then use the translateX(100%) to force the bottom of the .sticky-tab to align with the bottom of the .sticky.

left:50% element not appearing in middle of page

I have an absolute positioned popup (hover over "ice white" image to see popup) which has css left:50%. Now this should appear in the middle of page but doesn't. Any suggestions please? Thanks in advance.
You're also supposed to add margin-left with the negative of a half of visible width of the element. So, for example:
width: 400px;
padding: 10px;
border-width: 2px;
/* -(400 + 10 + 2)/2 = -206 */
margin-left: -206px;
left: 50%;
Note that margin: auto suggested by others won't work because you've positioned the element absolutely.
position: absolute;
left: 50%;
transform: translate(-50%,0)
Lol, no. The left side of the image appears at 50% of the page width. Hence; left: 50%.
In order to center your image, set margin: auto instead.
Your code is working correctly. The popup is being positioned with left of 50% ... of the TD tag it's nested inside.
Try either taking the popup out of the table, or setting it to 50% of the document width instead. (Your javascript is minified and unreadable to me, or I'd help further.)
u can try to change CSS Style like this
#displayDiv {
background-color: white;
font-weight: bold;
height: 460px;
left: 50%;
margin: auto auto auto -475px;/* change done here */
overflow: hidden;
position: absolute;
text-align: center;
top: 80px;
width: 950px;
z-index: 1;
}
Looks to me like there's a containing element somewhere in between the "Ice White" image and the body (specifically, Firebug reveals that it's the <a class="popup1" ... >) that is relatively positioned, so your 50% is relative to that rather than the whole page.
I know this seems a bit counterintuitive: Why should it be relative to a parent element if the poput uses absolute positioning? It's basically because relative positioning is relative to where the element is in the normal flow of the document, whereas absolute positioning yanks the element out of that flow. See sections 9.4.3 and 9.6 of the W3C's explanation of the visual formatting model for more info.
Check out a tutorial or two if this is giving you trouble. I like Learn CSS Positioning in Ten Steps and css-tricks.com's "Absolute Positioning Inside Relative Positioning" (to which I'd provide a link if not for the spam filter; first-time answerer here ;) ).
As for what to do about it, you might be able to move the popups out of the relatively positioned parent, as mblaze75 suggests, but it looks (and I'm guessing here) like that <a> is what's triggering your JavaScript event, so you probably can't do that. Instead, I'd try removing the relative positioning and using margins instead.
Also, bear in mind what Greg Agnew said: Even with that problem solved, you're still centering the left edge rather than the center of your popup. I think duri's answer will take care of that.

overflow:auto does not work with CSS3 transformed child elements. Suggested workaround?

Problem: css3 transforms applied to a child element inside a div are ignored by the browser (FF5, Chrome12, IE9) when calculating the scrollHeight and scrollWidth of the containing div's scrollbars when using "overflow: auto;".
<style type="text/css">
div{ width: 300px;height:500px;overflow:auto; }
div img {
-moz-transform: scale(2) rotate(90deg);
-webkit-transform: scale(2) rotate(90deg);
-ms-transform: scale(2) rotate(90deg);
}
</style>
<div><img src="somelargeimage.png" /></div>
I have put together a small test on jsfiddle showing the undesired behavior.
http://jsfiddle.net/4b9BJ/
Essentially I am trying to create a simple web based image viewer using css3 transforms for rotate and scale and would like a containing div with fixed width/height to be able to scroll to see the full content of the image it contains.
Is there an intelligent way to handle this issue, or even a rough workaround? Any help is appreciated.
I added an extra div to each of the transformations and by setting fixed widths for those divs and clipping overflow I manged to make them the correct size. But then I had to use position: relative and top: blah; left: blah to shift the images into the correct position.
http://jsfiddle.net/4b9BJ/7/