I'm attempting to rotate a div to which I have applied a 'page curl' drop shadow.
The page curl drop shadow effect is working fine until I rotate the div, at which point the drop shadow elements show up through the div (z-index issue)?
I've also noticed that if I have an image as the div content, I don't get this issue, but I'd love to get it working for a div with text content. Any suggestions?
Here's the code:
CSS (vendor prefixes removed to shorten code, but the problem is occurring across all modern browsers):
.shadow {border:1px solid #ccc;position:relative;width:300px;height:116px;background-color:#ededed;}
.shadow:before, .shadow:after {
bottom:13px;
content: "";
position: absolute;
z-index: -1;
-moz-transform: rotate(-11deg);
box-shadow: 0 15px 5px rgba(0, 0, 0, 0.2);
height: 50px;
max-width: 50%;
width: 50%;
left:3px;
}
.shadow:after {
-moz-transform: rotate(11deg);
left: auto;
right: 2px;
}
.rotate{
-moz-transform: rotate(4deg);
}
HTML:
<div class="shadow">this is the first div</div> <!-- this one is ok -->
<div class="shadow rotate">this is the second div</div> <!-- this has the issue -->
<div class="shadow rotate"><img src="//www.google.com/logos/2012/Teachers_Day_Alt-2012-hp.jpg" width="300" height="116"></div> <!-- this one is ok -->
And here's a jsfiddle:
http://jsfiddle.net/U8qY3/5/
Nice job!
As a workaround, you can put a DIV inside the rotated div, with background-colour set to underneath one, and full height and width, like this: http://jsfiddle.net/U8qY3/6/
HTML
<div class="shadow rotate">
<div class="workaround">this is the second div</div>
</div>
CSS
.workaround{
height: 100%;
width: 100%;
background-color: #ededed;
}
Related
I have a situation where, in normal CSS circumstances, a fixed div would be positioned exactly where it is specified (top:0px, left:0px).
This does not seem to be respected if I have a parent that has a translate3d transform. Am I not seeing something? I have tried other webkit-transform like style and transform origin options but had no luck.
I have attached a JSFiddle with an example where I would have expected the yellow box be at the top corner of the page rather than inside of the container element.
You can find below a simplified version of the fiddle:
#outer {
position:relative;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 300px;
border: 1px solid #5511FF;
padding: 10px;
background: rgba(100,180,250, .8);
width: 80%;
}
#middle{
position:relative;
border: 1px dotted #445511;
height: 300px;
padding: 5px;
background: rgba(250,10,255, .6);
}
#inner {
position: fixed;
top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px;
left: 0px;
background: rgba(200,180,80, .8);
margin: 5px;
padding: 5px;
}
<div id="container">
Blue: Outer, <br>
Purple: Middle<br>
Yellow: Inner<br>
<div id="outer">
<div id="middle">
<div id="inner">
Inner block
</div>
</div>
</div>
</div>
How can I make translate3d work with fixed-positioned children?
This is because the transform creates a new local coordinate system, as per W3C spec:
In the HTML namespace, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
This means that fixed positioning becomes fixed to the transformed element, rather than the viewport.
There's not currently a work-around that I'm aware of.
It is also documented on Eric Meyer's article: Un-fixing Fixed Elements with CSS Transforms.
As Bradoergo suggested, just get the window scrollTop and add it to the absolute position top like:
function fix_scroll() {
var s = $(window).scrollTop();
var fixedTitle = $('#fixedContainer');
fixedTitle.css('position','absolute');
fixedTitle.css('top',s + 'px');
}fix_scroll();
$(window).on('scroll',fix_scroll);
This worked for me anyway.
I had a flickering on my fixed top nav when items in the page were using transform, the following applied to my top nav resolved the jumping/flickering issue:
#fixedTopNav {
position: fixed;
top: 0;
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
Thanks to this answer on SO
In Firefox and Safari you can use position: sticky; instead of position: fixed; but it will not work in other browsers. For that you need javascript.
In my opinion, the best method to deal with this is to apply the same translate, but break children that need to be fixed out of their parent (translated) element; and then apply the translate to a div inside the position: fixed wrapper.
The results look something like this (in your case):
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
</div>
<div style='position: fixed; top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
<div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
Inner block
</div>
</div>
JSFiddle: https://jsfiddle.net/hju4nws1/
While this may not be ideal for some use cases, typically if you're fixing a div you probably could care less about what element is its parent/where it falls in the inheritance tree in your DOM, and seems to solve most of the headache - while still allowing both translate and position: fixed to live in (relative) harmony.
I ran across the same problem. The only difference is that my element with 'position: fixed' had its 'top' and 'left' style properties set from JS. So I was able to apply a fix:
var oRect = oElement.getBoundingClientRect();
oRect object will contain real (relative to view port) top and left coordinates. So you can adjust your actual oElement.style.top and oElement.style.left properties.
I have an off canvas sidebar that uses -webkit-transform: translate3d. This was preventing me from placing a fixed footer on the page. I resolved the issue by targeting a class on the html page that is added to the tag on initialization of the sidebar and then writing a css :not qualifier to state "-webkit-transform: none;" to the html tag when that class is not present on the html tag. Hope this helps someone out there with this same issue!
Try to apply opposite transform to the child element:
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(-100%, 0px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
Add a dynamic class while the element transforms.$('#elementId').addClass('transformed').
Then go on to declare in css,
.translat3d(#x, #y, #z) {
-webkit-transform: translate3d(#X, #y, #z);
transform: translate3d(#x, #y, #z);
//All other subsidaries as -moz-transform, -o-transform and -ms-transform
}
then
#elementId {
-webkit-transform: none;
transform: none;
}
then
.transformed {
#elementId {
.translate3d(0px, 20px, 0px);
}
}
Now position: fixed when provided with a top and z-index property values on a child element just work fine and stay fixed until the parent element transforms. When the transformation is reverted the child element pops as fixed again. This should easen the situation if you are actually using a navigation sidebar that toggles open and closes upon a click, and you have a tab-set which should stay sticky as you scroll down the page.
One way to deal with this is to apply the same transform to the fixed element:
<br>
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(0px, 20px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
I have a situation where, in normal CSS circumstances, a fixed div would be positioned exactly where it is specified (top:0px, left:0px).
This does not seem to be respected if I have a parent that has a translate3d transform. Am I not seeing something? I have tried other webkit-transform like style and transform origin options but had no luck.
I have attached a JSFiddle with an example where I would have expected the yellow box be at the top corner of the page rather than inside of the container element.
You can find below a simplified version of the fiddle:
#outer {
position:relative;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 300px;
border: 1px solid #5511FF;
padding: 10px;
background: rgba(100,180,250, .8);
width: 80%;
}
#middle{
position:relative;
border: 1px dotted #445511;
height: 300px;
padding: 5px;
background: rgba(250,10,255, .6);
}
#inner {
position: fixed;
top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px;
left: 0px;
background: rgba(200,180,80, .8);
margin: 5px;
padding: 5px;
}
<div id="container">
Blue: Outer, <br>
Purple: Middle<br>
Yellow: Inner<br>
<div id="outer">
<div id="middle">
<div id="inner">
Inner block
</div>
</div>
</div>
</div>
How can I make translate3d work with fixed-positioned children?
This is because the transform creates a new local coordinate system, as per W3C spec:
In the HTML namespace, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
This means that fixed positioning becomes fixed to the transformed element, rather than the viewport.
There's not currently a work-around that I'm aware of.
It is also documented on Eric Meyer's article: Un-fixing Fixed Elements with CSS Transforms.
As Bradoergo suggested, just get the window scrollTop and add it to the absolute position top like:
function fix_scroll() {
var s = $(window).scrollTop();
var fixedTitle = $('#fixedContainer');
fixedTitle.css('position','absolute');
fixedTitle.css('top',s + 'px');
}fix_scroll();
$(window).on('scroll',fix_scroll);
This worked for me anyway.
I had a flickering on my fixed top nav when items in the page were using transform, the following applied to my top nav resolved the jumping/flickering issue:
#fixedTopNav {
position: fixed;
top: 0;
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
Thanks to this answer on SO
In Firefox and Safari you can use position: sticky; instead of position: fixed; but it will not work in other browsers. For that you need javascript.
In my opinion, the best method to deal with this is to apply the same translate, but break children that need to be fixed out of their parent (translated) element; and then apply the translate to a div inside the position: fixed wrapper.
The results look something like this (in your case):
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
</div>
<div style='position: fixed; top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
<div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
Inner block
</div>
</div>
JSFiddle: https://jsfiddle.net/hju4nws1/
While this may not be ideal for some use cases, typically if you're fixing a div you probably could care less about what element is its parent/where it falls in the inheritance tree in your DOM, and seems to solve most of the headache - while still allowing both translate and position: fixed to live in (relative) harmony.
I ran across the same problem. The only difference is that my element with 'position: fixed' had its 'top' and 'left' style properties set from JS. So I was able to apply a fix:
var oRect = oElement.getBoundingClientRect();
oRect object will contain real (relative to view port) top and left coordinates. So you can adjust your actual oElement.style.top and oElement.style.left properties.
I have an off canvas sidebar that uses -webkit-transform: translate3d. This was preventing me from placing a fixed footer on the page. I resolved the issue by targeting a class on the html page that is added to the tag on initialization of the sidebar and then writing a css :not qualifier to state "-webkit-transform: none;" to the html tag when that class is not present on the html tag. Hope this helps someone out there with this same issue!
Try to apply opposite transform to the child element:
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(-100%, 0px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
Add a dynamic class while the element transforms.$('#elementId').addClass('transformed').
Then go on to declare in css,
.translat3d(#x, #y, #z) {
-webkit-transform: translate3d(#X, #y, #z);
transform: translate3d(#x, #y, #z);
//All other subsidaries as -moz-transform, -o-transform and -ms-transform
}
then
#elementId {
-webkit-transform: none;
transform: none;
}
then
.transformed {
#elementId {
.translate3d(0px, 20px, 0px);
}
}
Now position: fixed when provided with a top and z-index property values on a child element just work fine and stay fixed until the parent element transforms. When the transformation is reverted the child element pops as fixed again. This should easen the situation if you are actually using a navigation sidebar that toggles open and closes upon a click, and you have a tab-set which should stay sticky as you scroll down the page.
One way to deal with this is to apply the same transform to the fixed element:
<br>
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(0px, 20px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
I'm using bootstrap 3 as my grid framework along with css to create a semi-transparent area with one skewed/slanted edge, but am running into problems with my elements due to layered opacity.
The expectation is that the center is slanted, but the right side is still square.
Is there a better way to accomplish this?
Please see the jsfiddle for a working example.
<div class="container">
<div class="row marketing-text">
<div class="col-sm-6">
<!-- Intentionally empty, jsfiddle was giving me issues with the offset -->
</div>
<div class="col-sm-6 right">
<h5 class="uppercase">Header Text</h5>
<p>Long Text Input</p>
</div>
</div>
</div>
<style>
.row.marketing-text .right {
padding-top: 50px;
padding-bottom: 50px;
padding-left: 50px;
padding-right: 50px;
background-color: rgba(255, 139, 0, 0.5);
}
.row.marketing-text .right::before {
content: " ";
transform-origin: top;
-ms-transform: skew(-20deg, 0deg);
-webkit-transform: skew(-20deg, 0deg);
transform: skew(-20deg, 0deg);
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(255, 139, 0, 0.5);
}
</style>
https://jsfiddle.net/aq9Laaew/255707/
Referring your example, Overlapping layers having background-color with opacity/rgba value will definitely not achieve the desired output.
Better way to accomplish this would be using :before and :after pseudo-elements
I have a button fixed inside of outer div. The problem is when I set position: fixed(to keep the button stay while the page is scrolling) it didn't work properly.
The button still scrolled and moved out of the screen.
here is my code
.rotate {
transform: rotate(30deg);
background: blue;
width: 300px;
height: 300px;
margin: 0 auto;
}
.fixed {
position: fixed;
background: red;
padding: 10px;
color: white;
top: 50px;
}
<div class="rotate">
<button class="fixed"> I am fixed inside a rotated div.</button>
</div>
<!-- <div class="fixed"> I am fixed outside a rotated div.</div> -->
How can I fix it to keep button always display on the screen while scrolling the page?
This is either a buggy or by design behavior by the browsers: basically, and "position: fixed" fixed element won't be fixed if any parent element has "transform" set. The following thread has some reference on it:
Positions fixed doesn't work when using -webkit-transform
As for a workaround, you might use a as a wrapper and nest the colored and the rotated inside it, then adjust the positioning with "margin". It's kinda hacky, but it might work depending on the situation. Here's a demo:
[http://codepen.io/jean-andreghetto/pen/OxEaVN?editors=1100][2]
You have the fixed element inside of the static box, which means you made the red link fixed to the blue box, and not to the outside. What you need to do is remove the red link of inside the blue box.
This should be what you want.
https://codepen.io/dawsonhudson17/pen/jGKeRy
.rotate {
transform: rotate(30deg);
background: blue;
width: 300px;
height: 300px;
margin: 0 auto;
}
.fixed {
position: fixed;
background: red;
padding: 10px;
color: white;
top: 50px;
left: 50%;
z-index: 2;
transform: translate(-50%) rotate(30deg);
display: block;
}
<button class="fixed"> I am fixed inside a rotated div.</button>
<div class="rotate">
</div>
Since upgrading to iOS 7 on multiple iPhones and iPads, we've seen something very strange happening to part of the UI on our website.
The pink box in the image attached is within an absolutely positioned parent and it has two white divs positioned absolutely within it, each with differing opacities. The pink circle is just a div that has border-radius set to make it a circle. There are no images at all in this layout.
For some reason, the browser is intermittently stretching the pink div, but I can't think of anything that would cause it - and I'd have no idea how to achieve this effect if I wanted to!
I presume it's a bug in the browser(s), but I don't know how to fix it.
I haven't included any code as it's all really, really straightforward and there's nothing in there that would cause this (and indeed it works in iOS6). Just hoping someone has seen this before?
Any ideas?
Update
In response to comment by cimmamon here's the code:
<div class="col" style="left: -3920px; width: 280px;">
<div class="periods">
<div class="period3"></div>
<div class="period2"></div>
<div class="period1"></div>
<div class="nodeline colBk">
<div class="node colBrd"></div>
</div>
</div>
<div class="inner">
<div class="group first">
<div class="branch colBk"></div>
<a class="story">
<div class="strip colBk"></div>
<div class="caption">
<div class="text">
<p class="title">Test</p>
</div>
</div>
</a>
</div>
</div>
And the CSS that applies to the 'periods' container and children:
.tls .col { display: inline-block; position: absolute; top: 0; }
.periods { height: 72px; overflow:hidden; position: relative; border-left: 1px solid #fff; }
.period2 { height: 30px; opacity: 0.6; background-color: #fff; position: absolute; width: 100%; }
.period1 { height: 25px; opacity: 0.72; top: 30px; background-color: #fff; position: absolute; width: 100%; }
.nodeline { height: 61px; }
.colBk { background-color: #dd545c; }
.nodeline { height: 61px; }
.node { position: absolute; margin-left: -15px; left: 50%; bottom: 0px; width: 17px; height: 17px; border-radius: 50%; border: 6px solid #dd545c; background-color: #f9f9f9; }
.colBrd { border-color: #dd545c; }
It's such a strange bug - there's nothing in the CSS that could cause this that I can see.
Any suggestions on what CSS I could add that might force it to render correctly? You'd think the height alone would be enough but obviously not.
Fiddle here
I've had this problem, and it's also now in Safari 7.
Here's a simplified version of what was happening in my case
HTML
<ul>
<li>
<a> Some text </a>
</li>
<li>
<a> Some other text </a>
</li>
</ul>
I then had some javascript (in my case the bootstrap tooltip) which was adding in an element which made the html
<ul>
<li>
<a> Some text </a>
<div style="position: absolute" class="tooltip"> Some content here </div>
</li>
<li>
<a> Some other text </a>
</li>
</ul>
The new div was briefly displaying before the whole ul would get stretched down over the top of the new div.
This has got to be a bug in safari, but adding the following CSS to the inserted div works as a workaround.
.tooltip {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
This forces the inserted div to be rendered in a new composite layer which seems to prevent Safari screwing up.
Hopefully this is enough for you to reach a solution but let me know if not and I can flesh this answer out a bit more.
Try using backface-visibility:
-webkit-backface-visibility:hidden;
it caused my headings to stretch, once removed the world was and is a happier place
tested on iOS 6 & iOS 7 & Android 4.2 +
Another apparent workaround that avoids creating additional compositing layers is to add perspective to the elements that are in a GPU-composited context. (In this case, that's the elements with opacity.) Note that if you're positioning things in 3D space with translate3d, this will have a visual impact, and may not be an effective workaround.
.period1, .period2, .period3 {
-webkit-perspective: 1px;
perspective: 1px;
}
maybe this fixes the issue:
add height:17px; to .node so your css should look like
.node {
background-color: #F9F9F9;
border: 6px solid #DD545C;
border-radius: 50% 50% 50% 50%;
bottom: 0;
height: 17px; /*new*/
left: 50%;
margin-left: -15px;
position: absolute;
width: 17px;
}
jsFiddle