Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transition for moving objects with position: fixed?

This seems like it should be a simple problem, but I'm by no means a CSS expert, and I've been beating my head against the wall trying to figure it out. So I've got a ContentHeader element, and when the user scrolls down past a certain point, I want it to slide up to cover the NavigationHeader element. I'm changing the position of ContentHeader by changing the className property from "content-header" to "content-header top", which works, but ContentHeader just jumps into the new position instead of transitioning smoothly. This is the CSS I'm using currently:

.content-header {
    position: fixed;
    top: 50;
    width: inherit;
    z-index: 1030;
    padding: 12px 15px 12px 15px;
    transition: top 1s linear;
}
.content-header.top {
    top: 0;
}

If you need to see the JavaScript, let me know and I can add that as well, but it's basically just doing ...

<section className={className} ...

... where the value of className would vary depending on where ContentHeader should be positioned. I thought maybe the problem was that this is happening inside a React render block and that was skipping the transition, but I tried changing the class with an onClick event that wouldn't force a re-render, and the results were the same. If anyone could help, I'd appreciate it!

like image 206
dlwiest Avatar asked Mar 09 '17 23:03

dlwiest


People also ask

Can you transition position in CSS?

CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time.

What is Webkit transition?

-webkit-transition is a non-standard boolean CSS media feature whose value indicates whether vendor-prefixed CSS transition s are supported or not. This media feature is only supported by WebKit. The standards-based alternative is to use a @supports feature query instead.


2 Answers

You're missing px on your top value, which should read top: 50px;

$('button').on('click', function() {
  $('h1').toggleClass('top');
})
.content-header {
  position: fixed;
  top: 50px;
  width: inherit;
  z-index: 1030;
  padding: 12px 15px 12px 15px;
  transition: top 1s linear;
}

.content-header.top {
  top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="content-header">header</h1>
<button>click</button>

That said, I would use transform: translateY(); instead of top because that's more performant. Using a transition or animation with transform get GPU acceleration, where transitioning top does not.

$('button').on('click', function() {
  $('h1').toggleClass('top');
})
.content-header {
  position: fixed;
  transform: translateY(50px);
  width: inherit;
  z-index: 1030;
  padding: 12px 15px 12px 15px;
  transition: transform 1s linear;
}

.content-header.top {
  transform: translateY(0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="content-header">header</h1>
<button>click</button>
like image 135
Michael Coker Avatar answered Oct 21 '22 01:10

Michael Coker


Try giving the initial top value a unit, for example: top: 50px.

.content-header {
    position: fixed;
    top: 50px; // add `px` unit here
    width: inherit;
    z-index: 1030;
    padding: 12px 15px 12px 15px;
    transition: top 1s linear;
}
like image 27
edwarddamato Avatar answered Oct 21 '22 02:10

edwarddamato