How to add hover effect to img placed in parent container - html

How can I add a hover effect to the img after mouse is over link Text using CSS?
<div class="myTextContainer">
<p>
<a href="#">
<img height="128" width="128" title="icon1" alt="icon1" src="icon1.png" ">
</a>
</p>
<h2>
Text
</h2>
</div>

Try adding some JavaScript. In my case i added html attribute onmouseover and onmouseleave to call a javascript function. fun1 on hover and fun 2 onleave. I added id hover on my image and i said on each function to get the element of the id hover which is my image and change the backgroundColor='blue'. On hover i set it to blue and onleave i set it to red. You can change other elements like the src by doing style.src='here/put/the/image/source/img.png' and add different src on hover or leave. If you need more info leave a comment. Did this help?
function fun1(){
document.getElementById("hover").style.backgroundColor='blue';
}
function fun2(){
document.getElementById("hover").style.backgroundColor='red';
}
#hover{
background-color:red;
}
<div class="myTextContainer">
<a href="#">
<img id="hover" height="128" width="128" title="icon1" alt="icon1" src="icon1.png">
</a>
<h2>
Text
</h2>
</div>
-------- Or by doing this without script tag or file --------
#hover{
background-color:red;
}
<div class="myTextContainer">
<p>
<a href="#">
<img id="hover" height="128" width="128" title="icon1" alt="icon1" src="icon1.png">
</a>
</p>
<h2>
Text
</h2>
</div>

Change your HTML markup and put both, icon and text into one link.
<h2>
<a>
<img ...>
TEXT
</a>
</h2>
Than you can use simply
a:hover {color: red;} /* red text 'TEXT' */
a:hover img {border: 1px solid green}

Since h2 and p are siblings but you want to add hover on h2 img which is before p, you cannot do it with CSS. You need javascript:
document.querySelectorAll('a')[1].addEventListener('mouseover', fn, false);
document.querySelectorAll('a')[1].addEventListener('mouseout', fn2, false);
function fn(e) {
if(e.target.innerHTML == 'Text') {
document.querySelector('img[src="icon1.png"]').className = 'hover';
}
}
function fn2(e) {
if(e.target.innerHTML == 'Text') {
document.querySelector('img[src="icon.png"]').className = '';
}
}

you could declare:
.myTextContainer a:hover img {
// your CSS
}

Related

jQuery Change image depending on the link data-key in each parent

I have a section 2 blocks: one - with 3 images, second - with 3 links. Each image has it's own class (class=".img1") that is connected to a definite link with datakey=".img1".
When I hover over each link the definite image is being shown.
The section is a repeater block, that has a loop of images inside (I use ACF for this).
So when I have multiple sections on the page, the link hover from one section changes images in all other sections.
I was trying to use .each() to specify the parent section and then call .hover for links, but it doesn't work the way I need. I'm stuck in this and seems need to use another option.
JSfiddle with 1 section - https://jsfiddle.net/vernigoranataly/Lnwmjq3c/42/
JSfiddle with 2 sections - https://jsfiddle.net/vernigoranataly/kLtz5v4c/4/
JS:
$('.section_product-category ').each(function() {
$('.prodcat_btn .button-link').hover(
function() {
$($(this).data("key")).addClass('active');
$($('.prodcat_btn .button-link').not(this).data('key')).removeClass('active');
},
function() {
$($(this).data("key")).removeClass('active');
$($('.prodcat-img1')).addClass('active');
}
);
});
HTML:
<section class="section_product-category ">
<div class="prodcat_imgs">
<div class="prodcat_img prodcat-img1 active">
<img width="720" height="970" src="https://i.postimg.cc/k4pHm2DW/CTA-image.png" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img2">
<img width="345" height="480" src="https://i.postimg.cc/GhwC8fhG/visit-us-wine-glass.jpg" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img3">
<img width="1035" height="1440" src="https://i.postimg.cc/3NLm6GRH/social-image-three.jpg" class="attachment-full size-full">
</div>
</div>
<div class="prodcat_text">
<h2>Category #1 links</h2>
<div class="prodcat_btn btn">
<a class="button-link" data-key=".prodcat-img1" href="https://google.com">Link text here</a><br>
<a class="button-link" data-key=".prodcat-img2" href="https://google.ca">One more link btn</a><br>
<a class="button-link" data-key=".prodcat-img3" href="https://google.ua">Link text #3</a><br>
</div>
</div>
</section>
Update
I misunderstood what one part of your code was trying to do, and had replaced it with a different approach. I've updated my answer to use that part of your original code.
The problem is because each set has a <div> with the same class, like prodcat-img1, and the code which makes an image active:
$($(this).data("key")).addClass('active');
which evaluates to, eg:
$('.prodcat-img1').addClass('active');
matches all <div>s with that class, ie every one on the page.
The solution is to target only the ones in the current <section>, using something like:
$(this)
.closest('.section_product-category')
.find($(this).data("key"))
.addClass('active');
$(this) is the current element which triggered the hover/unhover event;
.closest() will traverse up the DOM tree until it finds the first match. In this case we look for the parent <section> which encloses this set of links and images;
.find() searches down the DOM tree from the current element for elements matching the selector. In this case we look for the (single!) element inside the <section> we found with a class matching your data-key;
Next, The same problem exists with this line:
$($('.prodcat_btn .button-link').not(this).data('key')).removeClass('active');
It will target every div on the page with the relevant class (eg .prodcat-img1), not just the one in the current section.
We can use the same fix though - start at the parent <section>, find the divs with active class, and remove that class. We just wrap the whole selector in the same code as above:
$(this)
.closest('.section_product-category')
.find($($('.prodcat_btn .button-link').not(this).data('key')))
.removeClass('active');
There is one other issue with this line - if you remove the class from the <div>s after you add it to the one we want, you're left with none of them with the class! :-) You need to remove the class from everything first, then add it to just the one we want. You already have that the right way around in the hover-out handler, just not in this hover handler.
Another issue is this code:
$('.section_product-category ').each(function() {
$('.prodcat_btn .button-link').hover( ...
Here you are iterating over all .section_product-category on the page, and adding handlers for $('.prodcat_btn .button-link'). But $('.prodcat_btn .button-link') matches every one of those elements on the page. So on the first iteration, you add a handler which matches every $('.prodcat_btn .button-link') on the page. The second iteration, you do it all again! The handlers just add up, they don't overwrite each other, and this means that every time you mouse over one of your links, your handler code runs 2x, or 3x if you have 3 sets, etc. You can confirm this by putting a console.log() inside your hover function - you'll see as many log lines written as you have <section>s, for a single mouse-over.
If you're lucky they won't interfere with each other, but depending on what they do they can, and you end up with weird behaviour. You can just remove the iteration - the single selector matches everything.
Here's a working snippet, starting from your 2-section JSFiddle, with those issues fixed:
$('.prodcat_btn .button-link').hover(
function() {
// $($(this).data("key")).addClass('active');
// $($('.prodcat_btn .button-link').not(this).data('key')).removeClass('active');
let $section = $(this).closest('.section_product-category');
// My original approach to remove active classes in this section
// $section.find('.prodcat_img').not($(this)).removeClass('active');
// Your original approach, updated to only target the current section
$section.find($($('.prodcat_btn .button-link').not($(this)).data('key'))).removeClass('active');
$section.find($(this).data("key")).addClass('active');
},
function() {
// $($(this).data("key")).removeClass('active');
// $($('.prodcat-img1')).addClass('active');
let $section = $(this).closest('.section_product-category');
$section.find($(this).data("key")).removeClass('active');
$section.find('.prodcat-img1').addClass('active');
}
);
.section_product-category {
display: flex;
width: 90%;
margin-bottom: 20px;
}
.section_product-category>div {
width: 70%;
}
.section_product-category>div:first-child {
width: 30%;
}
h2 {
margin-bottom: 45px;
}
.prodcat_img {
display: none;
overflow: hidden;
position: relative;
padding-top: 135%;
border: 1px solid blue;
}
.prodcat_text {
padding: 20px 20px 20px 40px;
}
.prodcat_img img {
position: absolute;
top: 0;
height: 100%;
width: 100%;
object-fit: cover;
}
.prodcat_img.active {
display: block;
}
.button-link {
margin-bottom: 7px;
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="section_product-category ">
<div class="prodcat_imgs">
<div class="prodcat_img prodcat-img1 active">
<img width="720" height="970" src="https://i.postimg.cc/k4pHm2DW/CTA-image.png" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img2">
<img width="345" height="480" src="https://i.postimg.cc/GhwC8fhG/visit-us-wine-glass.jpg" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img3">
<img width="1035" height="1440" src="https://i.postimg.cc/3NLm6GRH/social-image-three.jpg" class="attachment-full size-full">
</div>
</div>
<div class="prodcat_text">
<h2>Category #1 links</h2>
<div class="prodcat_btn btn">
<a class="button-link" data-key=".prodcat-img1" href="https://google.com">Link text here</a><br>
<a class="button-link" data-key=".prodcat-img2" href="https://google.ca">One more link btn</a><br>
<a class="button-link" data-key=".prodcat-img3" href="https://google.ua">Link text #3</a><br>
</div>
</div>
</section>
<section class="section_product-category ">
<div class="prodcat_imgs">
<div class="prodcat_img prodcat-img1 active">
<img width="720" height="970" src="https://i.postimg.cc/k4pHm2DW/CTA-image.png" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img2">
<img width="345" height="480" src="https://i.postimg.cc/GhwC8fhG/visit-us-wine-glass.jpg" class="attachment-full size-full">
</div>
<div class="prodcat_img prodcat-img3">
<img width="1035" height="1440" src="https://i.postimg.cc/3NLm6GRH/social-image-three.jpg" class="attachment-full size-full">
</div>
</div>
<div class="prodcat_text">
<h2>Category #2 links</h2>
<div class="prodcat_btn btn">
<a class="button-link" data-key=".prodcat-img1" href="https://google.com">Link text here</a><br>
<a class="button-link" data-key=".prodcat-img2" href="https://google.ca">One more link btn</a><br>
<a class="button-link" data-key=".prodcat-img3" href="https://google.ua">Link text #3</a><br>
</div>
</div>
</section>

Hover image issue

I have a link in text on this page, https://melodylakerart.com/product/sun-on-skin-mask-duplicate-1/ which when hovered over produces a pop up image.
As you can see, the text is broken - all the text between "sensitive' and 'off" should be on one line (including the link)
How do I get rid of the weird line breaks?
CSS is:
.hover_img a {
position: relative;
}
.hover_img a span {
position: absolute;
display: none;
z-index: 99;
}
.hover_img a:hover span {
display: block;
}
.hover_img a:hover span {
display: block;
width: 350px;
}
HTML is:
Sensitive ears? Add an
<div class="hover_img">
<a href="#">adjustable silicone strap
<span>
<img src="https://melodylakerart.com/wp-content/uploads/2020/06/Hanwell-Rainbow-Mask-1.jpg" alt="image" height="100" />
</span>
</a>
<div>
to take the pressure off
The addon is doing something strange with the internal div. It wraps the content in a p tag and pushes the div outside. Best to remove it as not needed and move the class name to the a tag (except)..... Change the a to a span because then you wont have the clickable behaviour.
Change the html to:
Sensitive ears? Add an <span class="hover_img">adjustable silicone ear protector strap <span><img src="https://melodylakerart.com/wp-content/uploads/2020/06/Mask-extenders-2.jpg" alt="image" height="100"></span></span>to take the pressure off.
Modify the Css:
span.hover_img { position:relative; color:#f66f61; }
span.hover_img span { position:absolute; display:none; z-index:99; }
span.hover_img:hover span {display: block;width: 350px;}
you have some problemes with the HTML tags organisation
try to replace the the full <div class="hover_img"> with this code
<div class="hover_img">
<p>
<span>Sensitive ears? Add an </span>
<a href="#">adjustable silicone strap
<span>
<img src="https://melodylakerart.com/wp-content/uploads/2020/06/Hanwell-Rainbow-Mask-1.jpg" alt="image" height="100" />
</span>
</a>
<span>to take the pressure off</span>
</p>
<p class="form-row form-row-wide wc-pao-addon-wrap wc-pao-addon-22252-0-0">
<label><input type="checkbox" class="wc-pao-addon-field wc-pao-addon-checkbox" name="addon-22252-0[]"
data-raw-price="1.50" data-price="1.5" data-price-type="quantity_based"
value="face-mask-strap-extension-loop-ear-protector"
data-label="Face Mask Strap Extension Loop Ear Protector"> Face Mask Strap Extension Loop Ear Protector
(+<span class="woocommerce-Price-amount amount"><span
class="woocommerce-Price-currencySymbol">£</span>1.50</span>)</label>
</p>
<div class="clear"></div>
</div>

CSS - Select a next element

I don't know how to explain this very well but...
I want to select an element but it's like "far" from other one
Like this:
<div class="image-div">
<img src="forest.png" class="image forest">
</div>
<p>
I want to change the color of this text if the image there ^ is "forest", which I'll change with JS
</p>
.image.forest [some selector idk] p {
color: red;
}
.image.train [some selector idk] p {
color: blue;
}
You could re-write it like this if it works for you.
<div class="image-div forest">
<img src="forest.png" class="image">
</div>
<p>I want to change the color of this text if the image there ^ is "forest", which I'll change with JS</p>
<style>
.forest + p {
color: red;
}
.train + p {
color: blue;
}
</style>
Why dont you just add a class to the p tag right after the forest image.
<div class="image-div">
<img src="forest.png" class="image forest">
</div>
<p class="forest-paragraph"></p>
.forest-paragraph {
color: #000;
}
You'd need to go from <img> to <div> to <p>, but going from <img> to <div> presents a problem: there is no CSS selector that allows one to reference an element that is higher up in the DOM tree, i.e. no child-to-parent selector.
Instead, you can apply the .forest class to the <div>.
HTML:
<div class="image-div forest">
<img src="forest.png" class="image">
</div>
<p>
I want to change the color of this text if the image there ^ is "forest", which I'll change with JS
</p>
CSS:
.forest + p {
color: red;
}

Why does toggling an anchor's child element with display cause a double tap, while toggling with opacity does not?

Why does toggling display and opacity on an anchor's child elements affect touch events differently on iOS devices?
I have a navigation menu in which each item contains an image and a short string of text.
Each image has a :hover state that uses the same shared overlay image.
If the :hover pseudo class sets the overlay image's display value, users on iOS devices have to tap the link twice.
If the :hover pseudo class sets the overlay image's opacity value, users on iOS devices do not have to tap the link twice.
In both cases, it doesn't matter if the overlay image covers the entire base image or is a smaller inset overlay.
In both cases, including the :active and :focus pseudo classes does not change the behavior.
I know that I can just remove the :hover rules with JavaScript for touch devices. I'm wondering if anyone knows the why there is a difference between display and opacity.
a {
display: inline-block;
height: 200px;
position: relative;
width: 150px;
}
a img.overlay {
display: block;
left: 0;
position: absolute;
top: 0;
}
a.overlay-display img.overlay {
display: none;
}
a.overlay-display:hover img.overlay {
display: block;
}
a.overlay-opacity img.overlay {
opacity: 0;
}
a.overlay-opacity:hover img.overlay {
opacity: 1;
}
<p>
Set overlay display:
</p>
<a class="overlay-display overlay-display-first" href="http://www.google.com" target="_blank">
<img class="overlay" src="http://placehold.it/150x150/ff0000">
<img src="http://placehold.it/150x150"> link text
</a>
<a class="overlay-display overlay-display-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150">
<img class="overlay" src="http://placehold.it/150x150/ff0000"> link text
</a>
<a class="overlay-display overlay-display-first" href="http://www.google.com" target="_blank">
<img class="overlay" src="http://placehold.it/50x50/ff0000">
<img src="http://placehold.it/150x150"> link text
</a>
<a class="overlay-display overlay-display-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150">
<img class="overlay" src="http://placehold.it/50x50/ff0000"> link text
</a>
<p>
Set overlay opacity:
</p>
<a class="overlay-opacity overlay-opacity-first" href="http://www.google.com" target="_blank">
<img class="overlay" src="http://placehold.it/150x150/ff0000">
<img src="http://placehold.it/150x150"> link text
</a>
<a class="overlay-opacity overlay-opacity-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150">
<img class="overlay" src="http://placehold.it/150x150/ff0000"> link text
</a>
<a class="overlay-opacity overlay-opacity-first" href="http://www.google.com" target="_blank">
<img class="overlay" src="http://placehold.it/50x50/ff0000">
<img src="http://placehold.it/150x150"> link text
</a>
<a class="overlay-opacity overlay-opacity-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150">
<img class="overlay" src="http://placehold.it/50x50/ff0000"> link text
</a>
Additionally, it doesn't seem to matter if I'm toggling an inline element or a block element. In this snippet, I'm toggling a span inside the anchor.
a {
display: inline-block;
height: 200px;
position: relative;
width: 150px;
}
a.text-display span.overlay {
display: none;
}
a.text-display:hover span.overlay {
display: inline;
}
a.text-opacity span.overlay {
opacity: 0;
}
a.text-opacity:hover span.overlay {
opacity: 1;
}
<p>
Set text display:
</p>
<a class="text-display text-display-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150"> link text
<span class="overlay">some other text</span>
</a>
<p>
Set text opacity:
</p>
<a class="text-opacity text-opacity-last" href="http://www.google.com" target="_blank">
<img src="http://placehold.it/150x150"> link text
<span class="overlay">some other text</span>
</a>
According to the iOS Developer Library documentation for One-Finger Events:
Mouse events are delivered in the same order you'd expect in other web
browsers illustrated in Figure 6-4. If the user taps a nonclickable
element, no events are generated. If the user taps a clickable
element, events arrive in this order: mouseover, mousemove, mousedown,
mouseup, and click. The mouseout event occurs only if the user taps on
another clickable item. Also, if the contents of the page changes on
the mousemove event, no subsequent events in the sequence are sent.
This behavior allows the user to tap in the new content.
The problem is that it's not clear what constitutes a content change.
Setting display:none removes the element from the document flow; setting display:block (or display:inline) will put it back into the document flow, which would be a content change akin to creating and adding a new element on the fly.
When you're changing opacity, the element is always in the document flow, just not visible.
Try using display:hidden rather than display:block. If I'm right, display:hidden won't cause you any trouble with double-taps either. Using "hidden" does not remove the element from the document flow, which is why there's a blank space equivalent to the size of the hidden object when the object is not visible.
https://www.w3.org/TR/CSS2/visuren.html#display-prop

Display div on hovering anchor tag

I want to display a div on hovering the anchor tag using css. Below is my html code
<td class="cellStyle">
<a href="#" class="linkStyle">
<div>Home</div>
<div style="display:none;">I'm here... (some html) </div>
</a></td>
Please tell me how i can achieve this using css.
Thanks
Give your hidden div a class:
<td class="cellStyle">
<a href="#" class="linkStyle">
<div>Home</div>
<div class="demo">I'm here... (some html) </div>
</a></td>
And use these styles:
<style>
a.linkStyle div.demo { display:none; }
a.linkStyle:hover div.demo { display:block; }
</style>
Working jsfiddle: http://jsfiddle.net/6pB8G/
how to make sub menu appear when hover over link?
CSS
a.linkStyle:hover div.here {
display:block;
}
div.here {
display : none;
}
HTML
<a href="#" class="linkStyle">
<div>Home</div>
<div class="here">I'm here... (some html) </div>
</a>
(Added a class to div which is to be hidden first)
JSFIDDLE DEMO
Try this:
CSS:
.hiddendiv {display:none;}
.linkStyle:hover > .hiddendiv { display:block; }
HTML:
<a href="#" class="linkStyle">
<div>Home</div>
<div class="hiddendiv">I'm here... (some html) </div>
</a>
here is a working demo
It's better to keep block level elements outside from inline elements. So, try keeping DIV outside from A.
here is demo:
HTML
<td>
<a class="tooltip">Home</a>
<div class="tip">I'm here... (some html)</div>
</td>
CSS:
.tip{display:none}
.tooltip:hover + .tip{display:block}
Working Demo