Here's a fiddle.
.box:hover {
-moz-transform: rotate3d(0,1,0,180deg);
-webkit-transform: rotate3d(0,1,0,180deg);
-ms-transform: rotate3d(0,1,0,180deg);
transform: rotate3d(0,1,0,180deg);
}
I'm using some CSS3 to get the card flip effect on some parts of my site. I have no issues with this in any Windows browsers, but I'm getting reports from some Mac users that the rotation is getting stuck and won't flip over completely. It looks like in those browsers, when doing a 3d transformation it appears that the "hitbox" for hover is transformed along with the element and content (as it gets close to rotating 90 degrees, the hitbox for the element approaches 1px width).
I could be wrong about what's happening or maybe there's a better fix than what I have in mind, but I was looking to hopefully work around this issue by causing the full transition/animation to play out as soon as the mouse triggered the hover. This way, even if the hitbox for the hover does change size, the elements will finish flipping over.
Is this possible with just CSS3? Or should I look into a javascript solution?
Wrap it with a wrapper and put the hover on the wrapper. I tested on FF and chrome on Mac
https://jsfiddle.net/6udv405h/3/
.wrapper:hover .box {
-moz-transform: rotate3d(0,1,0,180deg);
-webkit-transform: rotate3d(0,1,0,180deg);
-ms-transform: rotate3d(0,1,0,180deg);
transform: rotate3d(0,1,0,180deg);
}
HTML
<div class="wrapper">
<div class="box"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.box').mouseover(function () {
var box = $(this)
$(box).addClass('hovered');
setTimeout(function () {
$(box).removeClass('hovered');
}, 1000);
});
});
</script>
Little bit of Jquery solved my issue. I would still have preferred to use only CSS, so please reach out to me if you have a better solution without using JS.
Related
I have a simple class defined in css for an iframe that holds a slideshow pulled from Smugmug. The basic function is a 25% opacity when the user does not hover over the slideshow and a transition to 100% opacity when the user hovers over the iframe area. This works in Chrome, Firefox and Safari, but not in Microsoft Edge. In Edge, I get the 25% opacity and transitions, but the hover does not lift the opacity.
Does anyone know why Edge does not work? Am I missing some directive for the Edge browser?
Here is an example of the iframe . . .
<div id=avalon class="slide">
<iframe src="https://johndoc1.smugmug.com/frame/slideshow? key=M9jkGB&autoStart=1&captions=1&navigation=1&playButton=1&randomize=0&speed=4&transition=fade&transitionSpeed=2" width="1100" height="825" frameborder="no" scrolling="no"></iframe>
</div>
Here is the css for the slide class . . .
/* Slideshow style */
.slide {
width:80%;
margin-left:auto;
margin-right:auto;
background: #2F4538;
}
.slide iframe{
opacity:0.25;
transition: opacity 0.5s linear;
max-height: 100%;
max-width: 100%;
}
.slide iframe:hover{
opacity:1.0;
}
Thanks.
John Doc
I know that this is actually not very clean, but I tried several things and I was not able to make it run just via css. Maybe Edge is missing some directive in render core ... who knows.
Anyway... I was able to run it via javascript, in this solution I use jQuery as it is closer to me, I will add pure JS solutions as soon as I find, why jsfiddle cannot see my declared functions...
So - here it is:
https://jsfiddle.net/f4y0uugc/2/
note that jQuery code has to be on document ready.
theese are the major changes:
$(".slide iframe").on("mouseover", function(){
$(this).addClass("slideiframe");
});
$(".slide iframe").on("mouseout", function(){
$(this).removeClass("slideiframe");
});
and css added just
.slideiframe{
opacity:1.0 !important;
}
//EDIT - pure JS
Ok, here is a pure solution:
https://jsfiddle.net/f4y0uugc/4/
here you have your JS:
var slide;
function op025(){
slide = document.getElementsByClassName("slide")[0].getElementsByTagName("iframe")[0];
slide.style.opacity = 0.5;
}
function op1(){
slide = document.getElementsByClassName("slide")[0].getElementsByTagName("iframe")[0];
slide.style.opacity = 1;
}
Note, that classes and elements are arrays, yo if you have more than one matches, you will have to add IDs, or iterate in cycle for each solution.
Next, you have to set up calls of functions, so in html:
<div id=avalon class="slide">
<iframe onmouseover="op1();" onmouseout="op025();" src="https://johndoc1.smugmug.com/frame/slideshow? key=M9jkGB&autoStart=1&captions=1&navigation=1&playButton=1&randomize=0&speed=4&transition=fade&transitionSpeed=2" width="1100" height="825" frameborder="no" scrolling="no"></iframe>
</div>
Also, for both solutions, as this is scripted soltion, I have reduced transition duration to 0.2s as if user quickly moves cursor over the edge, opacity behavior is not clean.
I will try something pure css more, and I will let you know if I find something.
Using zoom: 0.5;, image gets rendered in 0.5x size when not inside <a> tag, but in 1x size when inside <a> tag.
This occurred with iOS 8 GM (iPhone 5 simulator of Xcode 6 GM, and iPad mini).
This did not occur with iOS 7.1.2 (iPhone 5) and iOS 7.0 (iPhone 5 simulator of Xcode 6 GM).
Here is an example : https://dl.dropboxusercontent.com/u/379843/ios8csszoom/test.html
<!DOCTYPE html>
<html>
<body>
<img src="star-on#2x.png" style="border: 1px solid blue; zoom: 0.5;"/>
<a href="#">
<img src="star-on#2x.png" style="border: 1px solid blue; zoom: 0.5;"/>
</a>
<hr>
<img src="star-on#2x.png" style="border: 1px solid blue; -webkit-transform: scale(0.5);"/>
<a href="#">
<img src="star-on#2x.png" style="border: 1px solid blue; -webkit-transform: scale(0.5);"/>
</a>
</body>
</html>
-webkit-transform is functioning on iOS 8, but I don' want to use this, because even though the image is rendered in 0.5x size, the space consumed by the <img> tag is 1x size.
Any workarounds?
Although not ideal, this is how I've coped with the problem:
Replace anchors with another element (div or span depending on block/inline)
Give each element a shared class name
Either leave the href, or, add a data-href property with the href
On a high level, have an event listener bind to all elements with your class name
Event listener reads href and then triggers routing/controller logic appropriate for your framework
Example: http://jsfiddle.net/z5crh05a/
$(".fauxLink").on("click", function(e) {
var href = $(e.currentTarget).attr("href");
e.preventDefault();
e.stopPropagation();
// navigation logic here
alert("Navigate to: "+href);
});
});
Hopefully the issue in Safari is fixed in a future iOS update.
By default -webkit-transform on Safari and MobileSafari has an origin “center center”, which means the parent container will be the same size as if not scaled.
Adjust this by setting this to “top left” using:
-webkit-transform-origin 0 0;
Whole solution would then be (with IE9+, FF, Chrome and Safari/MobileSafari support):
transform: scale(0.5);
-ms-transform: scale(0.5);
-mos-transform: scale(0.5);
-webkit-transform: scale(0.5);
transform-origin: 0 0;
-ms-transform-origin: 0 0;
-mos-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
I transform these pictures with scale.
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
-o-transform: scale(0.5);
transform: scale(0.5);
this also works for ios but you have to reposition your pics after that!
I figured out a workaround, but can only be used with a webapp framework.
I was using CakePHP, and was using a helper method to output all img tags, so I overrided that method so that it would output width and height attributes, and quit using the css zoom.
I used getimagesize of GD to get the width and height.
http://php.net/manual/ja/function.getimagesize.php
Rather than changing your markup, you can just resize the images using a little bit of javascript.
Here's a working snippet (using jQuery) of what I'm currently using on my WordPress blog:
var dmblog = {
// [TRUNCATED]
// ! dmblog.imgZoomResize
imgZoomResize : function(element) {
var zoom = element.css('zoom');
element.width(element[0].naturalWidth*zoom);
element.height(element[0].naturalHeight*zoom);
},
// ! dmblog.retinaImagesResize
retinaImagesResize : function() {
$('.post .entry-content img, .comment .comment-content img').each(function(){
dmblog.imgZoomResize($(this));
// set a handler on the resize event to resize the retina images
var $w = $(window),
namespace = $(this)[0].id.replace('#','.'),
element = $(this),
handler = function() {
dmblog.imgZoomResize(element);
};
$w.bind('resize'+namespace, handler);
});
}
};
// [TRUNCATED]
// ! for single posts, load some scripts
if ($('body').hasClass('single'))
{
// [TRUNCATED]
// resize retina images
dmblog.retinaImagesResize();
}
Using this workaround, there's no need to change your css, the anchor tags, nor any of your markup, just add a little bit of javascript to resize the images.
I'm using CSS media queries to set the CSS zoom to 1 on large screens, and to 0.5 on smaller screens. Even though the zoom value doesn't work anymore, it still reports as 0.5 in jQuery. Since it's a responsive design, I added a handler on the window resize event to automatically resize the image up/down whenever the zoom value is changed (responding to CSS media queries).
If you're not using media queries to responsively change the CSS zoom value though, then the amount of javascript you'll need (without the handler) is much less.
I have checked that in developer tools, the classes are simply not added during first time animation to the entering view.
My question is: Is this supposed to happen and I should add something more than ng-view directive or is it a bug and I should look for a workaround?
HTML:
<div ng-view></div>
CSS:
div[ng-view].ng-enter, div[ng-view].ng-leave {
-webkit-transition: all cubic-bezier(0.455, 0.03, 0.515, 0.955) 0.5s;
-webkit-transform: translateZ(0);
}
div[ng-view].ng-enter {
-webkit-transform: translateX(100%);
}
div[ng-view].ng-enter-active {
-webkit-transform: translateX(0);
}
div[ng-view].ng-leave {
-webkit-transform: translateX(0);
}
div[ng-view].ng-leave-active {
-webkit-transform: translateX(-100%);
}
That is actually all information I can provide. I have checked that all events are fired properly and there is nothing I can do wrong because there is no actual code I have written myself except for the CSS styles. After first $location.path() or href click css classes like ng-leave and ng-leave-active are added to the old view, but ng-enter and ng-enter-active are not added to the new view. After that first occurance everything works as expected.
It looks that it's now (since version 1.2.3) the normal way to go.
Animations are not played on bootstrap as explained here :
https://github.com/angular/angular.js/issues/5130
Several topics are asking for a solution, like this :
Enter animation not playing in Angular
I have an image built from multiple css sprites, as described in this question: css image building with sprites
How would I use that so that I could apply a size on the top container that would dynamically re-size all the children?
here is the working fidlle so far: http://jsfiddle.net/hWhUb/3/
here is the current html structure:
<div class="icon">
<div class="brigade brigade-purple-left"> </div>
<div class="brigade brigade-purple-middle"> </div>
<div class="brigade brigade-purple-right"> </div>
<div class="icon-type icon-hero"> </div>
</div>
I have a few questions, that might lead to a solution:
Why are you using multiple images for something that can be easily achieved using a bit of css3 and a single image (the cross thingie)? A single image can more easily be resized, as a percentage of the container width, or even using css3 background-size property.
If you must use images for each thing, could you possibly consider never using sprites, ever? Its maintainability is pure annoyance, especially if someone has to take the project away from you later on.
Perhaps a combination of both?
If you choose the second option, I suggest using data uris.
Here's a short explaination:
http://css-tricks.com/data-uris/
It saves one more http request than sprites, easier to maintain, and the difference in overall size is rather insignificant in my honest opinion, and support is great - IE8+ and all sane browsers our there.
Setting up is easy enough, especially if you use the all-mighty sass interpreter, but there are some nifty utils out there (command-line, gui or even web-based) to transform your images into base64.
It can even support IE7 with a little effort!
Edit 3.11.12
You can also add http://css3pie.com/ to the options to check out - it lets you do the css3 tricks we so love and adore with internet explorer. It's a bit unpredictable to my taste, but for a small feat like this it can definitely do the trick.
Further, I commented on your browser-support needs below. IE7 is not what's going to stop you;)
You can use a combo of zoom for webkit/ie and -moz-transform:scale for Firefox
[class^="icon-"]{
display: inline-block;
background: url('../img/icons/icons.png') no-repeat;
width: 64px;
height: 51px;
overflow: hidden;
zoom:0.5;
-moz-transform:scale(0.5);
-moz-transform-origin: 0 0;
}
.icon-huge{
zoom:1;
-moz-transform:scale(1);
-moz-transform-origin: 0 0;
}
.icon-big{
zoom:0.60;
-moz-transform:scale(0.60);
-moz-transform-origin: 0 0;
}
.icon-small{
zoom:0.29;
-moz-transform:scale(0.29);
-moz-transform-origin: 0 0;
}
One of the ways to achieve it will be to use inline CSS and to dynamically generate attribute values in JavaScript or PHP/What you use.
Assuming you know the width of the top container and the position of the css sprites
Calculate the left middle and right
You can also opt to generate the CSS code in a separate file
http://aquagraphite.com/2011/11/dynamically-generate-static-css-files-using-php/
Using a bit of jQuery I can make the elements resize to whatever you want (resizeTo):
$(document).ready(function () {
$('#resize').click(function (e) {
e.preventDefault();
var resizeTo = 100,
resizeRatio = Number(resizeTo) / Number($(".icon").width());
$(".icon").css('width', resizeTo);
$(".child").each(function () {
var childWidth = Number($(this).width()),
childHeight = Number($(this).height()),
newChildWidth = childWidth * resizeRatio,
newChildHeight = childHeight * resizeRatio;
$(this).css({ 'width': newChildWidth, 'height': newChildHeight });
});
});
});
However, size doesn't resize the sprites to fit the new box sizes so seems like a pointless task.
Fiddler: http://jsfiddle.net/hWhUb/4/
Though what you want to do can be accomplished, I think your approach is wrong. It's way more complicated than it needs to be, but the idea is sound.
Looking at your sprite, the only thing that can't be changed with CSS is the actual icons (the artwork). The rounded corners and background colors -- that's a different story.
CSS
.icon-cross {
background:purple url('cross.jpg') no-repeat 40px 12px;
border-radius:5px;
border:1px solid gray
}
#media only screen and (max-width:768px) {
.icon-cross {
background-size: 800px 1200px;
background-position; ??px ??px
}
}
#media only screen and (max-width:400px) {
.icon-cross {
background-size: 500px 900px;
background-position; ??px ??px
}
}
HTML
<div class="icon-cross"></div>
You can use css3 2d transforms:
.icon {
transform: scale(2);
-ms-transform: scale(2); /* IE 9 */
-webkit-transform: scale(2); /* Safari and Chrome */
-o-transform: scale(2); /* Opera */
-moz-transform: scale(2); /* Firefox */
}
and change the transform origin with: transform-origin
How can I zoom an HTML element in Firefox and Opera?
The zoom property is working in IE, Google Chrome and Safari, but it’s not working in Firefox and Opera.
Is there any method for adding this property to Firefox and Opera?
Try this code, this’ll work:
-moz-transform: scale(2);
You can refer to this.
Zoom and transform scale are not the same thing. They are applied at different times. Zoom is applied before the rendering happens, transform - after. The result of this is if you take a div with width/height = 100% nested inside of another div, with fixed size, if you apply zoom, everything inside your inner zoom will shrink, or grow, but if you apply transform your entire inner div will shrink (even though width/height is set to 100%, they are not going to be 100% after transformation).
For me this works to counter the difference between zoom and scale transform, adjust for the intended origin desired:
zoom: 0.5;
-ms-zoom: 0.5;
-webkit-zoom: 0.5;
-moz-transform: scale(0.5,0.5);
-moz-transform-origin: left center;
Use scale instead! After many researches and tests I have made this plugin to achieve it cross browser:
$.fn.scale = function(x) {
if(!$(this).filter(':visible').length && x!=1)return $(this);
if(!$(this).parent().hasClass('scaleContainer')){
$(this).wrap($('<div class="scaleContainer">').css('position','relative'));
$(this).data({
'originalWidth':$(this).width(),
'originalHeight':$(this).height()});
}
$(this).css({
'transform': 'scale('+x+')',
'-ms-transform': 'scale('+x+')',
'-moz-transform': 'scale('+x+')',
'-webkit-transform': 'scale('+x+')',
'transform-origin': 'right bottom',
'-ms-transform-origin': 'right bottom',
'-moz-transform-origin': 'right bottom',
'-webkit-transform-origin': 'right bottom',
'position': 'absolute',
'bottom': '0',
'right': '0',
});
if(x==1)
$(this).unwrap().css('position','static');else
$(this).parent()
.width($(this).data('originalWidth')*x)
.height($(this).data('originalHeight')*x);
return $(this);
};
usege:
$(selector).scale(0.5);
note:
It will create a wrapper with a class scaleContainer. Take care of that while styling content.
I would change zoom for transform in all cases because, as explained by other answers, they are not equivalent. In my case it was also necessary to apply transform-origin property to place the items where I wanted.
This worked for me in Chome, Safari and Firefox:
transform: scale(0.4);
transform-origin: top left;
-moz-transform: scale(0.4);
-moz-transform-origin: top left;
zoom: 145%;
-moz-transform: scale(1.45);
use this to be on the safer side
Only correct and W3C compatible answer is: <html> object and rem. transformation doesn't work correctly if you scale down (for example scale(0.5).
Use:
html
{
font-size: 1mm; /* or your favorite unit */
}
and use in your code "rem" unit (including styles for <body>) instead metric units. "%"s without changes. For all backgrounds set background-size. Define font-size for body, that is inherited by other elements.
if any condition occurs that shall fire zoom other than 1.0 change the font-size for tag (via CSS or JS).
for example:
#media screen and (max-width:320pt)
{
html
{
font-size: 0.5mm;
}
}
This makes equivalent of zoom:0.5 without problems in JS with clientX and positioning during drag-drop events.
Don't use "rem" in media queries.
You really doesn't need zoom, but in some cases it can faster method for existing sites.
I've been swearing at this for a while. Zoom is definitely not the solution, it works in chrome, it works partially in IE but moves the entire html div, firefox doesnt do a thing.
My solution that worked for me was using both a scaling and a translation, and also adding the original height and weight and then setting the height and weight of the div itself:
#miniPreview {
transform: translate(-710px, -1000px) rotate(0rad) skewX(0rad) scale(0.3, 0.3);
transform-origin: 1010px 1429px 0px;
width: 337px;
height: 476px;
Obviously change these to your own needs. It gave me the same result in all browsers.
It does not work in uniform way in all browsers.
I went to to: http://www.w3schools.com/html/tryit.asp?filename=tryhtml_pulpitimage and added style for zoom and -moz-transform. I ran the same code on firefox, IE and chrome and got 3 different results.
<html>
<style>
body{zoom:3;-moz-transform: scale(3);}
</style>
<body>
<h2>Norwegian Mountain Trip</h2>
<img border="0" src="/images/pulpit.jpg" alt="Pulpit rock" />
</body>
</html>
try this code to zoom the whole page in fireFox
-moz-transform: scale(2);
if I am using this code, the whole page scaled with y and x scroll not properly zoom
so Sorry to say fireFox not working well using "-moz-transform: scale(2);"
**
Simply you can't zoom your page using css in fireFox
**
does this work correctly for you? :
zoom: 145%;
-moz-transform: scale(1.45);
-webkit-transform: scale(1.45);
scale(1.45);
transform: scale(1.45);
For me this works well with IE10, Chrome, Firefox and Safari:
#MyDiv>*
{
zoom: 50%;
-moz-transform: scale(0.5);
-webkit-transform: scale(1.0);
}
This zooms all content in to 50%.