make :before not clickable in Firefox - javascript

I am working on an image uploader. I have a drag and drop field for the image using https://codecanyon.net/item/slim-image-upload-and-ratio-cropping-plugin/16364167?ref=pqina&ref=pqina&clickthrough_id=749572872&redirect_back=true . But I want the dropzone to have an image as an overlay of the dropzone. I managed to do this with a :before element. It works as intended in Chrome and even in Edge. But in Firefox I can't click the dropzone behind the :before Element. Is there any way to fix that?
Very simplified example here:
Simplified :before:
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
}
https://jsfiddle.net/6kv6u9kv/
I want the "click me" to be clickable. I appreciate any quick help because this is for work. Thanks in advance!

SOLUTION:
You can use pointer-events: none; css property in your overlay.
The pointer-events property allows for control over how HTML elements
respond to mouse/touch events – including CSS hover/active states,
click/tap events in Javascript, and whether or not the cursor is
visible.
CODE SNIPPET:
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
z-index: 100000;
pointer-events: none;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>

pointer-events: none is an obvious choice though has less browser support.
Here is another way
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
position: relative;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 0;
left: 0;
opacity: .5;
-moz-opacity: 0.5;
}
.dropper a {
position: relative;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>

You can use the css pointer-events style to tell the browser to, as the name suggests, ignore any pointer events. This includes blocking pointer events to elements it may cover.
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
z-index: 100000;
pointer-events: none;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>
Of course check the browser support. If you are targeting a browser that does not support it you would have to implement some forwarding system: capture the click on .dropper get the mouse x,y and for any element occupying the same coordinates trigger the event for that element.

Related

Show/hide floating div by click on right side of the screen

I need to make a floating div that appears to be almost hidden and if I click in the tab it appears to the left. Floating over the rest of the site. I don't know if I made myself clear, so I put here two images, how it should look hidden and visible. But I couldn't figure it out yet how to make it. Any help will be appreciated.
I work with VueJS.
This is a vanilla js implementation that uses fixed position, the css transition property for animation, and a class that is toggled when the handle is clicked to change the position.
const slideout = document.querySelector('.slideout')
const handle = slideout.querySelector('.handle')
handle.onclick = function() {
slideout.classList.toggle('active');
}
.slideout {
position: fixed;
width: 80%;
height: 80%;
left: 100%;
top: 10%;
transition: left .3s ease-out;
}
.slideout.active {
left: 10%;
}
.handle {
position: absolute;
top: 10px;
left: -20px;
width: 40px;
height: 40px;
border-radius: 50%;
background: darkred;
cursor: pointer;
}
.body {
position: absolute;
background: red;
width: 100%;
height: 100%;
border-radius: 8px;
}
<div class="slideout">
<div class="handle"></div>
<div class="body"></div>
</div>

text selection on a element behind an absolute element

I have an overlay element that hides other div's that contains text.
the overlay element is absolute positioned.
I want the user to be able to select a text on those div's behind.
My solution was to hide the overlay (display: none) on user event mouseDown and show it again when the mouseUp event occurred.
that way as soon as the overlay is hidden the user can select the text (as long as the mouseUp hasn't occurred yet).
This solution seems to work on chrome and safari but not on firefox, any advice?
You could use pointer-events on the element you want to click "through":
pointer-events: none;
It may need prefix in some browsers.
Examples: Here without pointer-events: none, you can't select the text:
#outer {
width: 100px;
height: 100px;
display: inline-block;
border: 1px solid black;
position: relative;
}
#inner {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
opacity: 0.5;
background-color: yellow;
}
<div id="outer">
Testing 1 2 3
<div id="inner"></div>
</div>
Here with pointer-events: none, you can:
#outer {
width: 100px;
height: 100px;
display: inline-block;
border: 1px solid black;
position: relative;
}
#inner {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
opacity: 0.5;
background-color: yellow;
pointer-events: none;
}
<div id="outer">
Testing 1 2 3
<div id="inner"></div>
</div>
You need help with javascript
https://codesandbox.io/s/jovial-hodgkin-jqrsp
Disable pointer-events when mouse is down.

Show overlay fullscreen div then hide it by clicking on it

I'm new to the html/css/jquery languages, so please pardon me if my question seems too obvious.
My aim is to make a fullscreen overlay div appear when clicking on a div (this step actually worked with the toggle function) and then make this same div disappear by just clicking on it.
I've browsed many related topics but I can't seem to find a way to resolve my issue. How can I make the full screen div disappear by clicking anywhere on it (clicking back on the first div is not an option since it's intentionally hidden)?
Here's my code so far:
JavaScript (jQuery):
$(function() {
$("#bandeau").click(function() {
$("#full_screen").toggle();
});
});
HTML:
<div id="bandeau">content</div>
<div id="full_screen">
<div class="info_visible" id="about">content</div>
</div>
CSS:
#bandeau {
background-color: black;
overflow: hidden;
cursor: crosshair;
width: 100%;
height: 57px;
z-index: 1000;
position: fixed;
}
#full_screen {
background-color: black;
overflow: hidden;
cursor: crosshair;
width: 100%;
height: 100%;
z-index: 1000;
position: fixed;
display: none;
margin: 0px;
padding: 0px;
}
.info_visible {
width: 100%;
height: auto;
color: white;
padding-top: 10px;
padding-bottom: 20px;
padding-left: 30px;
position: fixed;
}
Pure CSS solution with undercover checkbox:
html {
width: 100%;
height: 100%;
background: lavender;
text-align: center;
font-family: arial, sans-serif;
}
input {
display: none;
}
#target {
display: none;
}
#click:checked ~ label > #target {
position: fixed;
top: 0;
left: 0;
display: inline-block;
height: 100%;
width: 100%;
background: url('http://i.imgur.com/bv80Nb7.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.item {
position: fixed;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
}
#warning {
position: fixed;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
}
<input type="checkbox" id="click" name="click" value="click" />
<label for="click">
<p class="item"><b>CLICK HERE</b></p>
<div id=target><h1 id=warning>FULLSCREEN CONTENT</h1></div>
</label>
This will toggle full screen on or off
https://jsfiddle.net/42atLz1g/1/
$("#bandeau, #full_screen").click(function(){
$("#full_screen").toggle();
});
Below is a simple and easy way to do it with one command and full explination. Enjoy and welcome to website development!
Note: scroll to end of answer to see a short list of helpful links
// this is simply jQuery shorthand for document.ready = function ...
$(function(){
// this is how to dynamically assign events
// why is this important? let's say, in the future,
// you decide to add elements after the page is loaded,
// this allows the NEW elements to still use the same events you've assigned
$(document)
// .on and .off are as simple as they appear,
// on adds an event to a group of elements and off removes
// as you'll notice, I assign just one method to both elements
// the reason is this move is extremely simple
// all you need is to have one element hide or show, based on
// clicking one of the divs
.on('click', '#bandeau, #full_screen', function(e) {
// .toggle accepts a booleen argument
// if true = show, if false = hide
// thus i simply test the id name within the parameter!
$('#full_screen').toggle(this.id == 'bandeau');
})
});
#bandeau{
background-color: black;
color: green;
overflow: hidden;
cursor: crosshair;
width:100%;
height: 57px;
z-index: 1000;
position: fixed;
}
#full_screen {
background-color: black;
overflow: hidden;
cursor: crosshair;
width: 100%;
height: 100%;
z-index: 1000;
position: fixed;
display: none;
margin: 0px;
padding: 0px;
}
.info_visible {
width:100%;
height: auto;
color:white;
padding-top: 10px;
padding-bottom: 20px;
padding-left: 30px;
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bandeau">content</div>
<div id="full_screen">
<div class="info_visible" id="about">tnetnoc</div>
</div>
See more about jQuery Dynamic Events here (.on) && here (.off)
More you should read about dynamic entry
.toggle()
Try to replace your jQuery code with this
$(function(){
$("#bandeau").click(function(){
$("#full_screen").show();
});
$("#full_screen").click(function(){
$(this).hide();
});
});

On display of hidden element it shows on wrong place because of scroll, only in chrome

I don't realy know how to explain this thing in short sentence.
I don't know if it is bug or not..
In parent div with fixed height and overflow-y scroll, I have multiple children elements, which has jquery function click, what displays hidden element in these divs. When I scroll down to last div, after click, hidden element displays in wrong place.
I tried to search for this problem, cause it should be pretty common. But nothing came up.s
It's realy hard to explain with words. Just look at this jquery example with mozilla and after that with chrome.
https://jsfiddle.net/zvwcdzjz/2/#
P.S. I need my original example work and look exactly the same on chrome and mozilla, cause right now on mozilla everything looks exactly as i want it to be, but it bugs on chrome.
It can be solved with jQuery too, makes no difference for me.
HTML:
<div id="el">
<div class="content">
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
</div>
</div>
CSS:
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
#el .content {
width: 300px;
height: auto;
}
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
}
.button {
background-color: blue;
color: #fff;
cursor: pointer;
text-align: center;
margin-top: 90px;
float: left;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
margin-left: 300px;
background-color: red;
display: none;
}
JS:
$(function(){
$(".button").click(function(){
$(this).parent(".block").children(".blocktoopen").show();
});
$("#el").scroll(function(){
$(".blocktoopen").hide(); });
});
The set height of #el was causing the red box to appear in the incorrect location. I have removed this. See the example below:
Change:
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
To:
#el {
width: 300px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
And then you're good to go.
To make your life simpler make the parent .bloc relative so the blocktoopen will be computed relatively. Will help with the responsiveness.
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
position: relative;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
bottom: 50%;
background-color: red;
display: none;
right: 0;
}
I can't post comment so here is another try with jsfiddle. I am not sure if you have horizontal scroll as well. remove margin-right from .blocktoopen and add right:0; Also wrap all your internal content inside a div and set the width to maybe 225px
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
#el .content {
width: 300px;
height: auto;
}
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
position: relative;
}
.button {
background-color: blue;
color: #fff;
cursor: pointer;
text-align: center;
margin-top: 90px;
float: left;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
display: none;
top: 50%;
bottom: 50%;
right: 0;
}
.internal{
width: 225px;
}
Have you tried to click on 2 buttons without scrolling? Try it. Looks like you were using visibility: hidden; and not display: none;. Maybe trying to set the position: relative; ...
Just seen the jquery script. Show() and hide() appears to work as visibility css property.
If u look with Chrome DevTools the jsFiddle example you will see that you can't see the red boxes but they are still there.

Element z-index css property

I have 3 elements, two on the same level, and one child, all having fixed position. I need to set the z-index properties to place the parent on the bottom, the element on the same level in the middle, and the child on top.
I've tried setting a higher z-index for the child, but it's not working.
<div class="red">
<div class="blue"></div>
</div>
<div class="green"></div>
Here is the case http://jsfiddle.net/udENm/21/ (I need red on the bottom, green in the middle and blue on top, still maintaining red and greenon the same level).
My CSS is like this
.red {
position: fixed;
z-index: 2;
}
.green {
position: fixed;
z-index: 2;
}
.blue {
position: fixed;
z-index: 5;
}
Set your positioning to absolute and remove the z-index from the parent div (the red one) entirely. http://jsfiddle.net/calder12/udENm/32/
.foo {
background: red;
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: absolute;
left: 100px;
top: 100px;
z-index: 2;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: absolute;
left: 40px;
top: 40px;
z-index: 5;
width: 50px;
height: 50px;
}
​
The z-index property only has effect within the stacking context of the containing element.
Put another way, given a bunch of block elements within the same parent element, you can control their front to back ordering pretty easily. However, z-index can only control the front to back ordering within this parent element and not within the global context.
So, you can move .blue backwards and forwards within .red all you like. You can also switch .red and .green around in the z-plane all you like too. However, you can't put .green between .red and .blue because they are in different stacking contexts.
EDIT
Stacking context only applies to elements that are in the flow. If you use position:absolute, then you can do this. See Rick Calder's answer
The green blocks z-index needs to be lower than the red ones. I used this CSS instead of the one you posted:
.foo {
background: red;
position: fixed;
left: 50px;
top: 50px;
z-index: 2;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: fixed;
left: 100px;
top: 100px;
z-index: 1;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: absolute;
top:50%;
left:50%;
z-index: 5;
width: 50px;
height: 50px;
}
Works fine, as you can see green is now z-index 1, red is z-index 2 and the blue block has absolute positioning.
Z-index is relative in a way to the parent. Red is already at 2, and blue is only at z-index 5 compared to it's siblings, but not to outside elements like Green.
Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.
Kinda like this?
http://jsfiddle.net/kBv7R/
HTML
<div class="foo">
<div class="child"></div>
<div class="bar"></div>
</div>
CSS
.foo {
background: red;
position: fixed;
left: 50px;
top: 50px;
z-index: 2;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: fixed;
left: 100px;
top: 100px;
z-index: 5;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: fixed;
left: 90px;
top: 90px;
z-index: 6;
width: 50px;
height: 50px;
}
​

Categories