CSS keyframe animation not working on div element using opacity - css

I have div .list element with CSS below
.list{
bottom:0;
height:calc(100% - 85px);
left:50%;
max-width:600px;
padding-bottom:85px;
-webkit-transform:translate(-50%,-5%);
z-index:-1;
display:flex;
width:100%;
flex-wrap:wrap;
overflow-x:hidden;
overflow-y:scroll;
position:fixed;
justify-content:center;
opacity:0;
background-color:#f1f1f1;
}
I use JavaScript to add .anim class to this element which contains animation to open .list div element on click open button
document.querySelector('.list').classList.add('anim');
.anim class should animate opening .list using CSS animation.
.anim {
-webkit-animation:openlist 200ms ease forwards;
z-index:2
}
#-webkit-keyframes openlist {
0% {
-webkit-transform:translate(-50%,-5%)
}
to {
-webkit-transform:translate(-50%,0);
opacity:1
}
}
Problem with opacity: when I use Opacity outside CSS animation and put it inside .anim class after animation definition like below:
.anim {
-webkit-animation:openlist 200ms ease forwards;
z-index:2;
opacity:1;
}
.list div is scrollable without any problem but I don't get transition effect from opacity:0 to 1.
If I use opacity inside animation like below:
to {
-webkit-transform:translate(-50%,0);
opacity:1
}
Everything is working fine but .list div is not scrolling and scrollbar is hidden.
HTML
<body class="x">
<input type="search" class="s2" placeholder="Search...">
<div class="s1"></div>
<div class="c1"></div>
<div class="list"></div>
<img src="icons/heart.svg" id="m">
</body>
BODY CSS:
.x {
width:100%;
height:100%;
margin:90px 0;
overflow-x:hidden;
overflow-y:scroll;
}
Question: How to get CSS animation working with opacity inside and keep transition effect plus .list div scrollable?

I found a solution, problem was that i used opacity instead of filter:opacity, now i get opacity effect without scrolling problems

Related

Transitions won't work when transform:translate3d combined with opacity

On my website I have a second header that drifts down from the top when the user scrolls down the page. The original header remains absolutely positioned at the top and is scrolled out of sight as the second slides down.
Due to the Google Chrome bounce scroll effect, if the user scrolls up when the browser is already at the top of the page, they're able to see the second header hanging around outside the document. This looks very strange, and it only happens in Chrome.
I've been trying to make the second header invisible when the user scrolls back to the top and it slides back out of view. I have been attempting to do this with an opacity value of 0 set with an ease value. The problem is, I am using transform:translate3d to animate the slide-up / slide-down effect, and I can't get both opacity and transform to work in the same transition rule.
Ideally I'd like the following to work, but it won't for some reason.
.hidden-header {
position:fixed;
transform:translate3d(0,-100%,0);
background-color:red;
width:100%;
height:55px;
opacity:0;
transition: translate 0.3s, opacity 0s ease .3s;
}
body.header-dropdown .hidden-header {
transform:translate3d(0,0,0);
opacity:1;
transition: translate .5s, opacity 0s;
}
Here is a jsFiddle to show you what I mean – https://jsfiddle.net/wbmm0kL7/2/
At the moment I have had to set it to transition: all .3s which means that the opacity fades in and out as well, which I want to avoid.
Here is a picture of my website with the problem on Chrome I am trying to solve. Notice that the second header and the nav menu are visible when scrolling against the edge of the viewport/document.
Here is the rest of my code:
HTML
<header class="header">REGULAR HEADER</header>
<div class="transform-container">
<div class="hidden-header">HIDDEN HEADER (SLIDES DOWN ON SCROLL)</div>
</div>
<div class="content"></div>
</div>
CSS
html,
body {
height:100%;
width:100%;
margin:0;
padding:0;
}
.wrapper {
background-color:orange;
min-height:100%;
}
.header {
position:absolute;
width:100%;
height:55px;
background-color:pink;
}
.hidden-header {
position:fixed;
transform:translate3d(0,-100%,0);
background-color:red;
width:100%;
height:55px;
opacity:0;
transition: all .3s;
}
body.header-dropdown .hidden-header {
transform:translate3d(0,0,0);
opacity:1;
transition: all .5s;
}
.content {
height:2000px;
}
jQuery
jQuery(document).ready(function($) {
$(window).scroll(function() {
if ($(this).scrollTop() > 200) {
$('body').addClass('header-dropdown');
} else {
$('body').removeClass('header-dropdown');
}
});
});
As per my comment, you have a typo in your CSS transitions rule. You cannot transition individual transform components. Instead, use transition: transform 0.5s; for example.
To achieve the effect of the hidden header appearing immediately, you set the transition duration of opacity to 0s when .header-dropdown is added. To achieve the effect of the hidden header hiding after the transform is done transitioning, you set the transition delay of opacity to the transition duration used:
.hidden-header {
position:fixed;
transform:translate3d(0,-100%,0);
background-color:red;
width:100%;
height:55px;
/* Delay opacity transition when returning to ground state */
transition: transform 0.5s, opacity 0s 0.5s;
opacity: 0;
}
body.header-dropdown .hidden-header {
transform:translate3d(0,0,0);
opacity: 1;
transition: transform 0.5s 0s, opacity 0s;
}
See your fixed fiddle here: https://jsfiddle.net/teddyrised/wbmm0kL7/3/
Note that the first numeric value of the transition shorthand is always the transition-duration, while the second numeric value is the transition-delay

Overflow hidden not working for absolutely positioned elements

I'm trying to replicate the google's ripple effect in jquery + css.
It simply append a circular div inside buttons or divs, and when I click on the container, it applies a scale() animation to the circle.
I apply to the container (the button) the "ripple" class with position:relative and overflow:hidden, while on the circular div position:absolute
At the moment it works well for buttons, but for divs the overflow is not respected and the circle flows outside it.
button, .button {
padding:0.8em 1em;
border:none;
background:#09F;
color:#fff;
border-radius:0.5em;
cursor:pointer;
}
.ripple {
display:inline;
user-select: none;
position: relative;
overflow:hidden;
outline: none;
-webkit-transform: rotate(0.000001deg);
}
.effetto_ripple {
position:absolute;
border-radius:50%;
background-color:rgba(255,255,255,0.4);
transform:scale(0) translateZ(0);
}
.effetto_ripple.animato {
animation:ripple 0.6s ease-out;
}
#keyframes ripple {
0% {
transform: scale(0);
opacity:0.9;
}
100% {
transform: scale(2.5);
opacity:0;
}
}
This is the complete working code http://codepen.io/anon/pen/zvXKgz
Overflow is not settalbe on inline elements, change .ripple to inline-block. This will keep it inline, but you will be able to style it like a block element.

How do I stop CSS transitions from running the first time?

My site's menu changes to an off-canvas menu when the screen width is < 768px. The menu can then be triggered by a click, and it translates in and out using a CSS transition.
The problem is when a browser is > 768px, then gets resized to < 768px. The menu quickly transitions out instead of initially being off-canvas.
You can see an example here: http://codepen.io/anon/pen/RPoQzO (Code below)
Make the preview section really wide, and you'll see the white box fill the width
Resize the section narrow and you'll see it slide out. I don't want that - I just want it to be instantly gone.
Clicking on the green area, you'll see the desired transition effect.
(This is, of course a bastardized representation, but it exemplifies the problem)
I want to solve this (if possible) with just CSS. I don't want to add a Javascript listener for resizing. I'd rather have the effect continue, than use Javascript.
Edit: Here's the code:
<div id="menu">
This is the menu
</div>
And the CSS
body{
background:green;
}
#menu{
background:white;
}
#media(max-width:768px){
#menu{
transform:translateX(-100%);
-webkit-transform:translateX(-100%);
transition:transform 0.3s;
-webkit-transition:-webkit-transform 0.3s;
}
#menu.in{
transform:translateX(0);
-webkit-transform:translateX(0);
}
}
You can try to achieve this with one more helper class that would set a transition:
#menu {
background:white;
}
#media (max-width: 768px) {
#menu {
transform:translateX(-100%);
-webkit-transform:translateX(-100%);
}
#menu.clicked {
transition: transform 0.3s;
-webkit-transition:-webkit-transform 0.3s;
}
#menu.in {
transform:translateX(0);
-webkit-transform:translateX(0);
}
}
and JS part:
$(window).on('click',function() {
$("#menu").toggleClass('in').addClass('clicked');
setTimeout(function() {
$("#menu").removeClass('clicked');
}, 100);
});
Note, that you need to remove helper class after some short timeout, so that the transition is only active in case of click, but not when window is resized.
Demo: http://codepen.io/anon/pen/aOBYYP
Moving transition:-webkit-transform 0.3s; transition:transform 0.3s; from inside the media query to the standard #menu seems to work, as shown:
From this:
#menu{
background:white;
}
#media(max-width:768px){
#menu{
transform:translateX(-100%);
-webkit-transform:translateX(-100%);
transition:transform 0.3s;
-webkit-transition:-webkit-transform 0.3s;
}
#menu.in{
transform:translateX(0);
-webkit-transform:translateX(0);
}
}
To this:
#menu{
background:white;
transition:transform 0.3s;
-webkit-transition:-webkit-transform 0.3s;
}
#media(max-width:768px){
#menu{
transform:translateX(-100%);
-webkit-transform:translateX(-100%);
}
#menu.in{
transform:translateX(0);
-webkit-transform:translateX(0);
}
}
This is because there is no transition property applied when the screen is wider than 768px; so it will suddenly jump instead of smoothly changing.
Now that I understand the question more clearly, you could try this:
<style>
body{
background:green;
}
#menu{
background:white;
transform:translateX(-100%);
-webkit-transform:translateX(-100%);
}
.out{
transform:translateX(0%)!important;
-webkit- transform:translateX(-0%)!important;
}
#media(max-width:768px)
{
#menu{
transition:transform 0.3s;
-webkit-transition:-webkit-transform 0.3s;
}
}
#media(min-width:786px)
{
#menu{
transform:translateX(0%);
-webkit- transform:translateX(-0%);
}
}
</style>
<body onclick=" if(window.outerWidth < 786){document.querySelector('#menu') .classList.toggle('out');}">
<div id="menu">
This is the menu
</div>
</body>
This method doesn't use any event listeners, and providing it's not inside a frame (where the outerWidth is not it's width), it seems to work.

CSS Help: div:hover~div does not work for div later in code

Example of page
Sorry about the confusing title, I will try to describe the issue better here.
The page has two equal dividers, when I hover over the left div, I want the opacity to change as well, I want the opacity of the second div to change concurrently. The code currently does this, however, with the right divider, the hover only changes itself and not the left divider.
I am open to new ways to approach this as well.
HTML:
<div class="wrap">
<div class="bgimage" id="left">
<div class="text">
<h1>Portfolio</h1>
</div>
</div>
<div class="bgimage" id="right">
<div class="text">
<h1>Photography</h1>
</div>
</div>
</div>
CSS:
.wrap {
width:100%;
height:100vh;
background-color:#000;
}
.text {
height:55px;
opacity:0.9;
text-align:center;
vertical-align:middle;
position:absolute;
top:0;
bottom:0;
margin:auto; width:50%;
}
.bgimage{
width:50%;
height:100vh;
opacity: 0.6;
-webkit-transition: opacity 0.8s ease-in-out;
-moz-transition: opacity 0.8s ease-in-out;
-o-transition: opacity 0.8s ease-in-out;
transition: opacity 0.8s ease-in-out;
background-size:cover;
background-repeat:no-repeat;
background-position:center;
}
#left {
float:left;
background-image:url(left.jpg);
}
#right {
float: right;
background-image:url(right.jpg);
}
#left:hover~div#right, #right:hover~div#left {
opacity: 0.3;
}
#left:hover, #right:hover {
opacity: 1;
}
Of course it will work for the first div but not the second, and you can never select a preceding element in CSS, your best shot is jQuery, take a look at this code:
$(document).ready(function () {
$('.bgimage').hover(function () {
$('.bgimage').removeClass('hovered').addClass('unhovered');
$(this).addClass('hovered').removeClass('unhovered');
});
});
Here's a FIDDLE of your example, I made minor CSS changes .. Hope it helps

CSS3 transition for "top" and "left" properties not working

I have a list with one item on the list transitioning to the northeast when I hover over it. Using margin-top and margin-left property transitions worked but the item being hovered over kept pushing other elements so I added position:relative and tried using top and left transition properties but it didn't seem to be working.
Here is the jsfiddle:
list hover
Add left, top default
link demo
left: 0px
Have you tried setting the parent of your list. I know sometimes relative has issue unless the underlying item is also relative or absolute. Just a thought.
Use position:absolute and it will take it out of the normal document flow. You could also give it z-index:5 to make sure it floats over other elements.
.transition{
transition: all .4s;
-moz-transition: all .4s;
-webkit-transition:all .4s;
-o-transition: all .4s;
margin-top:20px;
border:1px solid gray;
width:80px;
padding:10px;
margin-left:50px;
position:relative;
cursor:pointer;
}
.hover_top{
top:0;
}
.hover_top:hover{
top:-10px;
}
.hover_left{
left:0;
}
.hover_left:hover{
left:-10px;
}
.hover_right{
right:0;
}
.hover_right:hover{
right:-10px;
}
<div class="hover_top transition"> Hover Top </div>
<div class="hover_left transition"> Hover Left </div>
<div class="hover_right transition"> Hover Right </div>
You have to define the property where you want to apply the transition effect. For example:
.box { position: relative; transition: all 0.4s ease;}
.box:hover { top: -1rem;}
that will not work. So you have to define top: 0 by default then top -1rem on hover. like
.box { position: relative; transition: all 0.4s ease; top:0}
.box:hover {top: -1rem}
that will work.

Resources