I am trying to animate a small rectangular div that is centered/fixed at the top of the screen and will scale from the center into a full screen overlay. Here is a wireframe of the animation I am trying to create.
I have a solution now but it is definitely not the most clean or elegant:
<div class="step1"></div>
.step1 {
border:none;
background:none;
text-align: Center;
font-size: 1.6em;
height: 200px;
width: 300px;
background-color: blue;
position: fixed;
left: 47%;
margin-left: -1.75em;
top: 0;
z-index: 1;
transition: all .2s;
}
.step2 {
height: 100%;
width: 100%;
left: 0%;
top: 0;
margin: 0;
border:none;
background:none;
color: white;
text-align: Center;
background-color: blue;
position: fixed;
z-index: 1;
border-radius: 0;
}
I am also getting a janky animation and I know there must be a better way. Can anyone offer a cleaner solution?
You can .toggleClass() on .click():
$('div').click(function() {
$(this).toggleClass('step');
});
div {
width: 300px;
height: 200px;
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%); /* makes it horizontally centered */
background: blue;
transition: all .3s linear; /* added linear transition effect, it's "ease" by default */
}
.step {
width: 100vw; /* 100% of the viewport width */
height: 100vh; /* 100% of the viewport height */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
I'd suggest using css animations like so
.step1 {
border:none;
background:none;
text-align: Center;
font-size: 1.6em;
height: 200px;
width: 300px;
background-color: blue;
position: fixed;
left: 47%;
margin-left: -1.75em;
top: 0;
z-index: 1;
transition: all .2s;
animation-name:demo;
animation-duration:2s;
animation-fill-mode:forwards;
}
#keyframes demo{
0%{height:200px;width:300px;left:47%;margin-left:-1,75em}
100%{height:100%;width:100%;left:0;margin-left:0}
}
<div class="step1"></div>
Here's my approach. You trigger the animation by hovering over the div. I decided to use transition because It's more practical for simple applications like this.
<!DOCTYPE HTML>
<head>
<meta charset="UTF-8">
<style type="text/css">
div {
background-color: #ff0000;
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 0px;
left: 50%;
transition: width 10s, height 10s, left 10s;
}
div:hover {
width: 100%;
height: 100%;
left: 0;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
Check the following demo:
$(document).ready(() => {
setTimeout(() => {
$('#myDiv').toggleClass('step1 step2');
},1000);
});
#myDiv {
position: fixed;
top: 0;
background-color: blue;
transition: all .2s;
}
.step1 {
left: 35%;
right: 35%;
height: 100px;
}
.step2 {
left: 0;
right: 0;
height: auto;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv" class="step1"></div>
Here is an easy solution:
body {
margin: 0;
height: 100vh;
}
div {
width: 300px;
margin: auto;
height: 200px;
background: blue;
animation: animate 3s linear 1s forwards;
}
#keyframes animate {
to {
width: 100%;
height: 100%;
}
}
<div></div>
Related
I'm trying to animate a hamburger button. The problem is that the animation works great only for the first click, and I do not know how to make the second click do the reverse animation. I'm not sure if this can be done without using keyframes. Ps. brackets in css are not formatted because its compiled from scss.
var hamburger = document.getElementById("hamburger");
var nav_items = document.getElementsByClassName("nav-items")[0];
var line1 = document.getElementsByClassName("line1")[0];
var line2 = document.getElementsByClassName("line2")[0];
var line3 = document.getElementsByClassName("line3")[0];
hamburger.addEventListener("click", function() {
nav_items.classList.toggle("nav-open");
line1.classList.toggle("first-line");
line2.classList.toggle("middle-line-hidden");
line3.classList.toggle("last-line");
});
body {
background-color: white;
margin: 0;
padding: 0;
}
#navbar {
position: fixed;
top: 0;
width: 100%;
height: 100px;
color: white;
z-index: 100;
background-color: blue;
}
#logo {
position: absolute;
top: 50%;
left: 25px;
transform: translateY(-50%);
font-size: 25px; }
#logo a {
text-decoration: none;
color: white; }
#logo a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
height: 5px;
width: 100%;
background-color: yellow;
z-index: -1; }
.nav-items {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
visibility: hidden;
justify-content: center;
font-size: 2rem;
background-color: black; }
.nav-items a {
text-decoration: none;
color: white;
margin: 15px 0; }
.nav-items a:first-child {
margin-top: 0; }
.nav-items a:hover {
color: yellow; }
#hamburger {
height: 40px;
width: 40px;
background-color: transparent;
border: 0px solid transparent;
padding: 0;
position: absolute;
right: 80px;
top: 50%;
transform: translateY(-50%);
z-index: 100;
}
#hamburger .line1,
#hamburger .line2,
#hamburger .line3 {
position: absolute;
left: 0;
height: 5px;
width: 100%;
background-color: white;
border-radius: 25px;
transition: 0.5s linear; }
#hamburger .line1 {
top: 3px; }
#hamburger .line2 {
top: 50%;
transform: translateY(-50%); }
#hamburger .line3 {
bottom: 3px; }
.nav-open {
visibility: visible; }
.middle-line-hidden {
animation: hamburger-mid-line 0s linear;
animation-fill-mode: forwards;
animation-delay: 0.3s; }
.first-line {
animation: hamburger-first-line 0.5s;
animation-fill-mode: forwards; }
.last-line {
animation: hamburger-last-line 0.5s;
animation-fill-mode: forwards; }
#keyframes hamburger-mid-line {
from {
visibility: visible; }
to {
visibility: hidden; } }
#keyframes hamburger-first-line {
0% { }
50% {
top: 50%;
transform: translateY(-50%); }
100% {
top: 42%;
transform: rotate(45deg); } }
#keyframes hamburger-last-line {
0% { }
50% {
bottom: 50%;
transform: translateY(50%); }
100% {
bottom: 45%;
transform: rotate(-45deg); } }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/main.css" />
</head>
<body>
<header id="navbar">
<div class="nav-items">
link1
link2
link3
</div>
<button id="hamburger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</button>
</header>
</body>
</html>
The most easy way is to assign in the css the animation to a class, for example .openedhamburger with the opening animation.
Now create other animation assigned to other class, for example .closedhamburger, with the closing animation.
Finally switch the class asigned to the element with javascript and there it is, whenever a different class is assigned, the proper animation will be triggered.
Edit: also, albeit in your case use a two step animation, so this is not applicable, know that using this class-approach, if you enable smooth transitions, then sometimes you can even do it without any animation: simply associate the positions and rotations for the elements on the two states and then because smooth transformations are enabled, animation will ocur.
I have created a preloader which works fine apart from when it is gone it is still there as a invisible layer covering all the content on the page. So none of the content like links can be clicked. How can this be solved but still keep the animation?
Codepen
<body>
<div id="preloader_wrap">
<div class="section" id="right_sect">
</div>
<div class="section" id="left_sect">
</div>
<div id="content">
<div id="img">
</div>
<div id="loading_bar">
<div></div>
</div>
</div>
</div>
<header>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</header>
</body>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
css:
*{
margin: 0;
padding: 0;
}
body{
background-color: #666666;
width: 100%;
}
#preloader_wrap{
z-index: 1010;
position: fixed;
top: 0;
left: 0;
right: 0;
}
.section{
position: fixed;
width: 50%;
height: 100%;
background-color: black;
top: 0;
transition: width 1s;
}
#left_sect{
left: 0;
}
#right_sect{
right: 0;
}
#content{
position: relative;
margin: 100px auto 0 auto;
width: 600px;
transition: all 1s;
}
#img{
height: 200px;
width: 300px;
background-color: red;
margin: 0 auto;
}
#loading_bar{
height: 50px;
width: 50px;
margin: 30px auto;
}
#loading_bar div{
height: 100%;
width: 100%;
border-bottom: 4px solid #ffffff;
border-left: 4px solid transparent;
border-radius: 100%;
animation: spin 0.9s linear infinite;
-webkit-animation: spin 0.9s linear infinite;
-moz-animation: spin 0.9s linear infinite;
-o-animation: spin 0.9s linear infinite;
}
#keyframes spin {
0% {-webkit-transform: rotate(0deg);}
100% {-webkit-transform: rotate(360deg);}
}
body.loaded .section{
width: 0;
}
body.loaded #content{
opacity: 0;
}
header{
width: 100%;
height: 75px;
background-color: blue;
position: fixed;
top: 0;
z-index: 1000;
}
ul{
list-style-type: none;
margin: 10px auto;
width: 300px;
}
ul li{
display: inline-block;
font-size: 40px;
}
ul li a{
color: white;
}
JS:
$(document).ready(function() {
setTimeout(function(){
$('body').addClass('loaded');
}, 2000);
});
Change your script to this...
$(document).ready(function() {
setTimeout(function(){
$('body').addClass('loaded');
$('#preloader_wrap').remove();
}, 2000);
});
That will completely remove the layer once the page is loaded.
Its basically a z-index problem on preloader_wrap. You can fix the z-index after the loader is loaded with $("#preloader_wrap").css("z-index","-1")
$(document).ready(function() {
setTimeout(function() {
$('body').addClass('loaded');
$("#preloader_wrap").css("z-index", "-1");
}, 2000);
});
* {
margin: 0;
padding: 0;
}
body {
background-color: #666666;
width: 100%;
}
#preloader_wrap {
z-index: 1010;
position: fixed;
top: 0;
left: 0;
right: 0;
}
.section {
position: fixed;
width: 50%;
height: 100%;
background-color: black;
top: 0;
transition: width 1s;
}
#left_sect {
left: 0;
}
#right_sect {
right: 0;
}
#content {
position: relative;
margin: 100px auto 0 auto;
width: 600px;
transition: all 1s;
}
#img {
height: 200px;
width: 300px;
background-color: red;
margin: 0 auto;
}
#loading_bar {
height: 50px;
width: 50px;
margin: 30px auto;
}
#loading_bar div {
height: 100%;
width: 100%;
border-bottom: 4px solid #ffffff;
border-left: 4px solid transparent;
border-radius: 100%;
animation: spin 0.9s linear infinite;
-webkit-animation: spin 0.9s linear infinite;
-moz-animation: spin 0.9s linear infinite;
-o-animation: spin 0.9s linear infinite;
}
#keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
body.loaded .section {
width: 0;
}
body.loaded #content {
opacity: 0;
}
header {
width: 100%;
height: 75px;
background-color: blue;
position: fixed;
top: 0;
z-index: 1000;
}
ul {
list-style-type: none;
margin: 10px auto;
width: 300px;
}
ul li {
display: inline-block;
font-size: 40px;
}
ul li a {
color: white;
}
<body>
<div id="preloader_wrap">
<div class="section" id="right_sect">
sdsadsadsa
</div>
<div class="section" id="left_sect">
dasdsadsad
</div>
<div id="content">
<div id="img">
</div>
<div id="loading_bar">
<div></div>
</div>
</div>
</div>
<header>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</header>
</body>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
Your loader area has a z-index of 1010, which puts it in front of everything else, and you aren't removing that, or removing the element itself. And because its width and height are 100% it blocks the whole page.
You can fix this just using CSS. You're already doing this:
body.loaded .section{
width:0;
}
body.loaded #content{
opacity: 0;
}
However, this only hides the inner parts of the loader, not the whole thing. Do this instead:
body.loaded #preloader_wrap {
display:none;
}
See working example: https://codepen.io/anon/pen/ZKbJEj
I'm not overly clear on which parts of your markup you are trying to hide, but assuming it's all of the stuff within the preloader_wrap element (and if not I would move that markup outside of it), the issue you are having is that this element is stacked on top of the other elements due to it's z-index being higher.
The easiest fix for this is to add the following CSS:
body.loaded #preloader_wrap {
display: none;
}
I can see that this breaks your animation, you could consider the following instead:
body.loaded #content{
opacity: 0;
display: none;
}
However this feels like a bit of a hack given we wouldn't be hiding the wrapper here therefore if anything else in it gave it height it would still overlay part of the page.
I would consider refactoring your markup/CSS transition to make this work for you in a more consistent way.
I have tiles which expand on hover event but they are partly covered by adjacent tiles, how can i fix this?
css code snippet:
.tile {
position: absolute;
width: 86px;
background-color: #000000;
height: 86px;
color: #fff;
transition: 1s linear all;
overflow: hidden;
}
.tile:hover {
background-color: #333333;
height: 172px;
width: 172px;
}
here is a link to my fiddle: https://jsfiddle.net/zjcfope1/
Add z-index to the tile class. Check out this updated fiddle
.tile {
position: absolute;
width: 86px;
background-color: #000000;
height: 86px;
color: #fff;
transition: 1s linear all;
overflow: hidden;
z-index: -9999;
}
.tile:hover {
background-color: #333333;
height: 172px;
width: 172px;
z-index: 9999;
}
is this is you want just try this.
.tile:hover {
background-color: #333333;
height: 172px;`
width: 172px;
z-index:1000;
}
I have the following: http://jsfiddle.net/yHPTv/2491/
I was wondering why the transition isn't working? What it's supposed to do is slide in the hidden element (which can be of variable width) to the right edge of the .block element, however, it just pops in.
.block {
position: relative;
width: 500px;
height: 300px;
overflow: hidden;
background: lightgrey;
}
.block .hidden {
background: red;
padding: 3px 10px;
position: absolute;
bottom: 0;
left: 100%;
transition: 1s;
}
.block:hover .hidden {
transition: 1s;
left: auto;
right: 0;
}
<div class="block">
<div class="hidden">ABCDEFGHIJKL</div>
</div>
I think it has something to do with left: auto because if I change it left: 50%, it works, but not in the way I need it to.
Thanks.
As you say you can't animate from % to auto. But to get the desire effect you can also use transform property. Try this:
.block .hidden {
background: red;
padding: 3px 10px;
position: absolute;
bottom: 0;
right: 0;
transform:translateX(100%);
transition: 1s;
}
.block:hover .hidden {
transition: 1s;
transform:translateX(0)
}
Check the Demo Fiddle
Consider transitioning on right, from -100% to 0:
.block {
position: relative;
width: 500px;
height: 150px; /* shortened to fit in the "Run" window */
overflow: hidden;
background: lightgrey;
}
.block .hidden {
background: red;
padding: 3px 10px;
position: absolute;
bottom: 0;
right: -100%;
transition: 1s;
}
.block:hover .hidden {
right: 0;
transition: 1s;
}
<div class="block">
<div class="hidden">ABCDEFGHIJKL</div>
</div>
For transition to work, you have to define the property you wish to change in both element states.
In your example it doesn't work because there is no common property between '.hidden' and ':hover' (you set the 'left' property in '.hidden', and 'right' property in ':hover')
If you instead use something like:
.block {
position: relative;
width: 500px;
height: 300px;
overflow: hidden;
background: lightgrey;
}
.block .hidden {
background: red;
padding: 3px 10px;
position: absolute;
bottom: 0;
right: -100%;
transition: 1s;
}
.block:hover .hidden {
transition: 1s;
right: 0%;
}
It will work because we defined the 'right' property in both states ('.hidden' and ':hover')
I'm trying create a simple animation that when a user hovers over an element, another element contained within it fills its parent. Currently, I have a JSFiddle that does just that.
BUT, I want to finish this with a few other features that I'm not sure I can actually do in CSS3.
I'm trying to find a way to, upon having the inner circle COMPLETELY fill its parent, (ie when its width/height = 300px), I'd like the fill to pause and not disappear after the animation is complete.
When a user moves their mouse outside the :hover range, I would like the animation to reverse direction as opposed to abruptly stopping.
I've gotten this far with CSS3 but am not sure I can implement these 2 features without resorting to Javascript. Does anyone know of a way of doing this entirely in CSS3/does anyone know if it is possible to do these last two features in CSS3, because I can't seem to find anything.
.circle {
width: 300px;
height: 300px;
background-color: white;
border: 1px solid #000000;
overflow: hidden;
border-radius: 150px;
-moz-border-radius: 150px;
-webkit-border-radius: 150px;
}
.filler {
width: 0px;
height: 0px;
background-color: red;
border: none;
position: relative;
left: 50%;
top: 50%;
border-radius: 150px;
-mox-border-radius: 150px;
-webkit-border-radius: 150px;
animation: empty 1s;
}
.circle:hover .filler {
animation: fill 2s;
-moz-animation: fill 2s;
-webkit-animation: fill 2s;
background-color: blue;
}
#keyframes fill
{
from {background: red; height: 0px; width: 0px;}
to {background: green; height: 300px; width: 300px; top: 0%; left: 0%;}
}
#-moz-keyframes fill /* Firefox */
{
from {background: red; height: 0px; width: 0px;}
to {background: green; height: 300px; width: 300px; top: 0%; left: 0%;}
}
#-webkit-keyframes fill /* Safari and Chrome */
{
from {background: red; height:0px; width:0px;}
to {background: green; height: 300px; width: 300px; top: 0%; left: 0%;}
}
#keyframes empty
{
to {background: red; height: 0px; width: 0px; top: 50%; left: 50%;}
}
#-moz-keyframes empty
{
to {background: red; height: 0px; width: 0px; top: 50%; left: 50%;}
}
#-webkit-keyframes empty
{
to {background: red; height: 0px; width: 0px; top: 50%; left: 50%;}
}
JS Fiddle
You don't need keyframes for this simple animation. Here is CSS you need:
.circle {
position: relative;
width: 300px;
height: 300px;
background-color: white;
border: 1px solid #000000;
border-radius: 150px;
overflow: hidden;
}
.filter {
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background-color: red;
border-radius: 0px;
-webkit-transition: all 1s;
-moz-transition: all 1s;
-o-transition: all 1s;
transition: all 1s;
}
.circle:hover .filter {
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 150px;
background-color: blue;
}
and HTML:
<div class="circle">
<div class="filter"></div>
</div>
Here is an example: http://jsbin.com/agekef/1/edit
I hope you can try out for this link might help you out
<http://jsfiddle.net/spacebeers/sELKu/3/>
<http://jsfiddle.net/SZqkb/1/>
<http://css-tricks.com/examples/DifferentTransitionsOnOff/>
Thanks