css transition effect for divs - javascript

I've the below Code.
function showOrHideDiv() {
var e = document.getElementById('pageRightMenu');
var l = document.getElementById('pageLeftMenu');
if (e.style.display == 'block') {
e.style.display = 'none';
l.style.width = '99%';
l.style.transition = "all 2s"; // Standard syntax
l.style.WebkitTransition = "all 2s"
}
else {
l.style.width = '60%';
l.style.transition = "width 2s"; // Standard syntax
l.style.WebkitTransition = "width 2s";
e.style.display = 'block';
}
}
html,
body {
position: fixed;
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
}
.blended_grid {
display: block;
width: 100%;
overflow: auto;
width: 100%;
height: 100%;
/* Webkit 35: */
-webkit-animation: fadeIn 1s linear;
/* Firefox 28, Opera 22, IE 11: */
animation: fadeIn 1s linear;
}
.pageHeader {
background-color: rgba(0, 0, 0, 0.5);
float: left;
clear: none;
height: 20%;
width: 100%;
border: 1px solid black;
}
.pageLeftMenu {
background-color: rgba(0, 0, 0, 0.5);
float: left;
clear: none;
height: 80%;
width: 100%;
border: 1px solid black;
}
.pageRightMenu {
background-color: rgba(0, 0, 0, 0.5);
float: right;
clear: none;
height: 80%;
width: 39%;
border: 1px solid black;
}
<div class="blended_grid">
<div class="pageLeftMenu" id="pageLeftMenu">
<input type="button" value="Click Me!" onClick="showOrHideDiv()" />
</div>
<div class="pageRightMenu" id="pageRightMenu" style="display: none">
This a textF
</div>
</div>
Here as part of my requirements, I've created 2 divs, and in left div there is a button, when I click, the other div will either appear or disappear, and everything is fine, but I want to have a css transition effect when I hide or show the div.
Update:
I'm able to do the transition. I've tried a js function that is doing what I actually require (updated in this question), but when you show the 2nd div, the div appears first below and then beside the other div. How can I fix it, I mean, after the entire transition, the 2nd div should be visible
please run the code snippet to get a better understanding of my issue.
please let me know how can I do this.
Thanks

I recommend using the jQuery fadeOut() function, which animates the opacity to zero and then sets the "display" property to "none" when the animation is finished:
function showOrHideDiv() {
var $e = $(document.getElementById('pageRightMenu'));
var l = document.getElementById('pageLeftMenu');
if ( $e.is(":visible") ) { //safer comparison in case you change things later
l.style.width = '100%';
$e.fadeOut(500); //fade out, taking 500ms
} else {
l.style.width = '60%';
$e.fadeIn(500); //fade in, taking 500ms
}
}

Here's how you do it:
Make this containing element a flexbox using display: flex
Give the pageLeftMenu a "fixed" width using flex: 0 0 auto, which means the width will be taken from the width property (and therefore animated)
Give the pageRightMenu a "flexible" width using flex: 1 1 0, which means it will take up all the remaining space in the parent not used by pageLeftMenu.
The example below shows the effect. Check out this guide for more on flexbox: https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties
function showOrHideDiv() {
var e = document.getElementById('pageRightMenu');
var l = document.getElementById('pageLeftMenu');
if (e.style.display == 'block') {
e.style.display = 'none';
l.style.width = '99%';
l.style.transition = "all 2s"; // Standard syntax
l.style.WebkitTransition = "all 2s"
}
else {
l.style.width = '60%';
l.style.transition = "width 2s"; // Standard syntax
l.style.WebkitTransition = "width 2s";
e.style.display = 'block';
}
}
html,
body {
position: fixed;
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
}
.blended_grid {
display: flex; //instead of display: block
width: 100%;
overflow: auto;
width: 100%;
height: 100%;
/* Webkit 35: */
-webkit-animation: fadeIn 1s linear;
/* Firefox 28, Opera 22, IE 11: */
animation: fadeIn 1s linear;
}
.pageHeader {
background-color: rgba(0, 0, 0, 0.5);
float: left;
clear: none;
height: 20%;
width: 100%;
border: 1px solid black;
}
.pageLeftMenu {
background-color: rgba(0, 0, 0, 0.5);
float: left;
clear: none;
height: 80%;
width: 100%;
flex: 0 0 auto; //use the width property to determine width
border: 1px solid black;
}
.pageRightMenu {
background-color: rgba(0, 0, 0, 0.5);
float: right;
clear: none;
height: 80%;
flex: 1 1 0; //use up all remaining space
border: 1px solid black;
}
<div class="blended_grid">
<div class="pageLeftMenu" id="pageLeftMenu">
<input type="button" value="Click Me!" onClick="showOrHideDiv()" />
</div>
<div class="pageRightMenu" id="pageRightMenu" style="display: none">
This a textF
</div>
</div>

Related

Hiding/Showing CSS elements does not work?

THE WHOLE CODE IN JSFIDDLE
I have been struggling to effectively remove the code and css created in the function Seifenblasen_blasen()
function Seifenblasen_blasen(){
btn1.style.display = 'none';
document.getElementById("text").innerHTML="Bubble"
const section = document.querySelector('section')
const createElement = document.createElement('spawn')
var size = Math.random() * 60;
createElement.style.width = 30 + size + 'px';
createElement.style.height = 30 + size + 'px';
createElement.style.left = Math.random() * innerWidth + "px";
section.appendChild(createElement);
setTimeout(() => {
createElement.remove()
},8000)
}
const Blaseninterval = setInterval(Seifenblasen_blasen, 100)
created CSS:
section {
width: 100%;
height: 100vh;
overflow: hidden;
background: #1F69FA;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
section.text{
font-size: 10em;
color: #333;
margin: 0 auto;
text-align: center;
font-family: consolas;
background-color:#1F69FA;
pointer-events: none;
border: none;
}
section spawn {
position: absolute;
bottom: -80px;
background: transparent;
border-radius: 50%;
pointer-events: none;
box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5);
animation: animate 4s linear infinite;
}
section spawn:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
transform: scale(0.25) translate(-70%, -70%);
background: radial-gradient(#fff, transparent);
opacity: 0.6;
border-radius: 50%;
}
#keyframes animate {
0% {
transform: translateY(0%);
opacity: 1;
}
99% {
opacity: 1;
}
100% {
transform: translateY(-2000%);
opacity: 0;
}
section span {
margin-top: 700px;
font-size: 1em;
color: #333;
margin: 0 auto;
font-family: consolas;
background-color: #1F69FA;
border: none;
position: absolute;
}
HTML:
<section id="section">
<div class="content">
<button id="btn"></button>
<button id="btn1"></button>
</div>
</section>
to then execute the next function function next(). This removal is needed because when I don't remove the elements from the first function the second wont work. I could just do document.head.innerHTML = "" but that would then also remove the css needed for the button appearing in the next function. So then I tried to make variables with const
const btn = document.getElementById('text');
const btn1 = document.getElementById('text1');
const section = document.querySelector('section')
// in function Seifenblasen_blasen()
btn1.style.display = 'none';
// in function next()
section.style.display = 'none';
btn.style.display = 'none';
btn1.style.display = 'block';
to hide and show only parts of the css without removing the css entirely to keep the styling intact, but now nothing works anymore.(the button on the next Screen doesn't show up at all and the first button does not contain any styling) My endgoal is that I can essentially switch between two screens one showing the bubbles and one the bouncy balls and when I click on the button it goes on. (for example start is bubbles. I click -> Bounce, click again -> back to Bubbles and so on)

JavaScript and CSS not working as intended

In the following code, when I put the div with class thumb-bar, the JavaScript I have written works but if place use it after full-img div tag, it doesn't work also the CSS attribute cursor: pointer for the thumb-bar div is not applied.
Edit - I mean the click listeners I apply using JavaScript are not working
CSS:
body {
width: 640px;
margin: 0 auto;
}
.full-img {
position: relative;
display: block;
width: 640px;
height: 480px;
}
button {
border: 0;
background: rgba(150, 150, 150, 0.6);
text-shadow: 1px 1px 1px white;
border: 1px solid #999;
position: absolute;
cursor: pointer;
top: 2px;
left: 2px;
}
.thumb-bar img {
display: block;
width: 20%;
float: left;
cursor: pointer;
}
HTML:
<div class="thumb-bar"></div>
<div class="full-img">
<img class="displayed-img" src="images/pic1.jpg">
<button class="dark">Darken</button>
</div>
JavaScript:
var displayedImage = document.querySelector('.displayed-img');
var thumbBar = document.querySelector('.thumb-bar');
btn = document.querySelector('button');
var overlay = document.querySelector('.overlay');
for (var i = 1; i <= 5; i++) {
var newImage = document.createElement('img');
newImage.setAttribute('src', 'images/pic' + i + '.jpg');
thumbBar.appendChild(newImage);
newImage.addEventListener('click', function(e) {
displayedImage.setAttribute('src', e.target.getAttribute('src'))
});
}
Because you're floating .thumb-bar img, those images are taken out of the page flow which results in the .thumb-bar element to have a height of 0, which in turn causes subsequent content to not be pushed down. That means that the .full-img element is rendered on top of the images and obscures them from the mouse pointer.
You need to clear the floats in order to get the .full-img element to render below them. This can be done by either making sure the .thumb-bar clear it's own content:
.thumb-bar {
overflow: hidden;
}
... or make the .full-img element itself clear them:
.full-img {
clear: both;
}

How to properly animate a bar gliding?

I have two buttons, when a user clicks on them it gets underlined. However, I'd like the .underline to be animated/glide horizontally to the button that is being clicked on.
Demo: https://jsfiddle.net/ds1wr736/11/
As of right now, the .underline just appears and disapears when a button is clicked. How can I animate this to smoothly glide (x values changing) to the selected button without hacks and JQuery?
function switchTab(tab) {
if (tab === 1) {
document.getElementById("tab2").classList.add("underline");
document.getElementById("tab1").classList.remove("underline");
}
else if (tab === 2) {
document.getElementById("tab1").classList.add("underline");
document.getElementById("tab2").classList.remove("underline");
}
}
.bar {
background-color: gray;
padding: 20px;
}
.underline {
border-bottom: 5px solid red;
}
button {
width: 100px;
height: 50px;
background-color: white;
}
button:focus {
outline: none;
}
<div class="bar">
<button id='tab1' class="underline" onclick='switchTab(2)'>Tab 1</button>
<button id='tab2' onclick='switchTab(1)'>Tab 2</button>
</div>
Rather than animating a border I've created an additional element that reacts to the the click events. This allows us to track the position of the "underline" and scale and animate it between buttons when clicked.
This can be modified to accept hover events instead using mouseover instead of click.
let buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('mouseover', hoverboard); // Hover event
//button.addEventListener('click', hoverboard);
});
function hoverboard(e) {
const board = document.querySelector('.hoverboard');
// - 1 due to the border of the button
let width = this.offsetWidth - 1;
const firstChild = document.querySelector('.bar button:first-child');
const lastChild = document.querySelector('.bar button:last-child');
// - 19 due to padding being 20px on the left and removing 1 for the button's border
let left = this.offsetLeft - 19;
board.style.cssText = 'transform: translateX(' + left + 'px); width: ' + width + 'px;';
}
.bar {
position: relative;
background-color: gray;
padding: 20px;
}
.underline {
border-bottom: 5px solid red;
}
button {
width: 100px;
height: 50px;
background-color: white;
}
button:focus {
outline: none;
}
.hoverboard {
position: absolute;
width: 100px;
height: 3px;
background: red;
transition: transform .25s ease, width .25s ease;
}
<div class="bar">
<button id='tab1'>Tab 1</button>
<button id='tab2' style="width: 65px;">Tab 2</button>
<button>Tab 3</button>
<div class="hoverboard"></div>
</div>
Here ya go. Only the edited classes are here:
.underline:after {
border-bottom: 5px solid red;
animation-name: slideIn;
animation-duration: 1s;
width: 100%;
content: '';
position: absolute;
bottom: 0;
left: 0;
}
#keyframes slideIn {
from {width: 0;}
to {width: 100%;}
}
button{
position: relative;
width: 100px;
height: 50px;
background-color: white;
}
What I did is that I used the abstract after element on the buttons and positioned it absolute to it's relative button. And used css animation.

Animate line wrapping of inline-block elements on content change

I have a container with a fixed width and overflow: auto; set.
It contains multiple items (display: inline-block;), also with fixed dimensions.
So if the container has enough children, the items will wrap around and create a grid-like pattern.
Now I dynamically remove children from the beginning and want to animate the position change of the items that are filling up the freed space and moving up from the start of a line to the end of the line above.
var counter = 1;
document.getElementById("additem").onclick = function() {
var item = document.createElement("div");
item.innerText = counter;
counter++;
document.getElementById('container').appendChild(item);
}
document.getElementById("removeitem").onclick = function() {
document.getElementById('container').removeChild(
document.getElementById('container').children[0]
);
}
#container {
width: 280px;
overflow: auto;
border: 1px solid red;
padding: 5px;
text-align: center;
}
#container > div {
width: 80px;
height: 90px;
border: 1px solid green;
margin: 5px;
display: inline-block;
}
<button id="additem">add item</button>
<button id="removeitem">remove item</button>
<div id="container">
</div>
EDIT: I am also able to use jQuery to accomplish this behaivor.
A reasonably clean solution is to use an inline style that sets the removed element's opacity to 0, accompanied by a transition and a setTimeout timed to run as soon as the transition finishes, effectively fading out the element and then sliding everything else into place. Here's a quick snippet I put together:
var counter = 1;
document.getElementById("additem").onclick = function() {
var item = document.createElement("div");
item.innerText = counter;
counter++;
document.getElementById('container').appendChild(item);
}
document.getElementById("removeitem").onclick = function() {
document.getElementById('container').children[0].setAttribute('style', 'opacity: 0');
window.setTimeout(function() {
document.getElementById('container').removeChild(
document.getElementById('container').children[0]
)
}, 300);
}
#container {
width: 280px;
overflow: auto;
border: 1px solid red;
padding: 5px;
text-align: center;
}
#container>div {
width: 80px;
height: 90px;
border: 1px solid green;
margin: 5px;
display: inline-block;
transition: opacity 0.3s;
}
<button id="additem">add item</button>
<button id="removeitem">remove item</button>
<div id="container">
</div>

Animating 2 flexbox DIVs

I have 2 DIVs in a flexbox container, where they both start of side by side. By removing one of the divs, the other one becomes centered within the container.
I cant seem to find a way of making an animated transition from centered/uncentered. Is there any way of doing this?
HTML:
<div id='wrap'>
<div id='a'></div>
<div id='b'></div>
</div>
<button id='btna' onclick="toggle('a')">Toggle Red</button>
<br>
<button id='btnb' onclick="toggle('b')">Toggle Green</button>
CSS:
#wrap{
width: 400px;
height: 200px;
border: 1px dashed grey;
display: flex;
justify-content: center;
}
#a{
width: 200px;
height: 200px;
background-color: red;
}
#b{
width: 200px;
height: 200px;
background-color: green;
}
JS:
var displayed = [ true, true ];
function toggle( div )
{
if( div == 'a' )
{
if( displayed[0] )
{
$('#a').fadeOut(500);
}
else
{
$('#a').fadeIn(500);
}
displayed[0] = !displayed[0];
}
else
{
if( displayed[1] )
{
$('#b').fadeOut(500);
}
else
{
$('#b').fadeIn(500);
}
displayed[1] = !displayed[1];
}
}
Here is a jsfiddle for what I have so far:
https://jsfiddle.net/uvyLh8m9/6/
The reason for this is that your function fadeIn first make decrease opacity without letting disappear the block, and only then, lets it disappear.
I would do it this way : which means, letting fade out manually and during the same time decreasing the width. Optionally you could call Element.style.display = 'none'; after 500ms using setTimeout(function(){/*code here*/}, 500);
var displayed = [ true, true ];
function toggle( div )
{
if( div == 'a' )
{
if( displayed[0] )
{
//$('#a').fadeOut(500);
document.getElementById('a').style.opacity = 0;
document.getElementById('a').style.width = '0px';
}
else
{
//$('#a').fadeIn(500);
document.getElementById('a').style.opacity = 1;
document.getElementById('a').style.width = '200px';
}
displayed[0] = !displayed[0];
}
else
{
if( displayed[1] )
{
//$('#b').fadeOut(500);
document.getElementById('b').style.opacity = 0;
document.getElementById('b').style.width = '0px';
}
else
{
//$('#b').fadeIn(500);
document.getElementById('b').style.opacity = 1;
document.getElementById('b').style.width = '200px';
}
displayed[1] = !displayed[1];
}
}
#wrap{
width: 400px;
height: 200px;
border: 1px dashed grey;
display: flex;
justify-content: center;
}
#a, #b {
-webkit-transition:opacity 500ms, width 500ms;
-moz-transition:opacity 500ms, width 500ms;
transition:opacity 500ms, width 500ms;
}
#a{
width: 200px;
height: 200px;
background-color: red;
}
#b{
width: 200px;
height: 200px;
background-color: green;
}
<div id='wrap'>
<div id='a'></div>
<div id='b'></div>
</div>
<button id='btna' onclick="toggle('a')">Toggle Red</button>
<br>
<button id='btnb' onclick="toggle('b')">Toggle Green</button>

Categories

Resources