user3360547
user3360547

Reputation: 163

CSS transitions: Strange unwanted delay in Webkit browsers (Chrome and Safari)

I was hoping someone could help explain the strange behaviour I'm experiencing in Webkit browsers with unwanted delays in CSS transitions.

Here is a link to the page I'm working on: http://demo.daised.com/help-me

The desired outcome is for the menu bar to shrink as the user scrolls down the page. This animates perfectly in Firefox.

However, in Webkit browsers the transition for font-size of the nav items is delayed by 6(!) seconds.

Thanks for helping me understand this better.

Upvotes: 16

Views: 15878

Answers (5)

Herobrine
Herobrine

Reputation: 3153

Came accross this issue as I had the same bug.

I had this in my CSS :

:root {
    --duration-fast: 0.2s ease-in-out;
}

* {
    transition: color var(--duration-fast),
    border-color var(--duration-fast),
    border var(--duration-fast),
    transform var(--duration-fast),
    opacity var(--duration-fast),
    margin var(--duration-fast),
    box-shadow var(--duration-fast),
    text-shadow var(--duration-fast);
}

Turned out it wasn't such a great idea... Here's how I fixed it:

:root {
    --duration-fast: 0.2s ease-in-out;

    --transition-fast: color var(--duration-fast),
    border-color var(--duration-fast),
    border var(--duration-fast),
    transform var(--duration-fast),
    opacity var(--duration-fast),
    margin var(--duration-fast),
    box-shadow var(--duration-fast),
    background var(--duration-fast),
    text-shadow var(--duration-fast);
}

Now, when I want to have an element with transitions (without specifying all of them), I just do this:

.my-component {
    transition: var(--transition-fast);
}

Upvotes: 0

Michael Lynch
Michael Lynch

Reputation: 3139

I ran into the same problem. My issue was that I was trying to transition properties that were originally being inherited from a parent. It turns out Webkit browsers (not Firefox) require each property that you're transitioning to actually be applied to that element. It seems they cannot transition properties that have been inherited.

For example, I was trying to do this:

HTML

<div class="parent">
    <div class="child"></div>
</div>

CSS

.parent {
    color: #000;
}

.child {
    transition: background-color 0.2s ease 0s, color 0.2s ease 0s;
    border-top: 10px #000 solid;
 }

.child.active {
    border-color: #ff0000;
    color: #ff0000;
}

Firefox managed to accomplish this but both Chrome and Safari required this:

.child {
    transition: background-color 0.2s ease 0s, color 0.2s ease 0s;
    border-top: 10px #000 solid;
    // even though the color property is inherited,
    // webkit requires it for transitions
    color: #000;
 }

Upvotes: 5

Lawrence_NT
Lawrence_NT

Reputation: 506

The issue is caused by stacked transitions on elements that inherit the transition property.

a, span {
  transition: 0.5s;
}

a {
  padding: 0.5em 0.75em;
  border: 1px solid red;
  color: #000;
  display: inline-block;
}

a:hover{
  color: #f00;
  background-color: #0f0;
}
<a>
  <span>Text Content</span>
</a>

The section of css a, span applies the transition to both elements. The span inherits the color from the a, but does not apply the animation color until the a has finished its animation.

The best fix for the above example would be to remove the rule for a, span and place transition: 0.5s; inside the rule for a:

a {
  transition: 0.5s;
  padding: 0.5em 0.75em;
  border: 1px solid red;
  color: #000;
  display: inline-block;
}

a:hover{
  color: #f00;
  background-color: #0f0;
}
<a>
   <span>Text Content</span>
</a>

Upvotes: 16

Tom
Tom

Reputation: 5121

Another reason for unwanted delays is with overflow: hidden;. If you have a dropdown toggle navbar for example: When it is toggled open, and the max-height is set to 1000px, whilst also having the CSS property overflow: hidden;, it will take longer to transition from its max-height to closed.

Upvotes: 3

kursus
kursus

Reputation: 1404

user3360686 is right, your transitions are somehow stacked. I'm not sure why it happens as it's not supposed to.

Anyway what you've done in the header is dangerous, and may trigger weird behaviors :

header * {
  transition: all 0.8s;
  -moz-transition: all 0.8s; 
  -webkit-transition: all 0.8s;
  -o-transition: all 0.8s;

  transition-delay: 0.2s;
  -moz-transition-delay: 0.2s;
  -webkit-transition-delay: 0.2s;
  -o-transition-delay: 0.2s;
}

You have about 25 elements in your header, transitions and delays will be applied to each of them. Use specific elements for more efficiency (and elegance).

Using "all" with transition is generally a bad idea, they are a good means to create conflicts. Use specific properties.

This quick and nice answer sums up pretty much everything : CSS3, WebKit Transition Order? How to queue to the transitions?

Upvotes: 7

Related Questions