Given the following HTML elements and their styles, the bottom left corner of the reflection is trimmed, which is undesirable. I have tried adjusting the height, overflow, margin, padding, etc. and nothing has made the entire image show. Whats the problem here in the first place? Is there anything I can do without changing the structure of the HTML?
//Elements
<div>
<img id="someImage" src="some-img.png"/>
<section class="reflection"></section>
<div>
//Styles
div {
perspecive:600px;
transform-style:perserve-3d;
}
div > img {
transform:rotateY(-60deg);
}
div > .reflection{
background:-moz-element(#someImage) no-repeat;
transform:scaleY(-1);
}
Only works in Mozilla:
http://jsfiddle.net/zorikii/RWfhc/
If anyone is interested its a pretty simple solution. The -moz-element() function takes the element exactly as it is displayed on screen.
The element() CSS function defines an value generated from an arbitrary HTML element. This image is live, meaning that if the HTML element is changed, the CSS properties using the resulting value are automatically updated. - MDN
So all I had to do was add some padding to the top of the original image element...
img{
transform:rotateY(60deg);
-webkit-transform:rotateY(60deg);
padding-top:100px;
}
.reflection{
background: -moz-element(#someImage) no-repeat;
height:400px;width:200px;
-moz-transform: scaleY(-1);
transform: scaleY(-1);
}
Updated Fiddle
You need to set the transform "origin", like this:
html{
background:black;
}
div{
perspective:600px;
-webkit-perspective:600px;
transform-style:preserve-3d;
-webkit-transform-style:preserve-3d;
/* sets origin slightly higher so it just off center */
-webkit-transform-origin: 50% 40%;
}
img{
transform:rotateY(60deg);
-webkit-transform:rotateY(60deg);
}
.reflection{
background: -moz-element(#someImage) bottom left no-repeat;
height:300px;width:200px;
-moz-transform: scaleY(-1);
}
Related
I am trying to position a rotated headline next to some text. Statically it works very easy with absolute positioning (left picture). I have, however, difficulties when the page gets resized and the positioning fails (right picture).
Current CSS (can be changed):
.headline {
white-space: nowrap;
position: absolute;
top: 185px;
left: -20px;
transform: rotate(270deg);
}
Current HTML structure (can be changed):
<header>
<h1 class="headline">Über mich</h1>
</header>
<div class="text">
<p class="introduction">....</p>
</div>
How can I position the element so that I always stays 20px next to the paragraph?
Could someone link me to existing patterns how to solve this?
A solution with JS (and jQuery) would an option, I would, however, obviously prefer CSS.
Had the same issue. Managed to solve it like this in pure CSS :
.parent {
position: relative;
}
.child {
position: absolute;
transform: translateX(-100%) rotate(-90deg);
transform-origin: right;
left: 30px; /* change this value to match needs */
top: 30px; /* change this value to match needs */
}
The solution was a combination of Diego's answer and Smamatti's comment:
I had to use transform-origin:bottom and width:0. That was working rather quickly, the big problem I had was positioning the text independently to the length of the text. I've only managed to do this by using javascript.
.header
{
margin: 0;
width: 0;
white-space: nowrap;
position: absolute;
text-align: left;
transform-origin: bottom;
margin-top: 280px;
transform: rotate(270deg);
}
Javascript (to ensure compatibility to variables text length):
function adjustSideHeader() {
//check if the headline is visible
if($('h1.headline').length > 0)
{
var headline = $('h1.headline')[0];
var stringLength = headline.textContent.length;
//add style tag to support media queries
document.querySelector('style').textContent +=
"h1.headline { margin-top: " + (stringLength*23.5) + "px; -webkit-transition: margin-top 2s; transition: margin-top 2s;}"
}
}
// fire it when document is loaded
$(document).ready(setTimeout(adjustSideHeader, 300));
Result:
Have you tried moving
<h1 class="headline">Über mich</h1>
inside
<div class="text">?
and set
.text {
position: relative;
}
so that the position is relative to to "text" div. After that you might want to move the Über mich text to the left by reducing it's left value.
Have you tried use position:relative and the margin property?, I suppose it would be something like this:
.headline {
white-space: nowrap;
position: relative; //changed
margin-top: 185px; //changed
margin-left: -20px; //changed
transform: rotate(270deg);
}
*Note: I think you should move the headline inside the paragraph
I have an answer that may be late but worked wonderfully for me.
Normally your text will have a class or id and it will be position:absolute, and positioning values after it, like so:
.TextClass{
position:absolute;
top:50%;
left:55%;
transform:rotate(-90deg);
etc.
However, when you rotate, the positioning becomes relative (as mentioned above).
I found out that by simply putting the rotated text inside a parent div, you can position the (unrotated, position absolute) parent div as much as you want, and then rotate the text (which will be position:relative) inside the parent div, like so:
.divname{
position:absolute;
top:50vh;
left:50vw;
}
.TextClass{
position:relative;
transform:rotate(-90deg);
}
On Chrome on OSX, rotating a element in 3D and performing the inverse of the rotation on a child element breaks mouse events on the child including any links. The hit area seems to be misaligned.
The dom structure is:
<div class='test'>
<div><a href='http://www.google.com'>Click me</a></div>
</div>
The above dom structure is also on JSFiddle
Does anyone know a workaround using the same dom structure that preserves the correct click area?
if a DOM element has an event connected to it for example a click element and you rotate it 90 degrees the element is still at that location but you can't click on it due to it being flat. DOM elements have a zero depth so when you rotate a DOM element 90 degrees you can't see it. if you rotate that same element back you will see it and the click event works. technically the click area works when the element is rotated 90 degrees it just has a zero point area to be clicked.
For the people that do not believe that the event is still attached test this out and see for your self. The event will stay connected to the element no matter how many transformation you do. It also works for chrome. This also works for links too. The only time an event is removed is when you remove the event or remove the element. transformation will never remove the event or the element.
document.getElementById("testButton").addEventListener("click", function() {
alert("It works");
});
document.getElementById("flipButton").addEventListener("click", function() {
if (document.getElementById("testButton").style.webkitTransform == "rotateX(0deg)") {
document.getElementById("testButton").style.webkitTransform = "rotateX(90deg)";
document.getElementById("test").style.webkitTransform = "rotateX(90deg)";
} else {
document.getElementById("testButton").style.webkitTransform = "rotateX(0deg)";
document.getElementById("test").style.webkitTransform = "rotateX(0deg)";
}
});
<html>
<body>
<button id='testButton'>test button</button>
<div id='test'>
<div><a href='http://www.google.com'>Click me</a></div>
</div>
<button id='flipButton'>transform button</button>
</body>
</html>
Here is an example using your example:
.test {
-webkit-transform-style: preserve-3d;
-webkit-transform: rotateX( 90deg);
}
.test>* {
-webkit-transform: rotateX( -90deg);
}
<html>
<body>
<div id='test'>
<div><a href='http://www.google.com'>Click me</a></div>
</div>
</body>
</html>
You will notice that it still works. The reason your code is not working is that your href you have href='htpp://boom'. The URI htpp://boom is not a real address.
There is no such thing as htpp:// and boom is not an address. Your bug in your code has nothing to do with transformation and nothing to do with css. Your bug is not using a real URI.
The -webkit-transform property may be functioning properly in displaying either element(s) at rotateX(90deg), or rotateX(-90deg), respectively.
Whereas at rotateX(90deg), the elements would not be expected to be rendered "view-able", or "visible".
The element(s) would be "flattened" along their X axis, as it were.
At rotateX(90deg) the css is probably transform 'ing the element(s) to just that - 90 deg (rees) sic.
Please see linked jsfiddle, with the css trasform property set to rotateX(45deg), and rotateX(-45deg), respectively, to view the prospective rotateX((n)deg) progression, at 45deg.
Again, the transform property may simply be attempting to achieve a true 90 deg (ree) sic angle, which, along the X axis, might resemble - if visible -
_
or a "horizon".
| - Y axis
_ - X axis
jsfiddle http://jsfiddle.net/guest271314/3XpFG/
Edit (update, workarounds)
You're answer does not mention the clickable area. Also, your demo
does not provide a workaround that preserves the click area. – Mark Lundin
If requirement includes setting css property rotateX() value to 90deg, element may appear to render similar to display : none;, that is, render virtually "invisible" on screen.
See http://jsfiddle.net/guest271314/N6MdE/
Workarounds
1) applicable to both options a), and b), below
html
<!-- add `tabindex` attribute to `.test > a`,
whether `element` rendered "visible", or "invisible",
pressing `Tab` `key` possible to select `a` `element`,
possibly add `title` attribute,
both `attributes` added for "notification",
of `a` `element` ("link") presence at that `position` in `document`,
still possible to `navigate` to `a` `link`, utilizing `Tab` `key`
-->
Click me
a) Render elements at css property rotateX(89deg), rotateX(-89deg), respectively, which should render the elements on screen, perhaps preserving at least some of the "effect" such a ndeg "rotateX()", offset by 1deg. jsfiddle http://jsfiddle.net/guest271314/bzdak/
.test{
-webkit-transform-style: preserve-3d;
-webkit-transform: rotateX( 89deg );
height : 50px;
opacity : 1.0;
}
.test > a{
-webkit-transform: rotateX( -89deg );
}
.test:hover, .test a:hover {
-webkit-transform : rotateX(0deg);
outline : thin solid blue;
opacity : 1.0;
cursor : pointer;
}
.test a:link, .test a:active {
color : #c17d11;
font-size : 24px;
}
b) Render elements at css property rotateX(89deg), rotateX(-89deg), respectively, including css property opacity value set to 0.9, which should render the elements virtually "invisible", similar to a rotateX(90deg) rendering (see http://jsfiddle.net/guest271314/N6MdE/), adding css :hover and/or :active pseudo elements, either, or both, for "notification" of a element ("link") presence at that position in document jsfiddle http://jsfiddle.net/guest271314/De7P6/
.test{
-webkit-transform-style: preserve-3d;
-webkit-transform: rotateX( 89deg );
display : block;
height : 50px;
opacity : 0.9;
}
.test > a{
-webkit-transform: rotateX( -89deg );
}
.test:hover, .test a:hover {
-webkit-transform : rotateX(0deg);
outline : thin solid blue;
opacity : 1.0;
cursor : pointer;
}
.test a:link, .test a:active {
color : #c17d11;
font-size : 24px;
}
I would like the top half of this image to display by default, and then use some CSS to make the image shift upward so that the bottom half shows when the mouse hovers over it. Here is the code and what I've tried, but it is not working. Can anyone help me make this code work?
HTML:
<div id="next">
<img src="images/next3.png" alt="next page">
</div>
CSS:
#next a:hover{background: url('images/next3.png') 0 -45px;}
EDIT:
HTML:
<div id="next">
</div>
CSS:
#next {
height:40px;
width:160px;
background-image:url('images/next3.png');
}
#next:hover{background-position: 100% 100%;}
I think you need to use background-position attribute to achieve this.
CSS
div
{
height:40px;
width:160px;
background-image:url('http://i.stack.imgur.com/OOGtn.png');
}
div:hover
{
background-position:100% 100%;
}
JS Fiddle Example
You can also look into CSS Sprites.
You need to use it as a background in the first place. The <img> is covering the background.
Get rid of the image HTML and just use some CSS like this
a {
display: inline-block;
height: 40px;
width: 160px;
background: transparent url(img.jpg) 0 0 no-repeat;
}
a:hover {
background-position: 0 40px;
}
In this case you will need to remove your <img> tag and consistently use the CSS background attribute for both cases. Also define your height and width width of your a tag with CSS too.
I've run into a rather strange problem. I have a div that is rotatable via CSS3. The div has a front div child and back div child, with the back div having -webkit-transform: rotateY( 180deg ) set.
The problem that once the parent element is rotated to display the back side of the div, it will only detect clicks of child elements on exactly one side of the div, specifically the second half of the div or right side. The front side div detects clicks on the entire face of element. Also, the z-indexes are fine. I assume that the issue may be due to the rotation and the browser displaying one half of the side "closer"?
The code that this is breaking is extremely complex, so I created a test file to demonstrate the problem below. I'm using a jQuery plugin I wrote for the 3D transformations, which can be found here https://github.com/pwhisenhunt/jquery.transform/blob/master/jquery.transform.js.
Edit: After experimentation, the clicking of the button element is only registering from 100-200px and not from 0-100px. In other words, it is in fact only registering on the second half of the div.
Any help is very much appreciated!
<html>
<head>
<style>
.element{
width:200;
height:200;
-webkit-perspective: 800;
-webkit-transform-style: preserve-3d;
}
.element figure {
display: block;
height: 100%;
width: 100%;
position: absolute;
-webkit-backface-visibility: hidden;
border:1px solid yellow;
}
.element .front {
-webkit-border-radius:8px;
padding: 0px;
margin: 0px;
background-color:yellow;
z-index: 9870;
}
.element .back {
-webkit-border-radius:8px;
padding: 0px;
margin: 0;
-webkit-transform: rotateY( 180deg );
z-index: 0;
border: 1px solid red;
background-color:green;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://raw.github.com/pwhisenhunt/jquery.transform/master/jquery.transform.js"></script>
<script>
$(function(){
var temp = false;
$(".element").click(function(){
if(temp == false){
$(this).transform("setAnimationDuration", 1).transform("rotateY", 180);
$(this).unbind("mouseenter mouseleave");
button = $(document.createElement('div')).attr("id", "button").css({ width: 200, height: 50, backgroundColor:"blue" });
button.click(function(){
console.log("Clicking");
});
temp = true;
$(this).append(button);
}
})
})
</script>
</head>
<body>
<div class="element">
<figure class="front"></front>
<figure class="back"></front>
</div>
</body>
</html>
A JSFiddle Example of the Problem - Can be found HERE!
I know this reply is a bit too late for most of us here, but I ran into this problem earlier today, and none of the replies helped me solve it.
Solution by #kristiankeane made the other half non-clickable. I was using a container for the wrapper as well. Turns out, it's an odd bug in webkit, and I was able to fix it and make 100% of the element clickable by changing transform: rotateY(180deg) to transform: rotateY(-180deg)
It's really odd, and I don't know how it worked, but it did. I hope this helps someone!
I had this exact same issue, was able to fix it by slightly changing the parent rotation when flipped - I changed
`.flip-holder.flipped {
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
}`
to
`$.flip-holder.flipped {
-webkit-transform: rotateY(180.5deg);
-moz-transform: rotateY(180.5deg);
transform: rotateY(180.5deg);
}`
and the entire backface (plus overflowed elements positioned absolutely) were now clickable, and the browser did not render the extra 0.5deg of rotation so text and images are clear.
Translate both front and back just a little bit and they won't overlap.
Example:
.element .front {
-webkit-transform: translateZ(1px);
}
.element .back {
-webkit-transform: rotateY(180deg) translateZ(1px);
}
it seems that you are missing a container (in much the same way I was missing it).
see the official documentation
it's not the outer element being flipped, but a wrapper inside it. that in turn causes one of two divs to be displayed (and the transition to occur)
If your flip card structure is like this:
<div class="flipcard">
<div class="flipcard-front">
</div>
<div class="flipcard-back">
</div>
</div>
then add this to your CSS:
.flipcard:hover {
pointer-events: none;
}
.flipcard-back:hover {
pointer-events: auto;
}
could It be (and I'm just speculating) that you should use a live or delegate event bind instead of the regular. I'm speculating the click event maybe 'remembers' some how the original div position without the rotating.
After all tricks as rotate to back and rotate to 180.5 and other...
problem fixed only the following way:
When the rotation ends - create new element, clone html from rotated element, and insert new element instead of old
I have a HTML code as
<div class="fl">
<div class="titleTextV">My ABC</div>
</div>
Now I have applied the CSS to rotate text as;
.titleTextV{
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
font-size:1.3em;
background:#999;
height:100%;
}
I want this titleTextV class to span the entire height of its
container 100%, no px value and be positioned inside, but currently the text is moving out of the box.
If you user jQuery try this:
$('.fl').height($('.titleTextV').width());
And add display: inline-block; to your titleTextV class.
Live example at jsFiddle: