Disable pointer-events only when dragging over an item - javascript

I have a container with dynamic content a user can interact with. It could be a YouTube video (iframe), amongst other things.
A user can drag and drop an image into this container and it'll replace the dynamic content with their image.
I'm aware that due to the dynamic content, drag events will behave erratically in the container, so I need to do pointer-events: none.
The HTML container has the following classes ant-upload-drag and ant-upload-drag-hover. The ant-upload-drag-hover class is only active when the image being dragged is on-top of the container.
I have CSS akin to the following where ant-upload-drag-container contains the dynamic content that I want unreachable by pointer-events:
.ant-upload-drag-hover {
.ant-upload-drag-container {
pointer-events: none;
}
}
Unfortunately, this doesn't work. It causes the container to behave erratically with the ant-upload-drag-hover class added and removed from the container over and over and over.
Meanwhile, the following works:
.ant-upload-drag {
.ant-upload-drag-container {
pointer-events: none;
}
}
Essentially, as long as .ant-upload-drag-container is always pointer-events: none; things work as expected, but if the pointer-events: none is triggered dynamically on hover, then things don't go as planned.
The following video demonstrates visually:
https://share.getcloudapp.com/ApuRgQlZ
The first example shows what is desired (when pointer-events is always none). The second example shows the current state (when pointer-events is dynamically shifted to always none).
I know this isn't much to go off of, but I'm not sure if I fundamentally misunderstand pointer-events: none, or if some React rendering shenanigans are happening.
Presumably, the moment ant-upload-drag-hover class is added to the element, the pointer-events: none would trigger, but it seems like for some reason pointer-events: none is also triggered on the container or something else must be happening for the container to lose the hover state and remove the class.

I'm not sure whether pointer-events: none interferes with the drag-and-drop events but it would explain your bug.
I'd suggest that you instead put a layer on top of the container that catches these events instead.
Here an example with a button and the layer is toggles (by a class) every 3 seconds.
// toggle class `ant-upload-drag-hover` every 3 seconds
setInterval(() => {
document.querySelector(".ant-upload-drag").classList.toggle("ant-upload-drag-hover");
}, 3000);
.ant-upload-drag-container {
position: relative;
}
.ant-upload-drag-hover .ant-upload-drag-container::before {
content: "";
display: block;
position: absolute;
z-index: 999;
height: 100%;
width: 100%;
/* the rest is just for aesthetics: */
content: " .ant-upload-drag-hover";
background: rgba(255, 255, 255, .5);
cursor: not-allowed;
}
button {
padding: 50px 100px;
}
button::before {
content: "Click here: ";
}
<div class="ant-upload-drag">
<div class="ant-upload-drag-container">
<button onclick="++this.textContent">0</button>
</div>
</div>

Related

CSS how do I add transition to my modal using 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.

How to center <div> inside a <button>?

I have a round < button > with a < div > inside that represents a Unicode image. Currently the button is set to border-radius: 12px; height: 24px; and width: 24px; and the < div > is to font-size: 17px. The < div > Unicode image sits inside but not centered and the button is slightly off to the side.
How can I get the < div > to center inside an oval button despite what font-size the < div > is?
EDIT
I want to create a circle/round button with an emoji center to the middle of the button despite the button's size or the emoji image's size.
CSS for the button and emoji image for div:
#emoji-button {
border-radius: 19px;
width: 38px;
height: 38px;
}
#thumb-emoji:after {
content: "\01F44C";
font-size: 20px;
}
And round/circle button with emoji image inside:
<button
type="submit"
id="emoji-button"
>
<div id="thumb-emoji"></div>
</button>
But it is not centered.
And is there a way to just back the emoji image alone to be clickable for a method?
First off:
A <div> is a block element by nature. It will always become 100% wide. If you want it to not be 100% wide, give it a display:inline-block so it won't get bigger than it needs to be. Then give it a margin:0 auto; or a text-align:center on the parent to center it.
HOWEVER, You are not allowed to put <div>s inside of <buttons>. it is invalid HTML
See this answer for more information:
Why can't a <button> element contain a <div>?
Or, you could read here, from W3 that only phrasing content is expected to be used within a button:
https://www.w3.org/TR/2012/WD-html5-20120329/the-button-element.html#the-button-element
If you do not know what phrasing content is, See this page:
https://www.w3.org/TR/2012/WD-html5-20120329/content-models.html#phrasing-content
-- if you are looking into styling buttons specifically, maybe this very short tutorial would help:
http://web.archive.org/web/20110721191046/http://particletree.com/features/rediscovering-the-button-element/
Here is a fiddle of a working button like yours:
https://jsfiddle.net/68w6m7rr/
I honestly didn't have many problems with this. I only replaced your <div> with a span, that's it.
can you post your code?
You should NOT need a div inside the button. If you need the button to have a specific style give it a class. You could do something like this
CSS:
button.something {
padding: 25px;
border-radius: 100%;
font-size: 20px;
border: none;
}
HTML:
<button class="something">👌</button>
For clean and valid code, you'd better use a :before or :after pseudo-element. This would also take care of the centering by default.
It's even easy to set the content. Either in css only, like this:
1.
button:before {content:"\25b6";}
(put your unicode value there and classes/ids as needed, then specify them in turn in css)
2.
Or if you need to specify the value in mark-up, drop a custom data-* attribute like this:
<button data-myunicode="\25b6"></button>
with each button taking it's own value, then drop this single line in css:
button:before {content:attr(data-myunicode);}
Before answering, let's clear some things out.
div is a block level element, used in an inline element, which is the button element. Browsers will consider this invalid and will fix it by removing the block element from the inline element. For more about CSS concepts like box model, box generation please refer to these resources:
https://developer.mozilla.org/en/docs/Web/HTML/Block-level_elements#Block-level_vs._inline
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Visual_formatting_model
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model
Also, if you are using an IDE, make sure you have installed linting/hinting tools to help you out. These tools can help you in code authoring so, make sure you have them. If you are using software like VSCode or Sublime Editor, there are many free code analysis tools out there.
Let's go back to the code now.
You said
I want to create a circle/round button with an emoji center to the
middle of the button despite the button's size or the emoji image's
size.
I went ahead and created a plunk here where I demonstrate this. Essentially, I wrapped the button around a div which serves as a container and through some CSS magic, I made it to have the same height as its width. More on that you can find at this SO answer.
The #emoji-button then has a border-radius: 100% in order to be round, width is inherited from the parent, meaning it has the same as the container and it position is absolute in order to fit in the container.
The #thumb-emoji has changed to a span element. By user agent styles it has text-align:center.
<div class="button-group">
<button type="submit" id="emoji-button">
<span id="thumb-emoji"></span>
</button>
</div>
CSS:
.button-group {
position: relative;
width: 100px;
}
.button-group:before {
content: "";
display: block;
padding-top: 100%;
}
#emoji-button {
width: inherit;
border-radius: 100%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#thumb-emoji:after {
content: "\01F44C";
font-size: 200%;
}
You can change the .button-group width to whatever width you want, it will still keep its 1:1 ratio.
You can use then media queries on .button-group to adjust the font-size of your #thumb-emoji, by setting your desired breakpoints.

How to MouseOver behind an object?

I'm trying to mouseover an image which is behind an another image.
Is there any way to render the front image like it is not there, so I can mouseover the other image behind it?
Example can be seen here:
I can't mouseover the characters which are behind the logo boundingbox.
You can set the CSS property pointer-events: none on the obstructing object... but be aware that pointer events are all or nothing; mouseovers and hovers will pass right through, but so will clicks.
Here is a description of the value, from the Mozilla Developer's Network:
none: The element is never the target of mouse events; however, mouse events may target its descendant elements if those descendants have pointer-events set to some other value. In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases.
I've put together a little example. In this example, I'm using onmouseover and onmouseout, since that's what you use on your website, but you could just as easily use the CSS :hover pseudo-selector. Here's a jsfiddle version of the example, and the stack snippet is below.
.hoverable {
width: 100px;
height: 100px;
background-color: blue;
}
.obscuring {
/* this first line is the important part */
pointer-events: none;
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background-color: red;
opacity: 0.5;
}
<div class="hoverable" onmouseover="this.style.backgroundColor = 'green'" onmouseout="this.style.backgroundColor = 'blue'"> </div>
<div class="obscuring"> </div>
You can create some invisible divs on top of the whole thing and put the hover behaviour on them. Then control the characters position with the position of the invisible divs.
Hope it makes sense.

Animating the "body" tag in jQuery does nothing

So one of the buttons on my site's nav bar brings down a small grey tab from the top which tells you about the site. Here is the code I'm using for the animations:
var aboutMenu = function(){
$(".aboutButton").click(function(){
$("body").animate({top: "42px"}, 200);
$(".about").animate({top: "0px"}, 200);
});
}
$(document).ready(aboutMenu);
The idea is that the body of my website, along with all its content, moves down 42 pixels. This is whilst the content in the "about" class moves down so that it's visible on the screen. If you do click on the "About" button, all that happens is the grey tab moves down, but the body stays where it is. This would not usually be a problem, except the tab obscures the rest of the nav bar.
Here is some more relevant code (if needed):
HTML:
<div class = "about">
<p align = "center">placeholder text</p>
</div>
and the actual link:
<li> <a class = "aboutButton">About this website</a></li>
CSS:
.about{
background-color: gray;
top: -42px;
height: 42px;
position: fixed;
}
.about p{
color: white;
}
.aboutButton{
cursor: pointer;
}
As mentioned in my comment, to be able to animate top (or other positions for that matter), you need to set a position: ... (e.g. position: relative;.
You could try using a different way to call your function, e.g. add this attribute to your link: `onClick(aboutMenu())
Also try putting an allcontent div around everything and animating that, body tags aren't that good for animations

using jQuery slideUp causes "jumpy" interface

On the demo link below, I am using jQuery slideUp and you will notice after it slides up, there is a quick jump of the content.
Do you know why this is? My html is valid (with the exception of the select option not having a label attribute..which I am still figuring out...). Do I have something positioned incorrectly?
http://demo.phppointofsalestaging.com/index.php
(Click login --> Sales -->Show Item Grid THEN Hide Item Grid to see the bug)
this inline style
<div style="margin-top: 39px;" id="content">
and line 724 of unicorn.css
#content {
...
margin-top: -39px;
...
}
... are conflicting with each other.
If you remove both, the page doesn't jump.
You have set a margin-top on the content div of 39px. This is only visible when you slide down the item grid. It seems to 'jump' when sliding back up because of this margin. Try setting the margin to 0px;
<div id="content" style="margin-top:0px;">
I played around a little bit and this is being caused by the margin-top:39px on your #content div, if you remove that and use top:39px instead of margin-top:39px on the #content element instead it doesn't jerk either - but it also causes the button to jump a bit on slideUp and slideDown so you will need to tweak the css of the button wrapper area like so:
To fix the button jumping issue:
#show_hide_grid_wrapper {
position: relative;
text-align: right;
padding: 10px;
}
As prev. answers mention, you have margin-top 39px on #content. Setting it to 0 will solve the problem, but it will also remove your beautiful dark gray section above the content. To get it back, add this to your CSS:
#content:before {
content: '';
display: block;
width: 100%;
height: 39px;
background: YOUR GRAY COLOR;
}

Categories

Resources