I'm trying to create a pie chart. On desktop (Google Chrome), this pie chart code works as usual and the left and right divs rotate fine. However, opening this code on a mobile device (specifically iPhone 11 running Safari) something weird happens. Right as the page loads on a mobile device, the rotating divs stick out of their parent element circle for a moment, mid-rotation, before eventually going back to normal.
let left = document.getElementById("left");
let right = document.getElementById("right");
function spinPieChart() {
setTimeout(() => {
left.style.opacity = 1;
left.style.transform = "rotate(180deg)";
setTimeout(function() {
right.style.opacity = 1;
right.style.transform = "rotate(60deg)";
}, 250);
}, 10);
}
spinPieChart();
* {
margin: 0;
padding: 0;
}
#circle {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
justify-items: center;
height: 200px;
width: 200px;
border-radius: 50%;
background-color: tomato;
overflow: hidden;
}
#left {
height: 100%;
width: 100%;
background-color: lightblue;
transform-origin: right;
opacity: 0;
transition: opacity 0s, transform 250ms;
transition-timing-function: ease-in;
}
#right {
height: 100%;
width: 100%;
background-color: lightblue;
transform-origin: left;
opacity: 0;
transition: opacity 0s, transform 250ms;
transition-timing-function: ease-out;
z-index: 1;
}
#cover {
position: absolute;
height: 100%;
width: 50%;
background-color: tomato;
left: 0;
}
<div id="circle">
<div id="left"></div>
<div id="right"></div>
<div id="cover"></div>
</div>
you can draw the same using svg and circle elements and apply the CSS for animation (eg. #keyframes).
svg {
display: block;
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow: visible;
}
circle {
fill:rgba(0,0,0,0);
stroke-width:31.8309886184;
stroke-dasharray: 0,0,0,100;
stroke-dashoffset: 25;
-webkit-animation: pie1 3s 1 ease both;
animation: pie1 3s 1 ease both;
}
.pie1 {
stroke:lightblue;
}
.pie2 {
stroke:tomato;
-webkit-animation-name: pie2;
animation-name: pie2;
}
/* 1st pie is 70% */
#-webkit-keyframes pie1 {
50%,100% {stroke-dasharray: 70,30,0,0;}
}
#keyframes pie1 {
50%,100% {stroke-dasharray: 70,30,0,0;}
}
/* 2nd pie is 30% */
#-webkit-keyframes pie2 {
50%,100% {stroke-dasharray: 0,70,30,0;}
}
#keyframes pie2 {
50%,100% {stroke-dasharray: 0,70,30,0;}
}
<div>
<svg viewBox="0 0 63.6619772368 63.6619772368">
<circle class="pie1" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
<circle class="pie2" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
</svg>
</div>
Related
There is a website page which height and width are equal to 100% of the browser viewport (100vw and 100vh).
There is a high quality image (3000x2857px) inside of absolutely positioned wrapper in the center of the page. Image wrapper has max-width in pixels (e.g. 300px).
Also, the image has an overlay. I add .active class to the image wrapper by clicking on overlay. This class makes max-width of image wrapper equal to 100vw.
So, I want to animate this. I added transition to max-width, top, transform properties, but it's laggy. I know that it's due to top and max-width properties because of heavy calculations of the browser. But I don't know how to do it in other ways.
Any help would be welcome!
P.S. While I wrote this question, I found that this implementation is buggy in Safari. I think transform transition doesn't work in this browser, so it will be great if you suggest code that work in it :(
Demo: https://codepen.io/ghettojezuz/pen/ExvGwJB
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: max-width .8s ease, top .8s ease, transform .8s ease;
}
.image-wrapper.active {
max-width: 100vw;
left: 50%;
top: 0;
transform: translate(-50%, 0);
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
One method which seems to react to transitioning well is to alter the scale rather than try to reposition and alter width etc.
This snippet keeps the image centered and calculates the scale needed to move from the initial width to 100vw.
Note: it removes margin on elements to ensure the full width of the viewport is covered.
const imageWrapper = document.querySelector('.image-wrapper');
const overlay = document.querySelector('.image-overlay');
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
function init() {
const w = window.innerWidth;
const scale = w / imageWrapper.offsetWidth;
imageWrapper.style.setProperty('--scale', scale);
}
window.onload = init;
window.onresize = init;
* {
padding: 0;
margin: 0;
}
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: .8s ease;
}
.image-wrapper.active {
transform: translate(-50%, -50%) scale(var(--scale));
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: scale .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
So, I tried multiple things like different css properties, #keyframes animations etc. None of them worked. But I found out that when the image format is SVG, the freezing disappears. I know, not all images can be converted to SVG, but see what you can do about it.
I change the top and transform with flex, now when you click only width changes, but i guess the lag will happen sometime in transform animation case
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.img_container {
max-width:300px;
transition: .5s;
position:relative;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 0;
top: 0;
bottom:0;
right:0;
display:flex;
align-items:center;
justify-content:center;
width: 100%;
transition: .5s;
}
.image-wrapper.active .img_container {
max-width: 100vw;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<div class="img_container">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
</div>
I recently got into coding and I'm enjoying it pretty much. With that being said, I'm pretty new to it and very... rookie. I was wondering if there's a way I can make my centered Icon fade out instead of just disappearing on click. The same goes for the overlay that I've created.
function functionHide(divId, divId2, ) {
let x = document.getElementById(divId);
let y = document.getElementById(divId2);
x.style.display = "none";
y.style.display = "block";
}
#icon {
content: url('https://i.picsum.photos/id/178/536/354.jpg?hmac=ehK1NKjWRA3SRY3R4dCo7ejDyrzqqjDWwtwo2TYLpHk');
height: 256px;
width: 256px;
top: 50%;
left: 50%;
position: fixed;
margin-top: -128px;
margin-left: -128px;
z-index: 1;
transition: .4s ease;
display: block;
}
#overlay {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
display: none;
}
#icon:hover {
cursor: pointer;
transform: scale(1.5);
transition: transform .4s;
}
<div id="icon" onclick="functionHide('icon', 'overlay')"></div>
<div id="background">
<div id="overlay"></div>
</div>
There is a good fade in example.
Use an animation in the hide class, for example:
.hide {
animation-name: fadeOut;
animation-duration: 3s;
}
#keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Remember to use browser extensions like -webkit or -moz.
Use a #keyframes animation or change the opacity of the image, granted that the transition was set.
#keyframes
function functionHide(divId, divId2, ) {
let x = document.getElementById(divId);
let y = document.getElementById(divId2);
x.style.animation = "fadeOut 0.2s forwards";
y.style.animation = "fadeOut 0.2s forwards";
}
#icon {
content: url('https://i.picsum.photos/id/178/536/354.jpg?hmac=ehK1NKjWRA3SRY3R4dCo7ejDyrzqqjDWwtwo2TYLpHk');
height: 256px;
width: 256px;
top: 50%;
left: 50%;
position: fixed;
margin-top: -128px;
margin-left: -128px;
z-index: 1;
transition: .4s ease;
display: block;
}
#overlay {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
display: none;
}
#icon:hover {
cursor: pointer;
transform: scale(1.5);
transition: transform .4s;
}
#keyframes fadeOut{
from{
opacity:1;
}
to{
opacity:0;
}
}
<div id="icon" onclick="functionHide('icon', 'overlay')"></div>
<div id="background">
<div id="overlay"></div>
</div>
Explanation
fadeOut 0.2s forwards
^ ^ ^
name of animation
duration of animation
instructs the animation to run once, then stay in the same state after animation
Or you can consider using the jQuery fadeOut() function like so:
function functionHide(divId, divId2, ) {
let x = document.getElementById(divId);
let y = document.getElementById(divId2);
$(x).fadeOut();
$(y).fadeOut();
}
#icon {
content: url('https://i.picsum.photos/id/178/536/354.jpg?hmac=ehK1NKjWRA3SRY3R4dCo7ejDyrzqqjDWwtwo2TYLpHk');
height: 256px;
width: 256px;
top: 50%;
left: 50%;
position: fixed;
margin-top: -128px;
margin-left: -128px;
z-index: 1;
transition: .4s ease;
display: block;
}
#overlay {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
display: none;
}
#icon:hover {
cursor: pointer;
transform: scale(1.5);
transition: transform .4s;
}
#keyframes fadeOut{
from{
opacity:1;
}
to{
opacity:0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="icon" onclick="functionHide('icon', 'overlay')"></div>
<div id="background">
<div id="overlay"></div>
</div>
So for the following code, I have a circular notification that animates, opening up left and displaying information and a profile image. I would like to be able to reverse the animation back by having the circle go forward covering up the info and fading out (which I already have inputed). However, I'm not sure how to implement this. I've tried a couple of ways like switching the animation around but it doesn't seem to work. Any suggestions?
You can click the "CLOSE ME" button to close the notification and the "OPEN ME" to open it as well.
$(document).ready(function() {
$(".open").click(function(e) {
$(".pgn-wrapper").fadeIn(250);
});
$(".close").click(function(e) {
$(".pgn-wrapper").fadeOut(500);
});
});
/* Circle Animation
------------------------------------
*/
.pgn-circle .alert {
border-radius: 300px;
animation: fadeInCircle 0.3s ease forwards,
resizeCircle 0.3s 0.4s cubic-bezier(0.25, 0.25, 0.4, 1.6) forwards;
-webkit-animation: fadeInCircle 0.3s ease forwards,
resizeCircle 0.3s 0.4s cubic-bezier(0.25, 0.25, 0.4, 1.6) forwards;
height: 50px;
overflow: hidden;
padding: 6px 55px 6px 6px;
-webkit-transform: translateZ(0);
position: relative;
}
.pgn-wrapper[data-position$='-right'] .pgn-circle .alert {
float: right;
}
.pgn-wrapper[data-position$='-left'] .pgn-circle .alert {
float: left;
}
.pgn-circle .alert > div > div.pgn-thumbnail > div {
border-radius: 50%;
overflow: hidden;
width: 48px;
height: 48px;
}
.pgn-circle .alert > div > div.pgn-thumbnail > div > img {
width: 100%;
height: 100%;
}
.pgn-circle .alert > div > div.pgn-message > div {
opacity: 0;
height: 47px;
padding-left: 9px;
animation: fadeIn .3s .5s ease forwards;
-webkit-animation: fadeIn .3s .5s ease forwards;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
word-wrap: break-word;
}
.pgn-circle .alert > div > div.pgn-message > div p:only-child {
padding: 12px 0;
}
.pgn-circle .alert .close {
margin-top: -12px;
position: absolute;
right: 18px;
top: 50%;
opacity: 0;
animation: fadeIn .3s .5s ease forwards;
-webkit-animation: fadeIn .3s .5s ease forwards;
}
.pgn-circle .alert p {
margin-bottom: 0;
}
.pgn-circle .alert > div {
display: table;
height: 100%;
}
.pgn-circle .alert > div > div {
display: table-cell;
vertical-align: middle;
}
#keyframes fadeInCircle {
0% {
opacity: 0;
width: 60px;
}
100% {
opacity: 1;
width: 60px;
}
}
#-webkit-keyframes fadeInCircle {
0% {
opacity: 0;
width: 60px;
}
100% {
opacity: 1;
width: 60px;
}
}
#keyframes resizeCircle {
0% {
width: 60px;
}
100% {
width: 300px;
}
}
#-webkit-keyframes resizeCircle {
0% {
width: 60px;
}
100% {
width: 300px;
}
}
#-webkit-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.close:target {
animation: resizeCircle2 1s all;
animation-direction: alternate;
}
#keyframes resizeCircle2 {
0% {
width: 300px;
}
100% {
width: 60px;
}
}
/* Headings
------------------------------------
*/
p {
display: block;
font-size: 14px;
font-weight: normal;
letter-spacing: 0.01em;
line-height: 22px;
margin: 0px 0px 10px 0px;
font-style: normal;
white-space: normal;
}
.bold {
font-weight: bold !important;
}
/* Alert
------------------------------------
*/
.alert {
background-image: none;
box-shadow: none;
text-shadow: none;
padding: 9px 19px 9px 15px;
border-radius: 3px;
font-size: 13px;
border-width: 0;
-webkit-transition: all 0.2s linear 0s;
transition: all 0.2s linear 0s;
}
.alert-danger, .alert-error {
background-color: #c42827;
color: white;
border-color: #933432;
}
.alert-danger .close, .alert-error .close {
background-position: -95px -10px !important;
}
/*------------------------------------------------------------------
Notifications
--------------------------------------------------
*/
.pgn-wrapper[data-position='top'] {
top: 0;
left: 0;
right: 0;
}
.pgn {
position: relative;
margin: 10px;
}
.pgn .alert {
margin: 0;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<div class="pgn-wrapper" data-position="top-right">
<div class="pgn push-on-sidebar-open pgn-circle">
<div class="alert alert-danger">
<div>
<div class="pgn-thumbnail">
<div>
<img width="40" height="40" style="display: inline-block;" src="https://x1.xingassets.com/assets/frontend_minified/img/users/nobody_m.original.jpg">
</div>
</div>
<div class="pgn-message">
<div>
<p class="bold" style="color:white">John Doe</p>
<p>Logging out in <b>60</b> second(s).</p>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="open" href="#">OPEN ME</a>
<a class="close" href="#">CLOSE ME</a>
<script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Well, you've got a ton of code and I didn't parse through all of it, but I can say that when you have an animation like this:
#keyframes resizeCircle {
0% {
width: 60px;
}
100% {
width: 300px;
}
}
You are indicating where the width should start and end so to reverse that, you'd want to either ensure that this animation is tied to a temporary state, like a hover with a selector like this:
element:hover {
animation:resizeCircle 1s all;
}
Then, the animation would only apply when the element is being hovered and when it isn't the element will animate back to its original state.
Or, you could set up a separate animation that specifies the reverse property values:
#keyframes resizeCircle2 {
0% {
width: 300px;
}
100% {
width: 60px;
}
}
and apply that to a "trigger" selector, such as:
element:target {
animation:resizeCircle2 1s all;
}
Which would (in this case) apply the reverse animation when the element is the target of a click.
Here's an example:
<div class="expandable"></div>
div.expandable {
background-color: green;
width: 30px;
height: 25px;
-webkit-transition: width 0.4s ease-in-out;
transition: width 0.4s ease-in-out;
}
div.expandable:hover {
width: 300px;
}
You can give that a run here: https://plnkr.co/edit/wa5Ny6vmluJv6xeDs7qt?p=preview
I am have made a heading (the word Welcome) that reveals itself once the page has loaded (onload="").
Fiddle in case the code below doesn't work.
function animate() {
document.getElementById("mainText").style.width = "100%";
}
#mainText {
margin: 0px;
display: inline-block;
font-size: 100px;
width: 0%;
transition: width 2s;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
The CSS and Plain JS work fine but I want the word "Welcome" to be revealed right side first and then moving along, so from the e to the W, instead of how it currently is, which opens left to right.
I have tried text align: right;, but this doesn't change anything.
I preferably don't want to use any jQuery, if the solution is a JS one.
An example of what the desired look should be, half way though the transition:
You can use the clip-path property to clip parts of the element so they are not visible. This property can also be animated to reveal the element again, using the forwards keyword in the animation so it stays in it's 'revealed' end state.
The inset takes values that are in order: from-top, from-right, from-bottom, from-left.
#text {
margin: 0;
font-size: 100px;
animation: reveal 2s forwards;
}
#keyframes reveal {
from {
clip-path: inset(0 0 0 100%);
}
to {
clip-path: inset(0 0 0 0);
}
}
<h1 id="text">Welcome</h1>
Yes, it is possible using Transitions and Positions:
window.onload = function () {
document.querySelector("h1").classList.add("active");
};
h1 {
overflow: hidden;
display: inline-block;
position: relative;
}
h1 .mask {
position: absolute;
transition: all 0.5s linear;
left: 0;
top: 0;
bottom: 0;
right: 0;
background-color: #fff;
}
h1.active .mask {
right: 100%;
}
<h1><span class="mask"></span>Welcome</h1>
I just wrote an article about this - CSS Transitions & JavaScript for Animated Entry Effects. Hope it is useful... :)
One option is transform: translate with a pseudo element, and no extra element needed.
function animate() {
document.getElementById("mainText").classList.add('show');
}
#mainText {
position: relative;
margin: 0px;
display: inline-block;
font-size: 100px;
white-space: nowrap;
text-overflow: clip;
overflow: hidden;
}
#mainText::after {
content: '';
position: absolute;
left: 0; top: 0;
width: 100%; height: 100%;
background: white;
transition: transform 2s;
}
#mainText.show::after {
transform: translateX(-100%);
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
Another option, an even better solution, using the pseudo with direction and left/width.
This one work in the same way clip-path does, completely transparent against its background, as opposite to having a mask that revels the text, and with much better browser support.
function animate() {
document.getElementById("mainText").classList.add('show');
}
body {
background: black;
}
#mainText {
position: relative;
margin: 0px;
display: inline-block;
font-size: 100px;
white-space: nowrap;
color: rgba(0, 0, 0, 0);
}
#mainText::before {
content: attr(data-text);
position: absolute;
left: 100%;
top: 0;
width: 0;
height: 100%;
color: white;
direction: rtl;
overflow: hidden;
transition: left 2s, width 2s;
}
#mainText.show::before {
left: 0;
width: 100%;
}
<body onload="animate()">
<h1 id="mainText" data-text="Welcome">Welcome</h1>
</body>
Something like this
function animate() {
document.getElementById("overlay").style.width = "0%";
}
#mainText {
margin: 0px;
display: inline-block;
font-size: 100px;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
#overlay{
width: 100%;
position:absolute;
top:0;
left:0;
background:#fff;
transition: width 2s;
height:100%;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
<div id="overlay"></div>
</body>
This will require a pseudo-element with a background on top of your heading serving as a mask. Instead of altering the inline styles I will simply add a class is-active. So everything style related can be styled via CSS.
function animate() {
document.getElementById("mainText").className = "is-active";
}
#mainText {
margin: 0px;
display: inline-block;
position: relative;
font-size: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
#mainText:before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
background: #FFF;
transition: width 2s;
}
#mainText.is-active:before {
width: 0%;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
I use Transform: translateX to achieve the desired effect.
It slides the text sideways or horizontally on the X axis.
.message {
color: darkred;
font-size: 30px;
display: inline-block;
font-weight: 100;
font-family: sans-serif;
}
.sliding-text-1,
.sliding-text-2,
.sliding-text-3 {
animation-name: slide;
animation-duration: 1s;
animation-timing-function: ease-out;
animation-iteration-count: 1;
animation-fill-mode: forwards;
opacity: 0;
}
.sliding-text-2 {
animation-delay: 2s;
color: darkblue;
}
.sliding-text-3 {
animation-delay: 4s;
color: darkgreen;
}
#keyframes slide {
from {
transform: translateX(200px);
}
to {
transform: translateX(0px);
opacity: 1;
}
}
<h1 class="message sliding-text-1">Hello!</h1>
<h1 class="message sliding-text-2">Thanks for visiting!</h1>
<h1 class="message sliding-text-3">Have a nice day!</h1>
So I got a little circle shape with an icon that when I click, it will make the icon disappear and show a few elements in another div. The circle shape transforms into a 260x260 px square with CSS animation.
Until that I was fine, but I can't make the fadeIn/fadeOut work. Is there a way to handle this by toggling a CSS class over the parent element?
I can't just use opacity 0 to opacity 1 because I need the icon to really disappear with display none. Same for the other when going back to circle+icon state. But I just can't even make the opacity animation work. I also tried with those keyframes of fadeIn and fadeOut but didn't work either.
I found this fiddle but it looks so ugly having to use a setTimeout.
Is there a way to solve this with only CSS?
$('.toggle-btn').click(function() {
$('.parent').toggleClass('expanded');
});
.parent {
width: 40px;
height: 40px;
background-color: lightgray;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
position: fixed;
left: 11px;
bottom: 18px;
text-align: center;
transition: all 500ms;
-webkit-transition: all 500ms;
-moz-transition: all 500ms;
}
.parent.expanded {
width: 200px;
height: 200px;
border-radius: 0 14px 0 0;
left: 0;
bottom: 0;
}
.children-1 {
display: block;
animation: opacity-up 500ms linear 700ms 1;
animation-fill-mode: forwards;
}
.help {
width: 21px;
height: 21px;
position: relative;
top: 9px;
}
.children-2 {
display: none;
animation: opacity-down 500ms linear 700ms 1;
animation-fill-mode: forwards;
}
.parent.expanded .children-1 {
animation: opacity-down 500ms linear 700ms 1;
animation-fill-mode: forwards;
display: none;
}
.parent.expanded .children-2 {
animation: opacity-up 500ms linear 700ms 1;
animation-fill-mode: forwards;
display: block;
}
#keyframes opacity-down {
0% {
visibility: visible;
opacity: 1;
}
100% {
opacity: 0;
visibility: hidden;
}
}
#keyframes opacity-up {
0% {
opacity: 0;
visibility: hidden;
}
100% {
opacity: 1;
visibility: visible;
}
}
/*
#-webkit-keyframes fadeIn {
0% { opacity: 0;
visibility: hidden;
display: none; }
100% { opacity: 1;
visibility: visible;
display: block; }
}
#keyframes fadeIn {
0% { opacity: 0;
visibility: hidden;
display: none; }
100% { opacity: 1;
visibility: visible;
display: block; }
}
#-webkit-keyframes fadeOut {
0% { opacity: 1;
visibility: visible;
display: block; }
100% { opacity: 0;
visibility: hidden;
display: none; }
}
#keyframes fadeOut {
0% { opacity: 1;
visibility: visible;
display: block; }
100% { opacity: 0;
visibility: hidden;
display: none; }
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="children-1">
<img class="help" src="http://media1.calvinklein.com/images/static/e-comm/icons/questionMark.png"/>
</div>
<div class="children-2">
<p class="paragraph">
Here is some content+inputs+other stuff, Here is some content+inputs+other stuff
</p>
</div>
</div>
<button class="toggle-btn">TOGGLE!</button>
Until that I was fine, but I can't make the fadeIn/fadeOut work. Is
there a way to handle this by toggling a CSS class over the parent
element?
You can do this without animation with toggle classes
$('.toggle-btn').click(function() {
$('.parent').toggleClass('expanded');
$('.children-2').toggleClass('show1');
$('.children-1').toggleClass('show2');
});
.parent {
width: 40px;
height: 40px;
background-color: lightgray;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
position: fixed;
left: 11px;
bottom: 18px;
text-align: center;
transition: all 500ms;
-webkit-transition: all 500ms;
-moz-transition: all 500ms;
}
.parent.expanded {
width: 200px;
height: 200px;
border-radius: 0 14px 0 0;
left: 0;
bottom: 0;
}
.children-1 {
display: block;
animation: opacity-up 500ms lineal 0s 1;
animation-fill-mode: forwards;
}
.help {
width: 21px;
height: 21px;
position: relative;
top: 9px;
}
.children-2 {
opacity: 0;
transition: opacity 1s;
}
.children-1 {
opacity: 1;
transition: opacity 1s;
}
.show1 {
opacity: 1;
}
.show2 {
opacity: 1;
}
.parent.expanded .children-1 {
animation: opacity-down 500ms lineal 0s 1;
animation-fill-mode: forwards;
display: none;
}
.parent.expanded .children-2 {
animation: opacity-up 500ms lineal 0s 1;
animation-fill-mode: forwards;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="children-1">
<img class="help" src="http://media1.calvinklein.com/images/static/e-comm/icons/questionMark.png" />
</div>
<div class="children-2">
<p class="paragraph">
Here is some content+inputs+other stuff, Here is some content+inputs+other stuff
</p>
</div>
</div>
<button class="toggle-btn">TOGGLE!</button>