CSS3 Rotate3d in desired direction - javascript

In this demo of rotate3d from the W3C, the first example is rotating the face of a div toward the "upper left".
However, with the same vector I can't get the face of a div to rotate toward the "upper left". How can I get this same rotation?
jsfiddle
#r {
position: absolute;
top: 100px;
left: 100px;
border: 7px dotted;
width: 200px;
height: 100px;
background-color: red;
font-size: 20px;
-webkit-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
#r:hover {
-webkit-transform: rotate3d(1, -1, 0, 70deg);
transform: rotate3d(1, -1, 0, 70deg);
}

What you have is correct. For me, the transformed version of the W3Schools first demo looked like this when inspected
The black outline was some weirdly warped version that doesn't make sense when you look at the code. The blue area is where it says the element is (and where it should be) and shows the correct transform
Here is what I see when I hover over your element
It's the same transform, just with a wider element. The problem is that our eyes can perceive that rotation as leaning back left of forwards right.
To show this you can look at this example I created for another question. With the shadows you can easily tell that the divs are following the mouse cursor
Now comment out lines 15 and 16 in the javascript to remove the shadows and try moving your mouse from the top left to the bottom right and then back. What do you find? it looks like the divs are moving the same way no matter which you go to!
Our eyes are stupid. Adding a small shadow to your element will make our eyes interpret the transform as you want them to. Updated jsFiddle
box-shadow: 10px 10px 5px #3D352A;
You can style the shadow however you like, but adding a small one makes it easier for our eyes to follow exactly what's happening
On a side note, don't use W3Schools, they are flawed, outdated, and often act unlike how they should. Don't be a W3Fool!

Like Zeaklous noted, it's our eyes who are fooled. So you'd have to add the perspective property to the container element. With this property you can control the strength of the 3d effect. It's the distance of the viewer's eye to the scene. The lower the value the more 3D effect there will be.
Another thing: It's better to have a container element for the face with position:relative and give that container the perspective property. Else you'd need perspective-origin property to center the 3D effect.
There also seems to be a bug in chrome. So sometimes the perspective works and sometimes not. A hack which I used is to add the perspective as transform: perspective( 400px ) to the child element.
Look the updated JSFiddle
Remember: Add the prefixes -moz and -o to support Mozilla and Opera, too.

Made four different variants, each in one direction...
<div id="ulb">
ULB<br/>
UPPER LEFT Backwards<br/>
rotate3d(-200,70,0,70deg);
</div>
<div id="urb">
URB<br/>
UPPER RIGHT Backwards<br/>
rotate3d(1,1,0,70deg);
</div>
<div id="llb">
LLB<br/>
LOWER LEFT Backwards<br/>
rotate3d(1,1,0,-70deg);
</div>
<div id="lrb">
LLB<br/>
LOWER RIGHT Backwards<br/>
rotate3d(1,-1,0,70deg);
</div>
JSFiddle

Related

How to set zoom on a element using Javascript on Firefox?

I can change a page element on Chrome using zoom
document.getElementById("pane-side").style.zoom = 0.5
Looks like Firefox did not support zoom, when i run the same code nothing happens.
Im searching for how to use zoom on Firefox, and i got this code:
document.getElementById("pane-side").style["-moz-transform"] = "scale(0.5)"
But the result was not what I expected:
Im trying to zoom out the element like on Chrome, any advice?
-EDIT-
The element I'm trying to zoom in is from the page web.whatsapp.com, the panel where show some contacts when you type something in the search (like on the chrome photo).
I hope you are not using this CSS property for a website in production,
the property zoom is a non-standard CSS property, originated from IE, unofficially proposed in May 2015 by Rossen Atanassov working at Microsoft.
It is unsafe to use since it will not work for every browser (and in my humble opinion, probably not going to be implemented). Unfortunately, this CSS property is not implemented in the Firefox Browser hence you are experiencing this issue.
I see that you already tried to use transform: scale(); instead,
and the difference in your screenshot is due to the fact zoom affects the layout size of the elements, while transform: scale(); does not.
You could try with the CSS at-rule #viewport, but keep in mind that this one was deprecated too (in 2020, here are the details: https://github.com/w3c/csswg-drafts/issues/4766) and probably doesn't work in Firefox either.
In your CSS file:
#viewport {
zoom: 1
}
A zoom factor of 1 or 100% corresponds to no zooming. Larger values zoom in. Smaller values zoom out.
That being said, you could also try to set bigger the font size of the target element (to have a zoomed-in effect).
If this is not enough, you could try to find a good balance between those properties.
I'll do the CSS example that might scale up all the font sizes:
body {
transform: scale(1.5);
font-size: 150%; // or any other value that is bigger than the computed value
padding: 20%; // optional spacing if some text is not visible because of the transform scale
}
zoom is not supported by FireFox.
Solutions below should work as you expect, only adjust numbers for your needs:
document.getElementById("pane-side").style.transform = "scale(0.5)";
document.getElementById("pane-side").style.transformOrigin = "left top";
document.getElementById("pane-side").style.width = "795px";
document.getElementById("pane-side").style.minHeight = "1700px";
document.getElementById("pane-side").style.alignSelf = "flex-start";
Or CSS version:
#pane-side {
transform: scale(0.5);
transform-origin: left top;
width: 795px;
min-height: 1700px;
align-self: flex-start;
}
Or eventually <style> element added with JS:
var style = document.createElement('style');
style.innerHTML = `
#pane-side {
transform: scale(0.5);
transform-origin: left top;
width: 795px;
min-height: 1700px;
align-self: flex-start;
}
`;
document.head.appendChild(style);
Does this works for you?
zoom: 0.5;
-ms-zoom: 0.5;
-webkit-zoom: 0.5;
-moz-transform: scale(0.5,0.5);
-moz-transform-origin: left center;
Both -moz-transform and transform should be supported in FF.
It could be because of the differences between zoom and scale.
zoom is applied pre-render and changes the layout sizing of the element.
transform is applied post-render and doesn't change the layout sizing
The easiest way to see this is with a div sized relative to a fixed element.
On zoom, everything inside the div will zoom in/out, but the div stays the same
On scale, everything 'zooms' in/out, including the div
You Can Use CSS Variables Try this
document.getElementById("pane-side").style.setProperty('--zoom', '0.5');
*{
transform: scale(var(--zoom));
}
<h1 id="pane-side" >Firefox</h1>

Notable spacing in rendering SVG in edge(chakra), firefox vs chrome | skewed layout

So I have this tricky layout that's giving me headaches.
I've placed few triangles (using svg polygon) and they seem to work fine in Chrome, but bug out a bit in Edge & Firefox.I tried using border and box-shadow to hide it, but it doesn't seem to help.
Is there any way to hide the white gaps? (on grey, orange and blue parts) (If you don't see them at first - try to resize the window a bit and it'll snap at some point)
#update2: setting borders for adjactent div looks like a workaround for now
I've also tried using a single css clip-path with a polygon that's shapped like a trapezoid, but it's not widely supported. The other thing i tried is to use css transform skew(), but I found it troublesome to position properly, as the following sections have to move accordingly to the side to match the degree of skew.
If you at least think there's a better solution to make this, please give me a hint and I'll try it out.
Here's the code for the version with svg triangles:
And for the clip-path version:
And the skew version:
#edit1
I've discovered that setting a gradient could help, but it leaks out on the corner...
background: linear-gradient(left,
rgb(253, 96, 64) 0%
rgba(255,255,255,0.8) 8px,
rgba(255,255,255,0) 100%)
#edit2
Changing the div neighbouring to the triangle to:
border-right: 1px solid rgb(253, 96, 64);
position: relative;
margin-right: -1px;
seems to be a good workaround. I've updated it in the sandbox.

Bootstrap 3 align elements into circle

I have a question about forming elements to form a circle, or align elements to form a circle, depending how you like it to be pronounce, now back to question:
There are couple of examples here on stackoverflow and on the internet regarding this question but any off these examples do not cover Bootstrap 3 responsive align elements to form a circle, I would like if someone can make an example out of mine working JSFiddle example (text needs to be a center of the circle, because I need to animate it), and make this using bootstrap grid system.
Is this possible, can you please explain to me how you do this so I can learn something out of this.
TL;DR; http://jsfiddle.net/k7yxtpc7/
Edit with (very long?) explanation:
So we start off with a bootstrap's hierarchy:
<div class="container-fluid">
<div class="row">
<div class="circle_container col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2 col-xs-12">
</div>
</div>
</div>
The planetary of images will be put inside .circle_container. Our aim is to make sure the whole circle will respond to .circle_container's width changes and adapt correctly. This way any change Boostrap makes to the container will be reflected on the circle itself, making it Bootstrap-compliant.
First we have to prepare .circle_container a bit. Since it's a whole circle the container must be square-ish. We must find a way to make .circle_container's height to be always equal to its width. I do this by putting a square img inside .circle_container, then scale the img's size according to the container's width:
<div class="circle_container ...">
<img class="transparent_square" src="http://i.stack.imgur.com/5Y4F4.jpg" width="2" height="2" />
</div>
.transparent_square{
width: 100%;
height: auto;
}
Note: I couldn't find a transparent square image on the web, so I had to make do with a white square. In your product a 2pxx2px transparent image is best.
Great, now we have a square container. But we've put a limiter on ourselves too. From now on, the img must be the only child of .circle_container that have a static (default) or relative position, because any further child will extend the container, destroying the square shape. Not a big deal though, since we'll position other children absolute anyway.
Next up is the central text bubble:
<div class="central_text text-center">
<h3>Special for you</h3>
<h5>Lorem ipsum</h5>
</div>
.central_text{
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
The translate trick make use of the fact that percentile value in css transform use the element's pre-render width & height, while all other positioning rule use its parent's width & height instead. By giving the element left: 50%; top: 50% we put its top left corner at the center of its parent, then we translate it up and to the left by 50% of its own width and height, effectively centering the element within its parent. This is only 1 of several methods to center an element within a container, but it fits our situation best because the element is absolutely positioned.
Finally we reach the part where we create the circle. To sum up the trick here: we put the actual image inside a container, which has a pivot point at the center of the container, and position the image off to 1 side of the container equal to the radius of the circle. This way when we rotate the image's container, the image will be moved in a circle around the center of the container, like a drawing compass. After the image has reached our desired position, we rotate the image itself by the same degree in the other direction to compensate for the tilt in orientation, making the image upright again.
The container and image:
<div class="moon_container moon1"><img class="moon moon1" src="http://letscode.ghost.io/content/images/2015/09/stackoverflow.png"></div>
.moon_container{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 20%; /* This is the final width of the image */
}
I set the width for .moon_container as 20% of .circle_container's width. This will be the width of the images in our final circle. Increasing or decreasing this number simply change the size of the image to your desire.
Now to offset the image from its container:
.moon{
width: 100%;
height: auto;
/* The image can be relative positioned without breaking anything because its parent is absolute */
position: relative;
/* The radius of the circle. This is equal to 175%*20% = 35% of .circle_container's width */
left: 175%;
}
Note that CSS's left use an element's direct parent's width as base unit. If you changed .moon_container's width in the previous part, the actual distance of the images will change as well.
Finally, rotations (I use moon2 as the example here because moon1 doesn't need to rotate):
/* Container rotate 45deg clockwise... */
.moon_container.moon2{
/* 360/8 (the number of images) = 45deg */
transform: translate(-50%, -50%) rotate(45deg);
}
/* ... while the image rotate 45deg counter-clockwise */
.moon.moon2{
transform: rotate(-45deg);
}
Why transform: translate(-50%, -50%) rotate(45deg); and not transform: rotate(45deg);? Because we declared transform: translate(-50%, -50%); earlier for the .moon_container (the centering trick). If we only write transform: rotate(45deg); here, the CSS parser will override the previous rule with the new one, losing the translate part. So we have to append manually.
Repeat the process to all 8 images and we're done!
If you have undetermined number of images, simply use javascript to calculate this rotation part for each image.
I hope my explanation was useful for you. I've always been bad at explanation...
Edit 2: http://jsfiddle.net/k7yxtpc7/3/ Text change on hover version as per OP's request. There's only 1 thing to note in this part, that is
$("body").on({
mouseenter : function(event){
...
},
mouseleave : function(event){
...
}
}, ".moon");
It is good habit to bind all events on either 'body' or document, instead of binding them on the actual elements itself (the .moon). This way you:
Always use only 1 event listener for the hover event, instead of 8 (you can imagine how the number scale up on an actual product).
When you add more images later, you don't have to bind the event on the new .moon again.
Original Answer:
As the requirement is rather vague, I couldn't know if my solution would satisfy you. My solution is based on 3 assumptions:
The entire planetary of images are only based on view port width, similar to how Bootstrap handle its responsive design. If you want to take view port height into consideration maybe I can conjure up another version.
The images are scaled based on the Bootstrap container's width, in order to make sure there's enough space to display all images.
Typography uses Bootstrap's defaults.
The solution avoid using javascript at the cost of not being able to add/remove images on-the-fly. If a dynamic number of images is your intention, I will put calculations in.
Sexy animations compatible.
Unfortunately Bootstrap's center-block only center a block horizontally, I had to make use of the translate trick to center the pivot point.
.central_text{
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
This is only an answer placeholder. I will write detailed explanation once we have a satisfactory solution.

CSS3 Vertical text banner to left of content

I am no guru when it comes to CSS and I wanted to create a web page layout using CSS only if possible. The layout that I would like is to have two divs, one containing a banner and the other containing the content of the page with the banner to the left of the content. So far easy enough. The banner div contains two sub-divs, one containing the title of the page and the other containing some extra information such as contact information. Once again, not too hard.
The problem arises when I want the text displayed in the title to be vertical, reading from bottom to top. I did some searching around on the web and found the CSS3 transform rotate functionality which does what I want it to do.
#name {
border: solid 1px black;
background-color: yellow;
height: 50px;
font: normal normal bold 40px Helvetica, Arial, sans-serif;
padding: 10px;
-webkit-transform-origin: left bottom;
-webkit-transform: rotate(270deg);
-moz-transform-origin: left bottom;
-moz-transform: rotate(270deg);
-ms-transform-origin: left bottom;
-ms-transform: rotate(270deg);
-o-transform-origin: left bottom;
-o-transform: rotate(270deg);
transform-origin: left bottom;
transform: rotate(270deg);
}
Unfortunately, when it comes to rendering the text in the browser, the space reserved by the browser for the rotated text is the width of the banner text before it was rotated, and not the width of the text after rotation (i.e. the height of the banner text before rotation). Hence my content div is sitting way out on the page when I would like it to be right next to my banner div.
To see what I mean, check out this JSFiddle.
How do I get the two divs to live side by side?
This doesn't haven't to be a purely CSS solution as I think I may have to use JavaScript/jQuery to calculate widths and heights etc. and then move the banner div accordingly, but a pure CSS solution would be nifty.
here's a fiddle: http://jsfiddle.net/sijav/UDfZE/53/
you should do this, make a max-width for #banner,
max-width:170px;
then put display:block-inline to main content too, that should do the trick.
http://jsfiddle.net/UDfZE/55/
float: left
Altered the above fiddle floating one element right the other one left will have them alongside each other.

Brighten images from dark to light on hover

I'm looking for a script of some sort that will select all images on a page within a certain div.class, apply a transparent black shadowing to it, and then fade it out on hover. Does anyone know of a system of doing this? I can't really modify the site itself (http://cargocollective.com/maureengriswold) or I'd have figured out some shoddy way of doing it already.
Typically you would do this by putting a black background behind your images and the set the opacity of the images to some value < 1.
On your site, you would add the following CSS:
.cardimgcrop {
background-color: black;
border-color: white;
}
.cardimgcrop img {
opacity: 0.7;
}
.cardimgcrop img:hover {
opacity: 1;
}
UPDATE:
If you want an animated fading, you would leave out the :hover CSS definition and add the following Javascript lines (using jQuery 1.4.2 as already used on your site):
$(document).delegate('.cardimgcrop img', 'mouseover', function() {
$(this).fadeTo(500, 1);
});
$(document).delegate('.cardimgcrop img', 'mouseout', function() {
$(this).fadeTo(500, 0.7);
});
Of course you could also native CSS transitions instead for this effect (as suggested in Howard's answer), but you would need to take care of browser capabilities.
Not entirely sure what you mean by transparent black shadowing, but I think you mean an effect like a veil over it, which lifts on hover and returns on mouseout?
You can probably achieve this effect entirely using css. Something like this:
DIV.myClass{
-moz-transition-property: background-color;
-moz-transition-duration: 2s;
background-color: rgba(0,0,0,0.6);
}
DIV.myClass:hover{
-moz-transition-property: background-color;
-moz-transition-duration: 2s;
background-color: rgba(255,255,255,1);
You'll want to play around with the exact CSS to achieve the effect you want, and also you'll want to test in various browsers as CSS transition support is not 100%.
You can read more on CSS Transitions at the MDN documentation site.
CSS filters are another option http://html5-demos.appspot.com/static/css/filters/index.html

Categories

Resources