I am creating a sticky header and it works fine but my problem is on "jump" when someone scroll down the page jumping some pixels and has no smoothness. I find some similar topics but I can not make it work for my website,
var navbar = document.getElementById("my_header");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.pageYOffset >= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}
window.onscroll = function() {myFunction()};
.sticky {
position: fixed;
top: 0;
width: 100%;
z-index:999;
padding:18px 0 0 0;
-webkit-transition: all 1.3s;
-moz-transition: all 1.3s;
-ms-transition: all 1.3s;
-o-transition: all 1.3s;
transition: all 1.3s;
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.75s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="topnavbar"></div>
<div id="my_header" style="width:1150px; background: #181818;">
<div style="width: 100%;margin: -18px auto 0; padding: 0;">
<div id="header"></div>
</div>
</div>
<div id="content"> ... </div>
you can find the demo at JSFIDDLE too.
my website is oipeirates.tv
Thank you in advance.
Check this This is a ready solution :)
Let's get rid of this unnecessary transitions. Do you want to achieve this effect?
.sticky {
position: fixed;
top: 0;
width: 100%;
z-index:999;
padding:18px 0 0 0;
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.75s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
http://jsfiddle.net/oipeirates/y41f98dg/39/
Specify what you want to animate, change transition: all 1.3s; to transition: opacity 1.3s;. Now the padding:18px 0 0 0; will not be animated, and the jumping behavior of the sticky header will be prevented.
JSFiddle : http://jsfiddle.net/y41f98dg/54/
i dont have problem to remove the transition or animation i just want to make it smooth with no jumping. but im totally tilted im trying so much days and i cant do this :/
Related
I am making a label pop up for the user, if the user tries to drag and drop an element that has already been dragged.
Problem is, that the animations only happens once, and at the end of the animation, it will have an opacity of 0 forever.
CSS
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
position: absolute;
z-index: 999;
display: none;
opacity: 0;
-webkit-animation: smooth 2s ease-in;
-moz-animation: smooth 2s ease-in;
-o-animation: smooth 2s ease-in;
-ms-animation: smooth 2s ease-in;
animation: smooth 2s ease-in;
}
To illustrate my problem, if I 'end' the animation on opacity: 0.2 instead of opacity: 0:
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0.2;}
}
... then the label will reappear for each event - but it will not fade out again, which I want to do.
You can put the animation rule in a specific css class rule, and then on clicking add that class again. Just keep these points in mind:
You need to remove the animation class first before adding it again to have any effect.
Even if you follow first point, removing the class and adding it back right then won't have any visual effect. To trigger reflow, you can use this statement: void targetDiv.offsetWidth;.
document.querySelector("#start-animation").onclick = function(e){
var targetDiv = document.querySelector("#mydiv");
targetDiv.className = "";
void targetDiv.offsetWidth; // this triggers UI reflow
targetDiv.classList.add("o_tip");
}//onclick
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
z-index: 999;
animation: smooth 2s ease-in forwards;
}
#mydiv{
background-color: yellow;
height: 50px;
width: 100px;
}
#mydiv.o_top{
display: block;
}
<div id="mydiv"></div>
<button id="start-animation">Start animation</button>
So I have got different animations made in CSS, though the problem is that they start right away when the page loads (ofcourse). I do not want this though. Is there a way in Vanilla JavaScript to get the animation to fire up only when it is in the viewport?
I have searched in a lot of places, but I either find a plugin I need to use or jQuery.
HTML:
<div class="introduction">
<h1>I can do the following for you:</h1>
<ul>
<li>Create a custommade, new website.</li>
<li>Code a PSD template into a working website.</li>
<li>Rework an outdated website.</li>
<li>Clean up messy code of a website.</li>
</ul>
</div>
CSS:
#keyframes showOnLoad {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.introduction li {
list-style-type: none;
margin-bottom: 5px;
text-align: center;
opacity: 0;
-webkit-animation: showOnLoad;
animation: showOnLoad;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.introduction li:nth-child(2) {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.introduction li:nth-child(3) {
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.introduction li:nth-child(4) {
-webkit-animation-delay: 3s;
animation-delay: 3s;
}
This is the code you need.
window.addEventListener("scroll", onScroll);
function onScroll() {
for (var item of document.querySelectorAll(".introduction li")) {
elementVisible(item);
}
}
function elementVisible(el) {
let top = el.offsetTop;
let height = el.offsetHeight;
let bottom = top + height;
let IsOverBottom = top > (window.pageYOffset + window.innerHeight);
let IsBeforeTop = bottom < window.pageYOffset;
if (!IsOverBottom && !IsBeforeTop) {
el.classList.add("show");
}
}
And a bit of CSS
#keyframes slideIn {
0% {
opacity: 0;
transform: translateX(100%);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
.show {
animation: slideIn 5s ease-in-out;
}
This is a basic implementation but it gets you closer.
http://jsbin.com/hetapaj/1/edit?css,js,output
So, I have created a CSS3 animation that is supposed to fade out an element by setting its opacity from 1 to 0 and at the last frames change the position to absolute and display to none. But on Safari it will only maintain the opacity, position and display are not set to the final values.
#-webkit-keyframes impressum-fade-out {
0% {
opacity: 1;
display: block;
position: relative;
}
99% {
opacity: 0;
position: relative;
}
100% {
opacity: 0;
display: none;
position: absolute;
}
}
It seems to work on Chrome but not on Safari (I tried version 8). Apparently, position and display do not work properly with animation-fill-mode: forwards...
JSFiddle: http://jsfiddle.net/uhtL12gv/
EDIT For Bounty: I am aware of workarounds with Javascript and transitionend events. But I am wondering why Browsers lack support for this? Does the specification state that fillmode forwards doesnt apply to some attributes like position or is this a bug in the browsers? Because I couldnt find anything in the bug trackers.. If anybody has some insight, I would really appreciate it
As Suggested in the comments, you can adjust the height.
EDIT: Animation Reference Links Added.
Display property is not animatable.
Position property is not
animatable.
List of all CSS properties and if and how they are
animatable.
$('.block').click(function() { $(this).toggleClass('active') });
#-webkit-keyframes impressum-fade-out {
0% {
opacity: 1;
}
99% {
opacity: 0;
}
100% {
opacity: 0;
height:0;
}
}
.block {
width: 100px;
height: 100px;
background: blue;
}
.block2 {
width: 100px;
height: 100px;
background: red;
}
.block.active {
-webkit-animation-name: impressum-fade-out;
animation-name: impressum-fade-out;
-webkit-animation-duration: 500ms;
animation-duration: 500ms;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="block"></div>
<div class="block2"></div>
I would suggest you the cross-browser solution based on CSS3 Transitions and transitionend event:
JSFiddle
$('.block').one('click', function() {
var $this = $(this);
$this.one('webkitTransitionEnd transitionend', function() {
$this.addClass('block_hidden');
$this.removeClass('block_transition');
});
$this.addClass('block_transition');
});
.block {
width: 100px;
height: 100px;
background: blue;
-webkit-transition: opacity 0.5s;
transition: opacity 0.5s;
}
.block_2 {
background: red;
}
.block_transition {
opacity: 0;
}
.block_hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="block"></div>
<div class="block block_2"></div>
I am trying to animate a div element (slide and fade) with a button click. At first, the element is not visible to a user. When the button is clicked, it will slide to right and fade in. Once the button is clicked again, it will slide to left and fade out. I come up with two solutions, with css and with JQuery.
In the first one, I used JQuery. You can find the example in this JSFiddle 1.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 1;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.stop(true, true).animate({
left: "toggle",
opacity: "toggle"
}, 1000);
});
Here, everything seems working but it does directly opposite of what I want. It first fades out, and with the second click, it fades in. It is because that the opacity of the element is 1, but if I turn it to 0, nothing happens.
Secondly, I tried to do that with css animation by using key-frames (changing opacity from 0 to 1) but it has also problem. It starts the animation exactly the way I want. However, when I click the button again, it disappears immediately. Here is the JSFiddle 2.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
-moz-transition: all 1s ease;
-webkit-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
.move-my-modal {
-moz-transform: translate(250px, 0px);
-webkit-transform: translate(250px, 0px);
-ms-transform: translate(250px, 0px);
-o-transform: translate(250px, 0px);
}
.animate-opacity {
-webkit-animation: toggle-opacity 1s ease;
-moz-animation: toggle-opacity 1s ease;
-o-animation: toggle-opacity 1s ease;
animation: toggle-opacity 1s ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-moz-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-o-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.toggleClass("move-my-modal");
$modal.toggleClass("animate-opacity");
});
To this end, I have these questions;
1) What are the problems with these two approaches? Is there something that I missed or forgot to use? How can I correct them to meet the requirements that I mentioned at the beginning.
2) Which one is the better way to make this action? Is there any cons or pros of these approaches?
3) Is there any other way to make this action? I am new on this area and I might not notice a simpler way.
You can toggle an .active class to the element and use CSS transitions.
This way, if the browser is old enough to not support animations, it will still work but it won't slow down computers that do not handle animations well.
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal.active {
opacity: 1;
left: 0;
}
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
transition: all 1s linear;
}
#my-modal.active {
opacity: 1;
left: 0;
}
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I want to slide in a fullscreen div from the top using CSS. I am using AngularJS (ionic framework) but attempting to keep this animation pure css. The div won't slide down in Safari (works in Chrome) - it just appears. But it will slide back up properly.Here's the code:
HTML:
<div class="slideDown ng-hide" id="gallery-overlay" ng-show="showGallery" ng-click="hideGalleryClick()"></div>
CSS:
.slideDown{
-webkit-animation-name: slideDown;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease;
visibility: visible !important;
}
#-webkit-keyframes slideDown {
0% {
-webkit-transform: translateY(-100%);
}
100% {
-webkit-transform: translateY(0%);
}
}
.slideUp{
-webkit-animation-name: slideUp;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease;
visibility: visible !important;
}
#-webkit-keyframes slideUp {
0% {
-webkit-transform: translateY(0%);
}
100% {
-webkit-transform: translateY(-100%);
}
}
JS:
$scope.showGalleryClick = function() {
$('#gallery-overlay').removeClass('slideUp');
$('#gallery-overlay').addClass('slideDown');
$scope.showGallery = true;
}
$scope.hideGalleryClick = function() {
$('#gallery-overlay').removeClass('slideDown');
$('#gallery-overlay').addClass('slideUp');
$scope.showGallery = false;
}
Is the problem with translateY(-100%) ?? How can I make this div slide in from the top and slide back up?
Converted to transitions instead of animations.
Fixed ng-click on anchor tag causing page to post by preventDefault().
Converted show/hide to toggle.
function GalleryCtrl($scope) {
$scope.toggleGallery = function($event) {
angular.element(document.querySelector('#gallery-overlay')).toggleClass('slideDown');
$event.preventDefault();
$event.stopPropagation(); /* Not required, but likely good */
};
}
#gallery-overlay {
position: absolute;
top: -100px;
left: 0;
right: 0;
height: 100px;
background-color: #222;
transition: all 1s ease;
}
#gallery-overlay.slideDown {
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="GalleryCtrl">
<div>
Click me to slide panel down
</div>
<div id="gallery-overlay" ng-click="toggleGallery($event)"></div>
</div>
</div>