I created a very basic sample:
HTML
<div id="bla"></div>
CSS
#bla {
width:400px;
height:400px;
background-color:green;
display:none;
}
#bla:hover{
background-color:red;
}
As you can see it's a DIV that is initially hidden and changes color when mouse hovers over it.
This JavaScript unhides it after 2 seconds
setTimeout(function() {
document.getElementById('bla').style.display="block";
},2000)
But if you place your mouse over location where the DIV is about to appear - when it appears - it appears in unhovered state. Only when you actually move the mouse - hover effect takes place.
Here's a demo. Run it and immediately place mouse over result pane.
Is this by design? Is there a way (without JS preferable) to detect that DIV is hovered?
While you can use opacity, #BrianPhillips mentioned, it doesn't work in IE 8. I don't know of a pure CSS solution, but here's a concise enough Javascript workaround:
window.onmousemove=function(event){
ev = event || window.event;
if (event.pageX <= 400 && event.pageY <= 400){
document.getElementById('bla').style.backgroundColor= "red";
} else {
document.getElementById('bla').style.backgroundColor= "green";
}
}
setTimeout(function() {
document.getElementById('bla').style.display="block";
},2000)
Demo
When you set display to none the image takes up no space meaining there is nowhere to hover over.
I would set the background-image in you css to rgba(0 0 0 0); making it invisible but still in the dom. You can then change your javascript to
setTimeout(function() {
document.getElementById('bla').style.backgroundColor="green";
},2000);
http://jsfiddle.net/euT7k/3
You could try using CSS opacity along with setting it to position: absolute to prevent it from taking up flow on the page. This appears to work properly:
CSS:
#bla {
width:400px;
height:400px;
background-color:green;
opacity: 0;
position: absolute;
}
JS:
setTimeout(function() {
document.getElementById('bla').style.opacity="1";
document.getElementById('bla').style.position="relative";
},2000)
Demo
The key here is that elements with opacity respond to events (click, hover, etc), while elements with visibility: hidden and display:none do not. (source)
Note that opacity isn't available in IE 8 and below.
Related
First off, sorry for the weird title, I don't really know a better way of describing it.
Basically I want the image to change color while the mouse is moving (hovering) over it, but for it to stop when the mouse is still,
While the mouse is stationary, color doesn't change,
While the mouse is moving, color changes.
I know there is the hover attribute in CSS, but it only has 2 states, when the mouse is hovering over it, and when it is not, what i'm looking for is something a bit trickier.
Hopefully that explains it :/
Please try this:
document.getElementById("myDiv").onmousemove = function() {
//Set random background color
myDiv.style.backgroundColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
}
Demo:
document.getElementById("myDiv").onmousemove = function() {
//Set random background color
myDiv.style.backgroundColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
}
#myDiv {
width: 150px;
height: 150px;
background-color: #ccc;
text-align: center;
line-height: 140px;
}
<div id="myDiv">Hover ME !</div>
You can achieve this with CSS animations, using Javascript to toggle a class when the mouse moves over the image, or stops doing so.
The image will need to be wrapped within another tag, if it isn't already, and then a pseudo-element will need to be added to that tag, positioned to sit directly on top of the image, with an initial opacity of 0. We ensure the image is visible behind the pseudo-element by setting the mix-blend-mode property of the latter. When the mouse first moves over the image it is, optionally, converted to grayscale and the background-color of the pseudo-element begins animating. When the mouse stops moving, the timeout in the JavaScript adds a class to the parent element which sets the animation-play-state property of the pseudo-element to paused and, when the mouse is moved again, this class is removed.
You can refine & tweak everything in this (e.g., removing the image's filter, adding/removing keyframes, chaning the mix-blend-mode, adjusting the animation-duration) just by editing the CSS, no need to touch the JavaScript.
var figure=document.querySelector("figure"),
img=figure.querySelector("img"),
timer;
img.addEventListener("mousemove",function(){
clearTimeout(timer);
figure.classList.remove("paused");
setTimeout(function(){
figure.classList.add("paused");
},300);
},0);
*{box-sizing:border-box;margin:0;padding:0;}
figure{
display:inline-block;
position:relative;
}
img{
vertical-align:middle;
transition:-webkit-filter .25s linear 99999s,filter .25s linear 99999s;
}
img:hover{
-webkit-filter:grayscale(1);
filter:grayscale(1);
transition-delay:0s;
}
figure::after{
animation:colours 5s linear infinite;
bottom:0;
content:"";
left:0;
mix-blend-mode:overlay;
opacity:0;
pointer-events:none;
position:absolute;
right:0;
top:0;
transition:opacity .25s linear 99999s;
}
figure:hover::after{
opacity:.75;
transition-delay:0s;
}
figure.paused::after{
animation-play-state:paused;
}
#keyframes colours{
0%{background:#f00;}
16.667%{background:#ff0;}
33.333%{background:#0f0;}
50%{background:#0ff;}
66.667%{background:#00f;}
83.333%{background:#f0f;}
100%{background:#f00;}
}
<figure>
<img src="https://unsplash.it/500/500/?random">
</figure>
I'm posting here as I need almost something like this. I need to change the back ground position on each mouse move. Image is set as background, here is the image:
http://pbdlbd.org/ipositive/wp-content/uploads/2015/02/one10.jpg
And I want to move the background position on each mouse move. This image has 4 parts(height of each part is 523px) and first it will show the top portion and after mouse move over it will show the 2nd portion and on another mouse move it will show 3rd portion and after 4th part it will repeat for further mouse move over it. After mouse is removed from the image, it will show the default top portion of the image.
Something like this:
document.getElementById("#ipos .flex_cell").onmousemove = function() {
//Set background position 523px bottom on each mouse move
#ipos .flex_cell.style.background-position = center -523px (here i can't make it so that it changes to -1046px by code);
}
Here is the site
TIA
i have h2 tag and have width just 100px but the text content inside h2 tag is more than 100px, i want to show text content appear just in one line. I want to make it like on brazzers.com, When user hover the mouse on title of post, the long title of post will be sliding to show all. Is there a way to create it using jquery? Sorry about my newbie question
Please, try this example:
http://jsfiddle.net/QKstB/2/
This is a script:
var textWidth = $('h1 nobr').outerWidth(),
totalWidth = $('h1').outerWidth(),
diff = totalWidth - textWidth;
$('h1').hover( function() {
$('h1 nobr').animate({ 'margin-left': diff }, 5000, function() {
$(this).css('margin-left', 0)
});
}, function() {
$('h1 nobr').stop(true, true);
});
Seems like this is something you can just do with CSS and hover behaviors
#test {
width:30px;
overflow:hidden;
white-space:nowrap;
}
#test:hover
{
overflow:visible;
}
http://jsfiddle.net/tYEfs
Also, maybe a nsfw warning on the reference link?
I would create a div with overflow: hidden and inside this div would be the h2 tag with postion set to relative or absolute (depends on your structure and intended behaviour). As soon as the mouse is over the div I would use http://api.jquery.com/animate/ to animate the css "left" property to a negative value.
P.S: Did not check the example, due to being on work ...
EDIT: Thanks for a lot of great examples on how to solve these. I cant decide between who to accept yet, but I will go though all examples and see which I like the most. Great feedback guys! =D
I normally do these kind of things in flash, but this time it has to be compatible with mac, iPads and all those units too.
So, what do I need help with?
I've got a picture, with some "hotspots" on. I want to be able to click any of those hotspots to show some information.
This should be fairly basic and easy to achieve, but since I've never done this in html before I have to ask you guys =)
So, what would be the best way to do this? It have to be compatible with any browser and device, and it doesnt need to be very advanced. If it's possible to add effects to the box (sliding out, fading in, or anything like that) then thats a nice bonus, but not something I need.
Any help would be great!
BREAKDOWN:
I have a background image with some "hotspots" (numbers 1 and 2 in my example). The users should be able to either hover the mouse over any of these or click it to get more information, as seen in picture #2
This is that happens when you hover/click any of these hotspots.
Text and image is displayed inside a nice little info box.
If the user clicks "more information" it will open up even further to display more information if available. Like in this img:
I don't think the Javascript approach is really necessary here. I created a little CSS-only mock-up for you on JSBin.
Basically the point is that you enclose the image in a relatively positioned div, then absolute position the hotspots inside the same div. Inside the hotspots divs you will have the more info elements, showing only on :hover of their parents.
This makes it simple, and far more accessible.
Update: cropping the image equally from both sides
If you want to keep the image centered and still not use any javascript, you could set the required image as a background-image of the container, and setting its background-position parameters to center center.
You would have to make sure that the width of this div is set to the width of your image, and the max-width to 100%, so that when the window gets resized below the image width it stays at the center.
Now, a problem that I encountered here is how to make the hotspots stay center relatively to the image. I solved it this way:
I created a wrapper div for the hotspots with these characteristics:
margin: 0 auto;
position: relative;
width: 0px;
This basically makes sure that the wrapper div finds the center of our image. Then, you would position the hotspots relatively to the top-center position of the image, instead of the top-left as a starting point.
Then you have what you are looking for.
Working demo
Here's another approach, and in my opinion far superior to using a map or excessive JS. Place <div> elements on top of the element with the background-image and have HTML and CSS do the heavy lifting for you.
See it on JSFiddle
HTML
The HTML should seem pretty each enough to understand, we create <div>s with the class hotspot and rely on certain things being present. Namely .text (to show digit), .hover-popup (to show on hover) and .click-popup (which is inside .hover-popup and is shown when clicked).
<div id="hotspot1" class="hotspot">
<div class="text">1</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
<div id="hotspot2" class="hotspot">
<div class="text">2</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
CSS
This is where most of the magic happens, see the comments for further explanation.
/* These two position each hotspot */
#hotspot1 {
left:15%; /* we could use px or position right or bottom also */
top:20%;
}
#hotspot2 {
left:35%;
top:25%;
}
/* General styles on the hotspot */
.hotspot {
border-radius:50%;
width:40px;
height:40px;
line-height:40px;
text-align:center;
background-color:#CCC;
position:absolute;
}
.hotspot .text {
width:40px;
height:40px;
}
/* Show the pointer on hover to signify a click event */
.hotspot .text:hover {
cursor:pointer;
}
/* hide them by default and bring them to the front */
.hover-popup,
.click-popup {
display:none;
z-index:1;
}
/* show when clicked */
.hotspot.clicked .click-popup {
display:block;
}
/* show and position when clicked */
.hotspot:hover .hover-popup {
display:block;
position:absolute;
left:100%;
top:0;
width:300px;
background-color:#BBB;
border:1px solid #000;
}
JavaScript (with jQuery)
Unfortunately you're going to have to use some JavaScript for the clicking part as CSS doesn't have a 'clicked' state (outside of hacks with checkboxes). I'm using jQuery because it's dead easy to do what I want.
$(document).ready(function () {
$('.hotspot').click(function () {
$(this).toggleClass('clicked');
});
});
Creating the arrow
Over at css-tricks you can find a tutorial for attaching an arrow to a element using the :before and/or :after pseudo-elements. You can even 'simulate' a border around them by placing the :after element on top of the :before. But yea, lots of resources on how to do this.
You should be able to use the onclick or OnMouseOver event in the map area (define the href as "").
An example using OnMouseOver is here: http://www.omegagrafix.com/mouseover/mousimap.html
Give a class for that image in html (Ex: imgclass). And in javascript(using jquery), build that hover box in html format and bind it to 'mouseover' event of that image.
For example:
function bindhtmltoimage() {
myimg = $('body').find('.imgclass');
divSlot.each(function (index) {
$(this).bind('mouseover', function () {
try {
//position the hover box on image. you can customize the y and x axis to place it left or right.
var x = $(this).offset().left;
var y = $(this).offset().top;
var position = $(window).height() - ($("#divHover").height() + y);
var widthposition = $(window).width() - ($("#divHover").width() + x);
if (position < 0 || widthposition < 0) {
if (position < 0) {
$("#divHover").css({
position: 'absolute',
left: x + 20,
top: y - $("#divHover").height() - 20
});
}
if (widthposition < 0) {
$("#divHover").css({
position: 'absolute',
left: x - $("#divHover").width(),
top: y + 20
});
}
}
//build your html string for that hover box and apply to it.
$('#divHover').html("your Html content for that box goes here");
$('#divHover').show();
//if you want the box dynamically generated. create the html content and append to the dom.
}
catch (e) {
alert(e)
}
});
});
}
it will work fine in desktop and mobile. if you face any problem in touch devices, bind the function to click event instead of 'mouseover'.
Also, for map approach, i strongly recommend SVG instead of images.
I am using the following jQuery script:
$("#divid").mouseenter(function() {
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
$("#hldiv").mouseenter(function() {
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
As you can see, when the mouse hovers over a hyperlink called #hldiv, the #divid should be shown. The main goal is to keep the DIV shown if the mouse is over the DIV - but the #divid should not be visible initially.
If the mouse moves over the hyperlink, the DIV should appear, and when the mouse then moves over the DIV, it should stay until the mouse leaves.
The problem is that with my current code, when the user moves over the hyperlink and then out - the DIV appears/disappears correctly, but when the user moves out of the hyperlink and over the DIV itself, the DIV also disappears.
How should I fix this?
Why don't you add a container and do:
<div id='container'>
<a ID="hlDiv">hlink</a>
<div ID="divId">Test Test Test</div>
</div>
$(document).ready(function() {
$("#hlDiv").hover(function() {
$('#divId').show(1000);
})
$('#container').mouseleave(function(){
$('#divId').hide(1000);
});
});
fiddle here: http://jsfiddle.net/w68YX/8/
If I understood right, rewriting
$("#divid").mouseenter(function() {
$('#divid').stop(true);
$('#divid').show(1000);
}).mouseleave(function() {
$('#divid').hide(1000);
});
Might help, since it stops the current animation (fading out) and fades it back in (if it has already turned a bit transparent).
However this depends on your HTML, and might not work in your case, so please post the structure also.
I am very late to this party - but there is a far better way to do this, so I want to add it for the sake of future browsers. You don't need jQuery for this effect at all.
First, wrap the two items in a container (here I'm using a div with class container), and apply a class to the item you want to appear/disappear on hove (here I'm using the show-on-hover class on the #divId element)
<div class="container">
<a id="hlDiv" href="...">link text</a>
<div class="show-on-hover" id="divId">popup stuff</div>
</div>
Next, set up your CSS as follows:
.container > .show-on-hover { display: none; }
.container:hover > .show-on-hover { display: block; }
#divId { /* whatever styles you want */ }
The effect is that the hover is now controlled entirely by CSS - but, it doesn't have the 1s transition you originally had. This is a little more complicated (and currently doesn't work in IE - but will be supported as of IE10).
Simply change the CSS as follows:
.container { position: relative; }
.container > .show-on-hover { opacity: 0.0; position: absolute; }
.container:hover > .show-on-hover { opacity: 1.0; }
.show-on-hover {
-webkit-transition: opacity 1s; /* Chrome / Safari */
-moz-transition: opacity 1s; /* Firefox */
-o-transition: opacity 1s; /* Opera */
}
The relative positioning on the .container means that the container sets its own bounding boxes for its child elements and their positioning. This means that when you then set the > .show-on-hover styling to position: absolute;, it will still be constrained to its parent (if you set left: 0; as an example, it will move to the left edge of the .container, rather than the screen).
The opacity toggle now simply makes the absolutely positioned item show/disappear wherever you've placed it (and you would update the CSS to put it exactly where you want, relative to the hyperlink). Because we're no longer using display: none - the DIV will always take up space on the screen - even when hidden (which is probably not what you want).
Finally - the last block, which sets transitions, tells modern browsers that whenever the opacity changes on elements of class .show-on-hover, make that change happen as a tween over 1s of duration.
Here is a jsFiddle showing the transitions: http://jsfiddle.net/TroyAlford/nHrXK/2
And here is a jsFiddle showing just the toggle: http://jsfiddle.net/TroyAlford/nHrXK/3/
CSS/Javascript is not my strong point so I would like to ask if is possible to change the background-image opacity to, let's say, 0.5.
I have a div with
background-image: url(images/nacho312.png);
background-position: -50px 0px;
background-repeat: no-repeat no-repeat;
but when I load a certain view it does not look very good, so I want to have a "half-disolve" effect when that view is shown. Is it possible?
Thanks
Here is a start.
var element = document.getElementById('hello'),
targetOpacity = 0.5,
currentOpacity,
interval = false,
interval = setInterval(function() {
currentOpacity = element.getComputedStyle('opacity');
if (currentOpacity > targetOpacity) {
currentOpacity -= 0.1;
element.style.opacity = currentOpacity;
} else {
clearInterval(interval);
}
}, 100);
See it on jsFiddle.
Run this on window.onload = function() { } or research cross browser on DOM ready events.
Of course, it is much easier with a library like jQuery.
$(function() {
$('hello').fadeTo('slow', 0.5);
});
This relies on your container's children inheriting the opacity. To do it without affecting them is a bit of a pain, as you can't reset children's opacity via opacity: 1.
If you want to animate smoothly and without doing too much extra work - this is a good task for jQuery (or another, similar library).
With jQuery you could do:
$('#id_of_div').fadeTo('fast', 0.5);
To get a fast animated fade effect on the relevant DIV.
Update: if you want to actually fade the background image, but not any foreground contents of the DIV, this is a lot harder. I'd recommend using one container DIV with position:relative and two inner DIVs with position:absolute; . The first of the inner DIVs can have the background image and a lower z-index than the second of the DIVs, and the second DIV would contain any text, etc. to show in foreground. When needed you can call $('#id_of_first_div').fadeTo('fast', 0.5); to fade just the DIV containing the background image.
By the way, the literal answer to your question is "No, you cannot animate the opacity of a CSS background image" - you can only (currently) animate the opacity of a DOM element, not its attributes, thus the need for the above hack.
Other Update: if you want to avoid using any third-party library, you can handle the fade of the background DIV using approach in Alex's answer.
background-image: url(images/nacho312.png);
background-position: -50px 0px;
background-repeat: no-repeat no-repeat;
opacity:0.5; //for firefox and chrome
filter:alpha(opacity=50); //for IE