Disabling pointer events only on a child element through CSS only - html

I'm working on a userscript for a page, so I don't have control over the original HTML. Also, because of the way the page loads and the script works, for various reasons I can only use CSS modifications here, and the modifications can only be on page-level CSS (not per-element style attributes).
So, the issue is, there is a large a element that has a hierarchy of divs in it. I would like to disable pointer events only on one of the child divs, while leaving everything functioning as normal everywhere else on the a. For example:
const disableBottomPointerEventsStyle =
'.bottom { pointer-events: none; cursor: default; }';
$('#test').click(function () {
$('<style/>')
.attr('type', 'text/css')
.text(disableBottomPointerEventsStyle)
.appendTo(document.head);
$(this).toggle();
});
.link { display: flex; width: 10ex; height: 20ex; margin-bottom: 1ex; }
.wrapper { display: flex; flex-direction: column; }
.top { border: 1px solid red; }
.bottom { border: 1px solid blue; }
div { flex-grow: 1; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- example of page structure: -->
<a class="link" href="about:blank">
<div class="wrapper">
<div class="top"></div>
<div class="bottom"></div>
</div>
</a>
<!-- ========================== -->
<button id="test">Test</button>
In that example there is an a with some divs in it, and the goal is to disable pointer events only on the blue div on the bottom while leaving everything else as-is.
To use the example press the Test button; this will insert a style rule in the document. My current best attempt is the value of disableBottomPointerEventsStyle:
.bottom { pointer-events: none; cursor: default; }
This has no effect.
So my question is, is it possible to do this only by modifying a page-wide CSS rule and, if so, how?
Note that this is fundamentally a CSS question, the JavaScript is pretty much incidental here.

The secret is to disable natural a behaviour, and enable it in the child.
I used hardcode a.link - to minimise a risk of side effects.
Supported https://caniuse.com/?search=pointer-events - should be good.
.link { display: flex; width: 10ex; height: 20ex; margin-bottom: 1ex; }
.wrapper { display: flex; flex-direction: column; }
.top { border: 1px solid red; }
.bottom { border: 1px solid blue; }
div { flex-grow: 1; }
a.link{ pointer-events: none}
div.top{ pointer-events: auto}
<a class="link" href="about:blank">
<div class="wrapper">
<div class="top"></div>
<div class="bottom"></div>
</div>
</a>

Related

Disable the div plus change the cursor

I have div element which I need to disable. So I have defined the following CSS class for it:
.hideDiv {
pointer-events: none;
cursor: not-allowed;
}
While the first line of the CSS class works fine, the second line does not. Can you help me with this?
Please note that I need to get this work on Internet Explorer.
pointer-events: none will effectively stop mouse interactions with .hideDiv. This means that the action of hovering over the div will also be prevented, thus making the cursor not appear.
Instead, you can wrap your .hideDiv in another div, and add the cursor property to the outer/parent div.
See example below:
.box {
height: 100px;
width: 100px;
border: 1px solid black;
}
.parent {
cursor: not-allowed;
}
.hideDiv {
pointer-events: none;
}
/* Remove pointer-events: none and the below css works */
.hideDiv:hover {
background-color: lime;
}
<div class="parent box">
<div class="box hideDiv">
</div>
</div>

Avoid using the !important css attribute for showing my container

I show/hide a container with boxes inside as showed below.
I use a simple mechanism with toggleClass to show/hide the container.
$("#btn").click(
function () {
$("#switch-apps-panel").toggleClass('flex-apps-panel');
}
);
The problem is I had to use the important attribute on the css and I prefer to avoid it.
.flex-apps-panel {
display: flex !important;
}
Any help on slightly changing my code to avoid using the important attribute ?
jsFiddle: https://jsfiddle.net/hg60e8gf/
You defined switch-apps-panel as an ID. IDs are always higher ranked and more specific than class names.
In order to get rid of your !important statement, either change the ID to a class or make your selector more specific and add the ID selector to your .flex-apps-panel like this:
#switch-apps-panel.flex-apps-panel {
display: flex;
}
Here I changed it to be a class:
$(document).ready(function() {
$("#btn").click(
function() {
$(".switch-apps-panel").toggleClass('flex-apps-panel');
}
);
});
.switch-apps-panel {
display: none;
z-index: 9999;
position: fixed;
top: 70px;
left: 10px;
background-color: white;
border: 1px solid #b6b6b6;
box-sizing: content-box;
box-shadow: 0 1px 15px rgba(0, 0, 0, .4);
padding: 10px 10px 10px 10px;
}
.flex-apps-panel {
display: flex;
}
.box-1 {
margin: 8px;
width: 100px;
background-color: yellow;
}
.box-2 {
margin: 8px;
width: 100px;
background-color: blue;
}
.box-3 {
margin: 8px;
width: 100px;
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
By default, boxes are hidden.
<button id="btn">Click here to show/hide boxes</button>
<div class="switch-apps-panel">
<div class="box-1">
<span>First</span>
</div>
<div class="box-2">
<span>Second</span>
</div>
<div class="box-3">
<span>Third</span>
</div>
</div>
You need to increase your selector's specificity. ID selectors have higher specificity than class selectors, so you can just try to select your ID with class like this:
#switch-apps-panel.flex-apps-panel {
display: flex;
}
You can read more about specificity on MDN, and also try to avoid styling by IDs in the future.

How to call another class on hover in CSS?

The class of DIV is FIRST. I want to call class SECOND on hover. How can I do this?
I am using following code:
.first{
background:#F00;
}
.second{
background: #0F0;
}
<div class="first"> This is DIV</div>
You don't need to use an additional class, just add the additional style on hover using the pseudo-selector :hover
<style>
.first{
background:#F00;
}
.first:hover{
background: #0F0;
}
</style>
As i am very kind, i have added an example of how to do what you are asking in pure javascript also:
<style>
.first{
background:#F00;
}
.second{
background: #0F0;
}
</style>
<div class="first" onmouseover="change()" onmouseout="changeBack()"> This is DIV</div>
<script>
function change() {
var d = document.getElementsByClassName("first");
d[0].className += " second";
}
function changeBack() {
var d = document.getElementsByClassName("first");
d[0].className = "first";
}
</script>
Your above way is not correct to do what you are looking for.
Check the below to know how to do it.
Live demo
The HTML code:
<div class="first"> This is DIV</div>
The CSS Code:
.first{
background:#F00;
}
.first:hover{
background: #0F0;
cursor: pointer;
}
Explanation
You need to declare :hover to create hover effect. So instead of creating a new class, you need to add :hover i.e a pseudo class to the class where you want the hover to work. This will make the hover effect you are looking for.
Reference:
W3 Hover reference
Hope this helps.
You can style an element (with a certain class) when another one is hovered in a limited number of cases. Main constraint: the hovered element must be placed in HTML code before the styled one.
More about + and ~ the adjacent and general sibling combinators
.first{
background:#F00;
}
.second{
background-color: #0F0;
}
.first:hover ~ .second {
background-color: tomato;
}
.first:hover ~ .hello .second {
background-color: violet;
}
.hello {
background-color: beige;
}
.hello {
padding: 1rem;
}
<div class="first"> This is DIV</div>
<div> Some div</div>
<div class="second"> I've class .second</div>
<div class="hello">
<div class="second"> Child of a (following) sibling of .first</div>
</div>
Hover the first box to see the result
This is how you would do it in javascript.
document.getElementById('idOfElement') is getting element reference.
Adding an event on it. In your case, you need two events which is onmouseover and onmouseleave.
let first = document.getElementById('first'),
sec = document.getElementById('second');
first.onmouseover = () => {
sec.style.background = 'black';
}
first.onmouseleave = () => {
sec.style.background = 'red';
}
#first, #second {
height: 100px;
width: 100px;
background: red;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s linear;
}
<div id="first">first</div>
<div id="second">second</div>
You can also do this on css. However, this is limited. You can't get reference to your parent element and previous sibling elements. That's what I know. (correct me if I am wrong).
#first, #second {
height: 100px;
width: 100px;
background: red;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s linear;
}
#first:hover ~ #second {
background: black;
}
<div id="first">first</div>
<div id="second">second</div>
Hope it helps. Cheers

Changing color of link on hover of a div

I'm trying to change the color of a link on hover of a <div>. Is that possible using just CSS? If not, how would I achieve this?
div {
border: 1px solid black;
padding: 15px;
}
div:hover {
color: red;
}
<div>
<a href='www.google.com'> www.google.com </a>
</div>
You need to style the anchor, not the div. Try this:
div {
border: 1px solid black;
padding: 15px;
}
div:hover a {
color: red;
}
<div>
<a href='www.google.com'> www.google.com </a>
</div>
The div itself has no text, so there's no place to apply the color property. So when you hover a div with nothing to color, nothing happens.
As mentioned in another answer, apply the hover to the anchor element, which contains text.
But your original code would work if instead of color you used background-color or border.
div {
border: 1px solid black;
padding: 15px;
}
div:hover {
color: red; /* won't work; nothing to color */
background-color: aqua; /* this will work */
border: 2px dashed #777; /* this will work */
}
<div>
<a href = 'www.google.com'> www.google.com </a>
</div>
rjdown's answer is correct, but the question is if you still need the div at all.
All a div does is provide a block for you to style. If you style the anchor as block, you have just that. Code bloat is bad for your SEO and headache-freeness. ;-)
Try this:
a:link {
display: block;
/* make it act as the div would */
overflow: auto;
/* or what you want, but good practice to have it */
border: solid 1px black;
}
a:hover,
a:focus,
a:active {
border: solid 1px red;
}
<a href='www.google.com'> www.google.com </a>
Remember to use more than a color change on your hover or the 1 in 12 males with color blindness won't see a thing, potentially, happening. The focus and active additions are for accessibility too. Especially focus is very important for keyboard users.
Good luck.
We can simply assign inherit value to all the CSS properties of anchor tag ,
Thus when you hover above its container DIV element , it will inherit all the new properties defined inside DIV:hover.
div {
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
height: 100px;
width: 100%;
color: white;
background: blue;
}
a {
text-decoration: inherit;
color: inherit;
}
div:hover {
color: orange;
}
<div>
www.google.com
</div>

CSS Cursor with !important gets overridden by defaults

I have the following code that sets a class of dragging-something to the html element on a page on a trigger. The class does the following:
html.dragging-something {
cursor: -moz-grabbing !important;
cursor: -webkit-grabbing !important;
cursor: grabbing !important;
}
That all works, until I move my mouse over another element that changes the cursor. (Like an input field)
How do I make it so my dragging-something class does not get overridden by anything else that might change the cursor?
jsFiddle (Problem): https://jsfiddle.net/BoxMan0617/jndukr86/
jsFiddle (Solution): https://jsfiddle.net/BoxMan0617/jxesdzqf/ (Thanks to #humble.rumble)
[Solved]
You need to apply it to the elements contained within the HTML tag not just the HTML tag
html.dragging-something * {
cursor: -moz-grabbing !important;
cursor: -webkit-grabbing !important;
cursor: grabbing !important;
}
I personally try to avoid using !important as often as I can. Instead I give structuring and specificity of rules a shot: http://jsfiddle.net/vy599pa2/
<div class="move">
<div class="pointer">
</div>
</div>
<div class="pointer">
div {
width: 150px;
height: 150px;
padding: 30px;
background-color: grey;
border: 2px solid black;
}
div div {
padding: 0;
background-color: lightblue;
}
div + div {
margin-top: 10px;
}
.pointer,
.pointer * {
cursor: pointer;
}
.move,
.move * {
cursor: move;
}