I’m using a combination of icons and text for some links in the sidebar on my website, but I want both the icon and text to change if the mouse hovers over either of them. Using MouseOn and ‘hover’ in my CSS file, I’ve managed to get this to work when the mouse hovers over the icon, but if the mouse only hovers over the text, only the text changes but not the icon as well. Does anybody know a way to do this please? A link to my site and the code I’m currently using are below. Thanks everybody.
http://www.retelevise.com
<span class="social-media-sidebar-panel">
<a href="https://www.facebook.com/re.televise" target="_external window fa">
<img src="http://www.retelevise.com/wp-content/themes/myownzee/branding/
socialmedia-facebook-1.png"
onmouseover="this.src='http://www.retelevise.com/wp-content/themes/myownzee/
branding/socialmedia-facebook-2.png'"
onmouseout="this.src='http://www.retelevise.com/wp-content/themes/myownzee/
branding/socialmedia-facebook-1.png'"
class="social-media-sidebar-icons" title="Facebook" alt="Facebook">
<span style="font-size: 0.8em">Facebook</span></a></span>
try moving your onmouseover and onmouseout events to anchor and change the 'this.' to reference the img by ID.
I've made several changes to the way you've done this:
Moved your styling and javascript to external files
Used JQuery for animations (simply easier)
This version now makes use of multiple images.
JSFiddle DEMO
HTML:
<span class="sm">
<a href="#" class="mediaLink">
<img class="mediaPic" data-hover="http://placehold.it/60/4477ee/ffffff" src="http://placehold.it/60/224499/ffffff"/>
<div class="mediaText"> Facebook</div>
</a>
</span>
<span class="sm">
<a href="#" class="mediaLink">
<img class="mediaPic" data-hover="http://placehold.it/60/ee9933/ffffff" src="http://placehold.it/60/777777/ffffff"/>
<div class="mediaText"> Stack Overflow</div>
</a>
</span>
<span class="sm">
<a href="#" class="mediaLink">
<img class="mediaPic" data-hover="http://placehold.it/60/66aaff/ffffff" src="http://placehold.it/60/3388aa/ffffff"/>
<div class="mediaText"> Twitter</div>
</a>
</span>
<span class="sm">
<a href="#" class="mediaLink">
<img class="mediaPic" data-hover="http://placehold.it/60/dd1122/ffffff" src="http://placehold.it/60/991122/ffffff"/>
<div class="mediaText"> YouTube</div>
</a>
</span>
JavaScript (Using JQuery):
$(document).ready( function() {
$(".mediaLink").on( {
mouseenter: function() {
$(this).children(".mediaPic").data("static", $(this).children(".mediaPic").attr("src"));
$(this).children(".mediaText").css("color", "orange");
$(this).children(".mediaPic").attr("src", $(this).children(".mediaPic").data("hover"));
}, mouseleave: function() {
$(this).children(".mediaText").css("color", "white");
$(this).children(".mediaPic").attr("src", $(this).children(".mediaPic").data("static"));
}
});
});
CSS:
.mediaLink {
display: block;
}
.mediaPic {
float: left;
width, height: 60px;
}
.mediaText {
height: 60px;
width: 150px;
padding-left: 10px;
line-height: 60px;
background: #242424;
color: white;
font-family: "Consolas"," Arial";
font-size: 18px;
float: left;
}
.sm {
margin: 5px;
float: left;
}
Explanation:
I'm making the <a> change its children (.mediaPic and .mediaText) when its being hovered over. On mouseenter is when the mouse is hovered over, and mouseleave is returning the <a> back to its regular state.
The part called data-hover is the url of the picture you wish to set the image to, where you leave src as the image you want to have as the default. When you hover over the image, the script will "remember" the original src and set it back to that when you leave the image (mouseleave).
Related
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>
I know this looks very simple, but I have been trying to figure out a solution for an hour now. I have an "a" element with text and an image inside. The problem is that the image goes below the text, and I want them lined up.
a {
text-decoration: none;
color: #fff;
}
a:hover {
color: #ff5c33;
text-decoration: none;
cursor: pointer;
}
#nav-user-logo{
max-height: 16px;
}
<!-- Header right part -->
<div class="dropdown">
<a>
User123
<img src="Images/Icons/user.svg" id="nav-user-logo" alt='User123'>
</a>
<div class="dropdown-content user-dropdown-content" >
<a>AW Admin</a>
<a>Account Settings</a>
<a>Change Password</a>
<a>Logout</a>
</div>
</div>
I didn't have the issue myself but you can do
#nav-user-logo {
max-height: 1em;
display: inline;
}
to guarantee it is inline with the text.
By defect, any browser, with your css will display the image side by side as, I think, you want:
example with your code:
a {
text-decoration: none;
}
a:hover {
color: #ff5c33;
text-decoration: none;
cursor: pointer;
}
#nav-user-logo{
max-height: 16px;
}
<div class="dropdown">
<a>
User123
<img src="https://www.ajvs.com/redirect/5/Agilent_IMG300_UHV_R0343301_1,8926cf9ec9ce009a52f3ea8866b07f5f" id="nav-user-logo" alt='User123'>
</a>
<div class="dropdown-content user-dropdown-content">
<a>AW Admin</a>
<a>Account Settings</a>
<a>Change Password</a>
<a>Logout</a>
</div>
</div>
Probably, you have some kind of "reset" css sheet that is turning all your images as display:block It's quite common in many wordpress themes. You may need to overwrite these css adding img {display:inline-block} or similar rule. Calling to the id image or class to not break your whole theme.
Turns out the issue was something super simple. This code is in a header, on the right side, and the "a" element was too small to display the code and image side by side. I fixed it with the following:
<!-- Header right part -->
<div class="dropdown">
<a style="display:inline-block; width: 150px;">
User123
<img src="Images/Icons/user.svg" id="nav-user-logo" alt='User123'>
</a>
<div class="dropdown-content user-dropdown-content" >
<a>AW Admin</a>
<a>Account Settings</a>
<a>Change Password</a>
<a>Logout</a>
</div>
</div>
This is my code:
HTML:
<a href="index2.html">
<input type="image" class="button" value="">
</a>
CSS:
.button {
background:url(example.jpg) no-repeat;
cursor:-webkit-grab;
border: none;
}
What should happen is that it display an image and when I click on, it will navigate to another this site index2.html. It worked with another image but it had an annoying border but after I changed the image it doesn't work any more.
You do not need an input type button, simply use img...
html:
<a href="index2.html">
<img src="example.jpg" />
</a>
css:
a img {
border: none;
cursor: grab;
}
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
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
}