CSS how do I add transition to my modal using javascript - javascript

I am a bit new to CSS and I know there are more topics like this around. But none seem to be the solution for my problem. So after 2 hours of trying all sort of hidden, transition, display etc and with the risk of posting a duplicate here is my question.
How do I make this modal show up smooth using CSS and Javascript?
The CSS
/* The Modal (background) */
.modalestate {
visibility: hidden; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 25;
top: 15;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
transition: all ease 1s;
}
/* Modal Content/Box */
.modalestate-content {
background-color: rgba(0,0,0,0.0);
margin: 12% auto; /* 15% from the top and centered */
padding: 22px;
float:left;
width: 550px; /* Could be more or less, depending on screen size */
transition: all ease 1s;
}
/* The Close Button */
.closeestate {
color: #aaa;
float: right;
font-size: 20px;
font-weight: bold;
}
.closeestate:hover,
.closeestate:focus {
color: whitesmoke;
text-decoration: none;
cursor: pointer;
}
The divs to show the modal and its content:
<div id="mymodelestate" class="modalestate">
<div class="modalestate-content">
<span class="closeestate">×</span>
<div id="responsecontainer" align="center"></div>
</div></div>
The Javascript:
<script>
// Get the modal
var modal = document.getElementById("mymodelestate");
// Get the button that opens the modal
var btn = document.getElementById("btnestate");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("closeestate")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {
modal.style.visibility = "visible";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.visibility = "hidden";
}
// When the user clicks anywhere outside of the modal, close it
window.addEventListener('click', function(event) {
if (event.target == modal) {
modal.style.visibility = "hidden";
}
});</script>
Thanks in advance guys !

What kind of "transition" are you trying to do? What effect do you want to apply to your modal? It's not very clear, but I'm going to guess you are trying to have the modal fade in and fade out slowly as the user clicks the buttons. This assumption comes from the fact you are using visiblity:hidden/visible.
If you are trying to have a fade-in/fade-out effect, you need to set the opacity to 0 instead:
opacity: 0;
And when you want to display it, you set opacity to 1.
However, you are going to run into many other issues. Though, I will say this will be a good learning exercise to familiarize yourself with how elements in HTML work and their interactions with CSS.
EDIT: As promised from my comments, I'll provide an example here and some advice.
First, you have the BODY. This BODY, is literally like a human body. You attach elements to it (or human parts). You have this down pretty good, you even use the z-index so I won't go over this too much. I know more "advanced" devs are going to say something about the DOM blah blah it's not attached yada yada, but we're going to keep it simple here.
Next is that the elements all have a initial attribute associated to them. For example, a DIV element has inline-block as an initial attribute. P element tag has some margin and is a block element. Etc etc. You can obviously override these with CSS or add extra attributes as you have been doing. By giving an element a CLASS, you are creating your own custom element of sorts (though it is still it's base element, DIV, P, A, SPAN, etc)
Next is understanding all of these attributes. You seem to know a good deal amount of attributes so I won't go over much, but I will go over these:
Visibility - The element still exists on the BODY. It's there, it still touches everything and affects everything around it. Think of it as an invisible arm on a human body. You can still use that arm and touch things, make things move, push things away, etc... It's just literally invisible. The GPU or whatever is driving graphics will simply NOT render this element.
Opacity - Similar to visibility, but you get some more control. Opacity of 1 (or 100%) means the element is completely visible. An opacity of .5 or 50% means the element is only half seen. That means things behind it can be seen through it. The GPU is still rendering this element but you can now include transparency. 0 means it has complete transparency (basically it's invisible).
Display - This is used to set how an element behaves in your body and how it interacts with other elements. You will often see or even use "display: none" which makes it seem like the element does not exist anymore (it's still there in HTML, though). It will no longer affect anything around it.
Now, what's more important is to understand some of the more complexities of these attributes. In your case, you should know about transitions. A transition attribute allows you to modify the browser's handling of attribute manipulation on an element. In simpler terms, as you know, it lets you create effects on elements, such as fading in, fading out, movement, etc. And it comes out nice and smooth (if done correctly).
However, these attributes that are being manipulated occur instantly. Thus, as mentioned, transitions give you that control to make it smooth. HOWEVER, it is important to note that these transitions will only work when an element already has attribute values to be manipulated. For example:
.MyDivClass{
height: 32px;
width: 32px;
transition: all .3s ease;
}
.MyDivClassExtra{
height: 64px;
width: 64px;
}
The div will seem to grow larger over .3 seconds. That is because my height and width are set. If I did "NOT" set width/height or even set it to atuo, it will just happen instantly. Because there was no attribute to be manipulated! Even setting height/width to 0 will work, because at least it has an attribute to work with.
You have to sometimes set aside common sense when it comes to programming. Things like Visibility you'd assume if you turn it on and off with transition, it'll fade in nicely. However, no. Visibility is simple ON or OFF. There is nothing to transition into. With opacity, it is not just simply ON or OFF. There are 101 numbers (infinite actually, I guess...) to transition from. 0% to 100%. You can do decimals, too. The same is true with display. A little more complicated but simply put - there is only ON or OFF with display.
Some other notes on your code is that your .modelstate element is on top of everything. Your users won't be able to click anything because of this. Visibility hidden does not make it unclickable. Like I mentioned, it simply makes it invisible - it's still there affecting everything else.

Related

how do I add an animation to my onmouseover javascript function(changing image on hover)?

I have been trying out a function where when a mouse hovers over the photo it changes. Is there a way to animate this change?
<img src='./images/rocks.jpg' onmouseover="this.src='./images/seasky.jpg';"
onmouseout="this.src='./images/rocks.jpg';" />
First, inline HTML event attributes (i.e. onmouseover, onmouseout, etc.) should not be used. The use of these kinds of attributes persists today because sites like W3 Schools still show them and millions upon millions of inexperienced developers just copy/paste code that they've seen somewhere else and because it seems to work, they don't think twice about it. In fact, there are many reasons why these attributes should die the abrupt death they deserve.
Now, to your specific question, if you want a transition effect, you'll need to use CSS to set it up. And, it's probably best done by using background images of a div element, rather than altering the src of an img element.
See the comments for details:
/* Separate your event handling code from your markup */
// Get a reference to the element
let fancy = document.querySelector(".fancyImage");
// Set up the mouseover event handler
fancy.addEventListener("mouseover", function(){
this.classList.add("go"); // Change to the Go image
this.classList.remove("stop"); // Remove the Stop image
});
fancy.addEventListener("mouseout", function(){
this.classList.add("stop"); // Change to the Stop image
this.classList.remove("go"); // Remove the Go image
});
/* Use CSS for all styling and layout */
.fancyImage {
/* Set up a transition for all property changes that takes place over 1 second */
transition:all 1s;
/* Set the size of the div, otherwise it will collapse because there's no content
in its foreground */
width:200px;
height:160px;
}
/* The element starts off with the stop class hard-coded, so it starts with this image */
.fancyImage.stop {
background: url("https://img.favpng.com/15/11/21/stop-sign-traffic-sign-clip-art-png-favpng-YVm6TAKXcApfNG5qQLT1Axke0.jpg");
/* Make the image fit into the element */
background-size:contain;
background-repeat:no-repeat;
}
/* This class gets dynamically added on mouse over */
.fancyImage.go {
background: url("https://theblogreaders.com/wp-content/uploads/2015/12/Go-298x300.gif");
background-size:contain;
background-repeat:no-repeat;
}
<!-- Don't use HTML event attributes or self-terminating tags.
See how much cleaner the HTML is now? -->
<div class="fancyImage stop">

How to trigger some javascript before CSS transition?

I have an element whose width increases when another element beside it is hovered over, i.e.
.div2 {
width: 0px;
display: none;
transition: width 2s;
}
.div1:hover ~ .div2 {
width: 100px;
}
I want to change the display to block on mouseover, but before the CSS transition. Then, similarly, I want to change the display back to none after the CSS transition finishes. I tried using .onmouseover to set the display to block, but it set it after the CSS transition.
Is there any way to set the display to block before the CSS transition?
As I understood your question, You can have two classes one for hidden (display :none) and another for visuallyHidden (may be visibility : hidden). On hover use visualy hidden class to get the css transition in effect(take help of JavaScript to add this class). You must take a help of setTimeout here (10 Ms ) should be fine to add another class which actually implements css transition. when it is un hovered you need to recycle logic again. hope it helps

clickable area of a button that scales down on click

I have an element which is acting as a button with a little Javascript and CSS. I'll strip it down to the most bare example, so you can see the problem. The issue originates from the fact that the element is scaled down when it's clicked. Javascript interprets the clickable area of the button as its scaled down size, not the original size. This occurs in all modern desktop browsers.
Here are the important parts. HTML:
<div id="refresh">more</div>
CSS:
#refresh {
background-color: #FFF;
cursor: pointer;
transition: all 150ms ease-out;
}
#refresh:active {
transform: scale(0.8);
}
JS:
var refreshBtn = document.getElementById("refresh");
function newImg() {
// updates an image elsewhere
}
// an event listener based on
// http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
addEvent(refreshBtn, 'click', newImg);
So my image gets updated when I click on the area occupied by the scaled down button, defined by transform: scale(0.8). If I click outside of that area, in the outer 20% of my button, my JS does not update the image. The proper click transitions occur and the cursor displays correctly as a pointer, but the JS does not count this area as part of the onclick event.
This was covered here, but I find the solution unappealing:
Non-clickable area on transforming anchor
The same solution is offered here:
increasing clickable area of a button
Here's the CSS I used as outlined in those answers:
#refresh:before {
position: absolute;
content: '';
top: -12%;
right: -12%;
left: -12%;
bottom: -12%;
}
These ensure that Javascript now recognizes a bigger clickable area instead of the scaled-down area, but in turn the pointer and the CSS hover effects now react to hovering and clicking well outside the original button element. I consider it an ugly solution. Surely someone else has run into this problem before. Are there any nicer solutions?
Update: Here is a jsfiddle of the situation I've explained: http://jsfiddle.net/cx9ur44e/4/
To solve the issue of the size, you would need to add the click even to a wrapper of the button that will keep the size even if the button is active.
<div id="wrapper>
<div id="refresh">more</div>
</div>

Animating divs in a set

I currently have a list of objects (projects) that are presented to the user initially as div's that have have a 100px x 200px height/width, position absolute, and float left. This list is contained within an angular ng-repeat method (not sure that makes a difference in the overall question but figured I'd add it in just in case it does). There could be 100s of these divs on the particular project listing page. Currently, I have the page setup so that if you click one of the projects, it's details come up in a modal dialog box. This functionality is fine per the requirements for my project but I'd like to add some "umph" to it by adding in an animation that does the following:
1) If you click on one of the projects, the box expands up to fill the parent container that contains all the projects
2) As the div grows to fill the space or when it's full sized, I want to expose the details of the project itself. Essentially, when the project is unselected, it's just a title/description showing. When it is selected, the project div goes full screen, exposes all of it's details, and shows it's editable fields in the full screen version of the div.
3) When the user closes that full screen div, I'd like it to go back to it's original state in it's original position.
I'm only using the latest version of Chrome for this project so it doesn't need to be a cross browser solution. I'd prefer to keep the animation as close to pure css as possible and would prefer to leave jquery out of it.
I currently have no experience with css3 animations but got a book on it that I hope can teach me about this eventually. However, I figured I would ask in the mean time in case someone can help me out soon so I can put this functionality in while still meeting my deadline for the functionality.
Thanks in advance!
Create a second CSS class that can be added to your div element when it is selected, and removed when it is not. Something like
div {
top: 100px;
bottom: 200px;
left: 100px;
right: 300px;
transition: all 1s; /* animate changes */
}
.active {
top: 0px;
bottom:0px;
left: 0px;
right: 0px;
}
.content {
display: none; /* hide the content unless active */
}
.active .content {
display: block; /* show the content when .active class is added */
}
Make sure that the parent container fills the entire window and is itself set to positiion: absolute or position: relative. There will be a lot more details to work out as you go, but that should give you a framework to get started. You can then add or remove the .active class as needed with JavaScript.

jQuery Mouseenter and mouseleave actions

I am using the following jQuery script:
$("#divid").mouseenter(function() {
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
$("#hldiv").mouseenter(function() {
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
As you can see, when the mouse hovers over a hyperlink called #hldiv, the #divid should be shown. The main goal is to keep the DIV shown if the mouse is over the DIV - but the #divid should not be visible initially.
If the mouse moves over the hyperlink, the DIV should appear, and when the mouse then moves over the DIV, it should stay until the mouse leaves.
The problem is that with my current code, when the user moves over the hyperlink and then out - the DIV appears/disappears correctly, but when the user moves out of the hyperlink and over the DIV itself, the DIV also disappears.
How should I fix this?
Why don't you add a container and do:
<div id='container'>
<a ID="hlDiv">hlink</a>
<div ID="divId">Test Test Test</div>
</div>
$(document).ready(function() {
$("#hlDiv").hover(function() {
$('#divId').show(1000);
})
$('#container').mouseleave(function(){
$('#divId').hide(1000);
});
});
fiddle here: http://jsfiddle.net/w68YX/8/
If I understood right, rewriting
$("#divid").mouseenter(function() {
$('#divid').stop(true);
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
Might help, since it stops the current animation (fading out) and fades it back in (if it has already turned a bit transparent).
However this depends on your HTML, and might not work in your case, so please post the structure also.
I am very late to this party - but there is a far better way to do this, so I want to add it for the sake of future browsers. You don't need jQuery for this effect at all.
First, wrap the two items in a container (here I'm using a div with class container), and apply a class to the item you want to appear/disappear on hove (here I'm using the show-on-hover class on the #divId element)
<div class="container">
<a id="hlDiv" href="...">link text</a>
<div class="show-on-hover" id="divId">popup stuff</div>
</div>
Next, set up your CSS as follows:
.container > .show-on-hover { display: none; }
.container:hover > .show-on-hover { display: block; }
#divId { /* whatever styles you want */ }
The effect is that the hover is now controlled entirely by CSS - but, it doesn't have the 1s transition you originally had. This is a little more complicated (and currently doesn't work in IE - but will be supported as of IE10).
Simply change the CSS as follows:
.container { position: relative; }
.container > .show-on-hover { opacity: 0.0; position: absolute; }
.container:hover > .show-on-hover { opacity: 1.0; }
.show-on-hover {
-webkit-transition: opacity 1s; /* Chrome / Safari */
-moz-transition: opacity 1s; /* Firefox */
-o-transition: opacity 1s; /* Opera */
}
The relative positioning on the .container means that the container sets its own bounding boxes for its child elements and their positioning. This means that when you then set the > .show-on-hover styling to position: absolute;, it will still be constrained to its parent (if you set left: 0; as an example, it will move to the left edge of the .container, rather than the screen).
The opacity toggle now simply makes the absolutely positioned item show/disappear wherever you've placed it (and you would update the CSS to put it exactly where you want, relative to the hyperlink). Because we're no longer using display: none - the DIV will always take up space on the screen - even when hidden (which is probably not what you want).
Finally - the last block, which sets transitions, tells modern browsers that whenever the opacity changes on elements of class .show-on-hover, make that change happen as a tween over 1s of duration.
Here is a jsFiddle showing the transitions: http://jsfiddle.net/TroyAlford/nHrXK/2
And here is a jsFiddle showing just the toggle: http://jsfiddle.net/TroyAlford/nHrXK/3/

Categories

Resources