Mobile Menu is being stretched by Firefox and Safari - css

I have a mobile menu that is supposed to disappear when users scroll. I did work out all fine, but now I have a problem that boggles my mind. I am using headroom.js to make the menu disappear and reappear. For the headroom element, I have defined some css classes. The whole thing is embedded in a Joomla Template.
Now, on Firefox Mobile as well as Safari (iPhone Browser), I get this weird behavior that header classes are stretched to 1500px width, a value that is never defined anywhere in my css files. When I let Chrome do a simulation of Mobile Viewport, everything works out the way it should.
My html:
…
<header class="headroom" id="main-header-navi-headroom">
<nav id="nav-main" class="navbar navbar-default" style=" background-color: #fff;">
<div class="navbar-header">
<!-- a button to toggle navbar-collapse goes here -->
</div>
<div class="collapse navbar-collapse" id="collapsible-menu">
<!-- all my menu points are being summoned here -->
</div>
</nav>
</header>
…
My template.css
.headroom {
position: sticky;
top: 50px;
left: 0;
right: 0;
transition: all .6s ease-in-out !important;
z-index: 900;
}
.headroom--unpinned {top: -150px;}
.headroom--pinned {top: 50px;}
My template_responsive.css:
#media (max-width: 1179px) {
.headroom {
position: fixed;
top: 50px;
left: 0;
right: 0;
margin-top: 0;
max-height: calc(var(--vh, 1vh) * 100);
overflow-y: auto;
-webkit-transition: -webkit-transform 300ms ease-out;
transition: -webkit-transform 300ms ease-out;
-o-transition: -o-transform 300ms ease-out;
transition: transform 300ms ease-out;
transition: transform 300ms ease-out, -webkit-transform 300ms ease-out, -o-transform 300ms ease-out;
will-change: transform;
z-index: 9998;
}
.headroom--pinned {
top: 50px;
position: sticky;
}
.headroom--frozen {
top: 0 !important;
}
a.reduced-z {
z-index: 9997 !important;
}
.headroom--unpinned {
-webkit-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
top: 0;
}
}
What I've tried: I tried to add a max-width: 100%; property to the headroom class, to no avail. Also, in my template there is another <nav> element that has max-width set to 100%, but it gets still rendered to a width of 1500 pixels.
What confuses me are two things:
There is no class or identifier in my whole css that has their width set to 1500px. I first thought that maybe that prop somehow oozed to my menu element. But since there is none, I do not understand how Firefox comes up with that width.
If I just scale a regular Firefox window on my Desktop Computer, everything works fine. Just the mobile preview or an actual mobile device produce the hiccups described.
Any ideas on why that problem occurs and how to fix it?

Related

Firefox heavy lag when using transform: translateX() in a transition

What I have is an offcanvas nav that moves the entire page once opened.
It looks like this:
.offcanvas {
position: fixed;
padding-left: calc($unit * 8);
z-index: 3;
height: 100%;
width: 420px;
top: 0;
right: 0;
background: $color-secondary;
overflow-x: hidden;
transform: translateX(420px);
will-change: transform;
transition: transform .2s ease-in-out;
}
When a button is clicked it gets a class modifier through jquery which moves it inside the window:
&--opened {
will-change: transform;
transform: translateX(0);
}
Content is wrapped in main which also gets moved once the nav is opened:
.main {
will-change: transform;
transition: transform .2s ease-in-out;
&__moved {
will-change: transform;
transform: translateX(-420px);
}
}
It works just fine in every major browser except Firefox (54.0.1), tested on Windows and OSX. The transition is extremely laggy both when opening and closing the menu. I tried adding will-change: transform; but the issue is still there. I've tried using translate3d and left/right, but those didn't help.
Has anyone experienced these issues and what have you done to solve them?
Thanks!

picture with border-radius 50% and transform(scale)

I have a sqare image wich is turned into a circle by using border-radius: 50%; That works quite well so far. ;) But the next step is difficult to do: I want the image to zoom "nearer" by using transform: scale. I mean: I dont want to change the same size of the image, it should stay with the same diameter. But I want to show a small section of the image. The zooming should be activated on :hover and it should be processed during a period of 0.8s
My code works perfectly in Firefox, but in Chrome and Safari it does not. Where are my mistakes?
My HTML:
<div class="hopp_circle_img">
<img src="... alt="" />
</div>
My CSS:
.hopp_circle_img {
width: 100% !important;
height: 100% !important;
max-width: 100% !important;
max-height: 100% !important;
overflow: hidden;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
}
.hopp_circle_img img {
transition: all 0.8s;
-moz-transition: all 0.8s;
-webkit-transition: all 0.8s;
-o-transition: all 0.8s;
-ms-transition: all 0.8s;
}
.hopp_circle_img img:hover {
display: block;
z-index: 100;
transform: scale(1.25);
-moz-transform: scale(1.25);
-webkit-transform: scale(1.25);
-o-transform: scale(1.25);
-ms-transform: scale(1.25);
}
The problems:
1) Chrome: The "zoom" works, but during the transition-time (o,8s) the image has sqare borders. After the trasition took place, they are rounded.
2) Safari:
The transition-time is ignored, transition takes place immediately, without "soft" zooming.
3) IE: I did not dare to take a look at IE, if it does not even work in Safari and Chrome. ;)
Thanks for your ideas. I tried many different things, none of them worked.
Raphael
With Harry's suggestion to fix the square, this one should work in Safari as well.
First, prefixed properties should be before unprefixed, second, don't use all as in
transition: all ...
name the properties to be transitioned, in this case
transition: transform 0.8s
Note, you need to add back the rest of the prefixed properties
.hopp_circle_img {
position: relative; /* new property added */
width: 100% !important;
height: 100% !important;
max-width: 100% !important;
max-height: 100% !important;
overflow: hidden;
-webkit-border-radius: 50%;
border-radius: 50%;
z-index: 0; /* new property added */
}
.hopp_circle_img img {
-webkit-transition: transform 0.8s; /* re-ordered property, named */
transition: transform 0.8s; /* what to be transitioned */
}
.hopp_circle_img img:hover {
display: block;
z-index: 100;
-webkit-transform: scale(1.25);
transform: scale(1.25);
}
<div class="hopp_circle_img">
<img src="http://lorempixel.com/400/400/nature/1" alt="" />
</div>
OK, I have a first success:
Changing .hopp_circle_img img:hover into .hopp_circle_img:hover fixed the problem in Safari. But it still remains in Chrome.
What fixed this issue for me was:
.hopp_circle_img {
transform: scale(.99);
}

Transform scale working on Chrome but not on Firefox

Once I start animating, on Chrome I get a ripple effect. My circle transform scales up. On Firefox, that exact same animation is ignored for some reason.
$("#animate").click(function() {
$("#square").toggleClass("animate");
$("#fab").toggleClass("ripple");
});
#keyframes ripple {
from {
transform: scale(0)
}
to {
transform: scale(20)
}
}
#square {
position: relative;
width: 300px;
height: 300px;
overflow: hidden;
border: 1px solid red;
transition: background 0.1s linear 0.6s, transform 1s;
transform: rotate(0deg);
}
#fab {
position: absolute;
width: 56px;
height: 56px;
border-radius: 50%;
background: #4FB5AB;
top: 122px;
right: 0;
transform: scale(1);
transition: transform 1s;
}
.ripple {
animation: ripple 1s 0.5s;
transform: scale(20) !important;
/*Duration - delay */
transition: transform 0s 1s !important;
}
.animate {
transform: rotate(90deg) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="square">
<div id="fab"></div>
</div>
<br />
<button id="animate">animate</button>
CodePen Demo
Before I start explaining the problem with your code, here is a word of caution - Do not use transitions and animations together. They generally end up causing problems like the one faced here.
When an animation is specified on an element, it will take complete control over the properties that are being animated unless there is a rule with !important setting. If !important setting is used then that rule takes precedence over the animation. (but unfortunately Chrome and Firefox seem to be handling this case differently).
As per W3C Spec:
CSS Animations affect computed property values. During the execution of an animation, the computed value for a property is controlled by the animation. This overrides the value specified in the normal styling system. Animations override all normal rules, but are overriden by !important rules.
emphasis is mine
In your code, there were two problems and they are as follows:
Within .ripple selector, you were specifying the transition-duration as 0s, which means, there is no transition at all and that the change of transform is an instant one. As explained in the W3C Spec, Firefox seems to be (correctly) giving the control to the rule with !important setting (that is, the transform and transition within .ripple selector) and so it transitions the state change immediately after the specified 1s delay+. Chrome lets animation take control and thus produces the effect you are looking for.
Firefox seems to animate the element quicker than Chrome does and so while a duration of 1s is enough for the animation in Chrome, FF needs it to be 2s to be slower and show the effect.
+ - You can further verify this by removing the !important settings on the rules. Once !important is removed, the animation would take control.
$("#animate").click(function() {
$("#square").toggleClass("animate");
$("#fab").toggleClass("ripple");
});
#keyframes ripple {
from {
transform: scale(0)
}
to {
transform: scale(20)
}
}
#square {
position: relative;
width: 300px;
height: 300px;
overflow: hidden;
border: 1px solid red;
transition: background 0.1s linear 0.6s, transform 1s;
transform: rotate(0deg);
}
#fab {
position: absolute;
width: 56px;
height: 56px;
border-radius: 50%;
background: #4FB5AB;
top: 122px;
right: 0;
transform: scale(1);
transition: transform 1s;
}
#fab.ripple {
animation: ripple 2s 1s;
transform: scale(20);
/*Duration - delay */
transition: transform 1s 1s;
}
#square.animate {
transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="square">
<div id="fab"></div>
</div>
<br />
<button id="animate">animate</button>
Finally, please do not use !important unless it is mandatory. Instead just make the selector more specific. In the snippet, I have made it more specific by using the #id.class format.

Keyframe CSS animation overwrites hover transition

I am afraid there are similar questions to this but I didn’t found a concrete solution, so I created a fiddle:
http://jsfiddle.net/Garavani/yrnjaf69/2/
<div class= "category_item">
<div class= "cat_button">
<span class="title_cat">TEXT</span>
</div>
</div>
CSS:
.category_item {
position: absolute;
background-color: #999;
top: 100px;
left: 50px;
width: 200px;
height: 200px;
/* seems to be overwriten by animation keyframes */
-webkit-transition: -webkit-transform 0.215s ease-in-out;
transition: transform 0.215s ease-in-out;
cursor: pointer;
}
.category_item:hover {
-webkit-animation-name: easeBack;
animation-name: easeBack;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes easeBack {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
50% {
-webkit-transform: translateY(-50px);
transform: translateY(-50px);
}
100% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
}
.cat_button {
position: absolute;
width: 200px;
height: 55px;
bottom: 0;
border: 2px solid #fff;
color: #fff;
-webkit-transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
}
.category_item:hover .cat_button {
background: #fff;
border-color: #fff;
color: #511c5b;
}
In this (simplified) animation everything works fine except for when the mouse leaves the entire box. The animation starts from it original state, but abruptly.
The basic transition time (and ease) is ignored because it seems the keyframes have higher importance and overwrite it.
What I need is the keyframe animation triggering AND when the mouse leaves it should turn back to the original state smoothly.
Is there a solution for this
1) in pure CSS
2) maybe with some little javascript only?
Thanks in advance for help and ideas!
EDIT:
After implementing the solution offered kindly by Toni this is the correct fiddle:
http://jsfiddle.net/yrnjaf69/40/
Thanks again Toni!
EDIT 2:
Sadly, yet, there is one question left. The part with the keyframes is not executed on Firefox even though I added all the -moz- vendors, too, in this fiddle:
http://jsfiddle.net/dr6Ld0wL/1/
Why?
PS: As far as I tested for now it works even in Opera (Beta). Only browser resisting is Firefox
EDIT 3:
The correct (working) code is now in this fiddle:
http://jsfiddle.net/dr6Ld0wL/16/
The keyframes also need to be explicitly divided in vendor prefixes. Jesus Christ. Those prefixes…
Here is a jsfiddle that achieves this.
.demo-hover {
position: relative;
margin: 100px;
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
.demo-hover:hover {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
#keyframes complexProcess {
/* keyframes */
}
#keyframes complexProcessReversed {
/* keyframes (opposite) */
}
The animation out is assigned in the css in the main class, then the hover state kicks in on hover and css re-applies the original class properties on unhover.
The animation does trigger backwards on page load, so you might like to think of tweaking your animation to take this into account, like this example, pinched from this answer. Alternatively, use javascript (or jquery), like this example where the animations are triggered by adding and removing classes to the target using jquery:
JavaScript
$('.demo-hover').hover(
function() {
// mouse in
$(this).removeClass('forwards--reversed').addClass('forwards');
},
function() {
// mouse out
$(this).removeClass('forwards').addClass('forwards--reversed');
}
);
CSS
.forwards {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
.forwards--reversed {
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
Also, I'd use #keyframe or transition. Use transition if you just need a simple even change from n to m but when things are more complex, such as one thing changing evenly over 100% but another thing not starting until 50% off the animation has played, then use a #keyframe
Using both will cause confusion, especially if you're trying to animate the same properties.
Finally css vendor prefixes are required

Animating scale using CSS - with multiple backgrounds

I've been trying for days to emulate a video editing effect using CSS3 with no luck. I have two background images (one on top of the other) and want to create an animation where I scale up or zoom the image on top while leaving the background image intact.
I have been able to successfully change the position of the top image while leaving the background intact, and I can also do an animation which scales both foreground and background images at the same time.
Here's some code to make this all a bit more clear:
My HTML:
<section id="about-photo" class = "light-bg img-bg" style = "background-image: url({% static "assets/images/art/cocuy-foreground.png" %}), url({% static "assets/images/art/cocuy-background.jpg" %});">
<div class="container inner">
<div class="row">
</div><!-- /.row -->
</div><!-- /.container -->
</section>
My CSS (only including webkit for sake of brevity)
#-webkit-keyframes hide {
from { background-position: 0px 0px, 0px 0px; }
to { background-position: 0px 300px, 0px 0px; }
}
#-webkit-keyframes zoom {
from {-webkit-transform: scale(1,1), scale(1,1) ;}
to {-webkit-transform: scale(2,2), scale(1,1) ;}
}
#about-photo {
background-repeat: no-repeat;
-webkit-animation-name: zoom;
-webkit-animation-duration: 4s;
-webkit-animation-delay: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
}
When I apply the animation called "hide" things work fine, but when I use "zoom" nothing happens.
Any ideas/tips would be greatly appreciated!
Dennis
Not sure if you actually need to use keyframes for this. You can simply use transition and transform to achieve this. I made a jsFiddle showing how you can do that. Also be aware that you want to include other vendor prefixes so your code works in all browsers.
#about-photo {
position: relative;
}
.light-bg {
width: 1000px;
height: 1000px;
background: url('http://www.broomehovercraft.com.au/graphics/bht/popups/gallery-sunset-6.jpg');
background-repeat: no-repeat;
}
.smiley {
position: absolute;
top: 10%;
left: 20%;
width: 100px;
height: 100px;
z-index: 2;
background: url('http://www.wpclipart.com/smiley/assorted_smiley/assorted_3/smiley_a_bit_angry_T.png');
background-size: 100px 100px;
-webkit-transition: 1s ease-in-out;
-moz-transition: 1s ease-in-out;
-o-transition: 1s ease-in-out;
transition: 1s ease-in-out;
}
.smiley:hover {
-webkit-transform: scale(2);
-moz-transform: scale(2);
-o-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
}
<section id="about-photo" class="light-bg img-bg">
<div class="smiley"></div>
<!-- /.container -->
</section>
http://jsfiddle.net/augburto/44sbrooy/
The main thing to note is that on the element you wish to have a "zoom effect", you want to apply a transition so it knows that when a transform is applied to it, it will do it smoothly (if you don't have this, then it will do the action immediately.
Right now I have it so when you hover over the smiley, it will scale with a transform. However, you can easily change this to a class that you can apply. As long as your element has a transition, it will create that nice "zoom-in" effect. Then the actual scaling of the image can be applied to a separate class which you can apply whenever.
For more documentation on transitions, check out MDN.
If you really want to use keyframes, then update your question, but in my eyes it isn't necessary in this situation.

Resources