Do any web browsers support animated cursors?
I've been searching the web to add custom cursors to my web application. I've been finding a lot of non animated (.cur) and animated (.ani) cursors, and using the correct CSS so that my application has custom cursors! It seems that the animated cursors are not supported in the web browsers I tried and I was wondering if there is any way possible to put animated cursors into my web application.
You can make it happen with the help of a bit of javascript:
Add to your css
#container {
cursor : none;
}
#cursor {
position : absolute;
z-index : 10000;
width : 40px;
height : 40px;
background: transparent url(../images/cursor.gif) 0 0 no-repeat;
}
Then add to your js
Straight Javascript Version
// Set the offset so the the mouse pointer matches your gif's pointer
var cursorOffset = {
left : -30
, top : -20
}
document.getElementById('container').addEventListener("mousemove", function (e) {
var $cursor = document.getElementById('cursor')
$cursor.style.left = (e.pageX - cursorOffset.left) + 'px';
$cursor.style.top = (e.pageY - cursorOffset.top) + 'px';
}, false);
Jquery Version
$('#container').on("mousemove", function (e) {
$('#cursor').offset({
left: (e.pageX - cursorOffset.left)
, top : (e.pageY - cursorOffset.top)
})
});
I managed to accomplish this using CSS keyframes, animating the source image of the cursor. It works in Chrome and Safari (though it can get a little glitchy if you've got a ton of stuff running). Good enough for my personal site!
* {
cursor: url(frame1.png), auto;
-webkit-animation: cursor 400ms infinite;
animation: cursor 400ms infinite;
}
#-webkit-keyframes cursor {
0% {cursor: url(frame1.png), auto;}
20% {cursor: url(frame2.png), auto;}
40% {cursor: url(frame3.png), auto;}
60% {cursor: url(frame4.png), auto;}
80% {cursor: url(frame5.png), auto;}
100% {cursor: url(frame6.png), auto;}
}
#keyframes cursor {
0% {cursor: url(frame1.png), auto;}
20% {cursor: url(frame2.png), auto;}
40% {cursor: url(frame3.png), auto;}
60% {cursor: url(frame4.png), auto;}
80% {cursor: url(frame5.png), auto;}
100% {cursor: url(frame6.png), auto;}
}
After doing some more research, I don't think it's possible at the moment. It doesn't seem that any of the browsers support animated cursors as of 2/8/2012 using the CSS cursor property. I suppose it could be done using JavaScript to repeatedly change the value of the cursor property every few frames to make it appear animated, but that may be more trouble than it is worth.
Animated cursor files .ani files do not work. All 5 major web browsers will not show the cursor. If you try some CSS like, cursor: url('animated.ani'), that cursor will not show up!
If you make the cursor an animated gif file, it only shows up on some browsers and it's temperamental, like cursor: url('animated.gif'), the cursor works in Firefox and Chrome but it is not animated, the cursor does not work at all in IE9 or Opera, and it did something really weird in the Windows version of Safari - it works but is only animated when I move the cursor vertically on the screen, and did not animate at all when the cursor was not moving or was moving horizontally. Credit to Brutallus for the idea to use an animated gif even though it did not work!
It doesn't seem that browsers support animated cursors at this time which is a shame because I really think it would add some depth to certain web applications. I don't advocate using animated cursors for most websites because they are extremely annoying, but there are some rare situations where they can be useful, such as a HTML5 game where the cursor can potentially add to the theme of the game.
To answer your question
Do any web browsers support animated cursors?
Yes.According to MDN, IE supports .cur and .ani formats.
As a suggestion,have you considered using an animated gif image instead?
Try this in your css
cursor: url(img/animated_cursor.gif), auto;
-->it flickers for some reason when you move the mouse in a downwards direction
It happens because the cursor goes over the animated gif (over the #mycursor image, look the code) and exits the element on which you call the function.
I was able to get .ani cursors rendering in modern browsers by using JavaScript to extract the individual animation frames from the .ani file and convert them to data URIs which I then compose into a CSS animation similar to the solution proposed by Laura above.
I've published it as an NPM module called ani-cursor.
Some limitations of this approach:
The .ani file must be served from the same domain, or include proper CORS headers.
CSS cursor animation does not currently work in Safari, but a fix has landed so it should be in the next release.
I've also written a blog post with some details about how it works: https://jordaneldredge.com/blog/rendering-animated-ani-cursors-in-the-browser/
No major browser actually supports animated cursors (of type .ani) as of 2017, and I don't think any are really planning to add them in the future. However, some random browser may support this feature (a not really well known browser), so you should add a feature that will make the cursor work in those browsers:
body {
cursor: url("hand-pointing.ani"), pointer;
}
This way, if the animated cursor doesn't work in a user's browser, at least the normal pointer cursor is enabled. If you don't add the pointer part, than browsers without animated cursor support would load an ENTIRELY DIFFERENT cursor from what you wanted. Also, note that the default browser cursors kind of suck. I know that many people want animated cursor support added to major browsers, but it won't happen unless lots of people petition for it or something.
In other words, there is no answer to this question right now. Please comment if this changes.
Full code without bugs
<body id="body" onmousemove="showCoords(event)" onmouseout="clearCoor()">
<div id="mini_mouse">
</div>
<script src="lib/js/jquery-3.3.1.min.js"></script>
<script>
function showCoords(event) {
var elmnt = document.getElementById("html");
var scrollTop = elmnt.scrollTop;
var x = (event.clientX) - (10);
var y = (event.clientY) - (10) + (scrollTop);
document.getElementById("mini_mouse")
.style = ("top: " + y + "px ;" + "left: " +
x + "px ;" + "
background-color: red;
width: 20px;
height: 20px;
opacity: .5 ;
position: absolute;
z-index: 100;
border-radius: 100px ;
");
}
function clearCoor() {
document.getElementById("mini_mouse").style = "";
}
</script>
A possible alternative: you could convert the ANI into a GIF and then have the GIF follow your (hidden) mouse cursor around.
// Have the cursor follow the mouse
$(document).mousemove(function (e) {
$(".pointer").css({ left: e.pageX, top: e.pageY });
});
/* Hide original cursor; add whatever elements necessary */
html, input, textarea {
cursor: none;
}
.pointer { /* Set cursor location */
position: absolute;
height: 480px; top: 100px;
width: 480px; left: 50%;
z-index: 9999; /* Put cursor on top of everything */
pointer-events: none; /* Make sure cursor doesn't change */
}
.pointer img { /* Set cursor size constraints if desired */
height: 50px;
width: auto;
}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script></head>
<body>
<div class="pointer">
<img src="https://i.imgur.com/K5ufqqA.gif">
</div>
</body>
When viewing a website with Chrome for Android, the height of the view-area changes as soon as scrolling causes the URL-bar to hide. When using a fixed background image, this results in annyoing resizing of the image, initially when scrolling down, and also when the user scrolls up again, which enables to URL-bar again.
This topic has already been discussed here:
Background image jumps when address bar hides iOS/Android/Mobile Chrome
There was also a 'fix' announced, that recommends the use of vh instead of % to describe the height of the image:
https://developers.google.com/web/updates/2016/12/url-bar-resizing
Given now a site that contains a fixed background image:
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="content">
<div style="padding-bottom:2000px; width:100%;">Test</div>
<div>Test again</div>
</div>
</body>
</html>
using the following CSS:
html, body {
margin: 0;
padding: 0;
}
div {
color:white;
font-size: 30px;
}
#content {
background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
background-size: cover;
}
will rescale the background image as described above, using Google Chrome for Android. Here is a Fiddle.
The methods determined to solve this (see linked JS-thread) make use of JavaScript to determine the window height after resizing of the window has taken place and then update the image height. However, it won't stop the background image from resizing without leaving a part of the page blank.
In order to keep the background image in place, two methods seem suitable:
preventing the URL-bar to hide
render the image with an initial offset to be able to compensate the image shift
Preventing the URL-bar to hide
In order to keep the URL-bar visible all the time, I created a fixed-div that contains a scrollable div-container:
<div id="content">
<div id="fixed">
<div id="scroller">
<div style="padding-bottom:2000px; width:100%;">Test</div>
<div>Test again</div>
</div>
</div>
</div>
CSS:
#fixed {
height:100vh;
width:100vw;
overflow:hidden;
}
#scroller {
overflow-y: auto;
height:100vh;
}
The idea is that since the user is not scrolling the website-body, the URL-bar won't disappear. This Even though this works on my emulator, it doesn't work on a real Galaxy S20. A user would be able to hide the URL-Bar after scrolling to the bottom of the page (the div).
Rendering the image with an initial offset to be able to compensate the image shift
The other idea was to draw the background image 'deeper' by default:
background-size: auto calc(100vh + 100px);
If there is "unused" space on top of the image, it should be possible to catch the resize- or touchmove-event, compare the new window height to the initial window height and then compensate the offset. Unfortunately, this will only affect the y-dimensions of the image and I would probably need to do the same for the x-axis or rescale the image again. However, when trying to determine the current image size in JavaScript (using jQuery, see this thread), I ran into another error; retrieving the image-size via $('#background').css('background-size') returned just auto and ignored the second part.
Most threads about this topic are older than five years. Can someone enlighten me and tell me there is a way to manage this by now?
Update:
I was able to eliminate the resizing using the following technique:
Assuming portrait-mode is active, I calculated the image width from the scaled image height and set the background-size to pixel values:
var initHeight = '';
var initWidth = '';
var imageHeight = 982;
var imageWidth = 1500;
var cssHeight;
var cssWidth;
$(window).on('resize', function () {
if (initHeight == 0) {
initHeight = $(window).height();
initWidth = $(window).width();
cssHeight = parseInt($('#content').css('background-size').split(" ")[1].slice(0,-2));
cssWidth = cssHeight / imageHeight * imageWidth;
$('#background').css('background-size', cssWidth + "px " + cssHeight + "px");
}
Now the background image won't scale, but it will move vertical when toggling the URL-bar.
To get rid of this, I make use of the second method described above and draw the background image with an initial offset:
background: url(../images/bg.jpg) no-repeat right 15% top -100px;
background-size: auto calc(100vh + 200px);
As soon as a resize-event occurs, I update the background image position:
let newHeight = $(window).height();
let newWidth = $(window).width();
let diff = newHeight - initHeight;
$('#background').css('background-position', "85% " + (startHeightOffset + diff) + "px")
This seems to work in my emulator. The background image stays in place now. However, when switching devices, I noticed that this approach works only for devices that have no toolbar in the bottom. Emulating a Galaxy S9, which has a URL-bar on the top as well as a toolbar on the bottom, the background image gets shifted too much, since the space acquired by both toolbars (top and bottom) will be added to the top of the image. In order to make this work, I would need to determine the height of the top URL-bar only and I genuinely don't know if this is possible.
Again, in order to solve this problem, one of the following problems must be solved:
reliably prevent hiding of the URL-bar
determining the height of the bottom toolbar
Update 2:
I was able to prevent hiding of the URL bar like so:
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow: scroll;
}
body {
-webkit-overflow-scrolling:touch;
}
#content {
width: 100%;
height: 100%;
background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
background-size: cover;
}
#fixed {
height:100%;
width:100vw;
overflow:hidden;
}
#scroller {
overflow-y: auto;
height:100vh;
}
The background image stays in place, since the URL-bar will never collapse. However, this isn't the ideal solution and it would be great if there would be a way to make this work without the need of preventing the URL-bar to collapse.
Im trying to figure out whats going on in my website that in mobile devices im not able to scroll till the end where the arrow up is.
I need you to help me. Thanks
My website is www.agustinmoles.byethost32.com
EDIT: I have found that the error is in some part of this code, but I don't think its bad... hmmmm
function deSeccion1A2() {
deSeccionXaSeccionY('#section1 #portfolio i','#section2');
}
function deSeccion2A3() {
deSeccionXaSeccionY('#section2 .bottom-arrow','#section3');
}
function deSeccion3AContact() {
deSeccionXaSeccionY('#section3 .bottom-arrow','#contact-section');
}
function deContactATop() {
deSeccionXaSeccionY('#contact-section .bottom-arrow','#section1');
}
function deSeccionXaSeccionY (nombreElemento, nombreDivAMoverse) {
$(nombreElemento).click(function() {
var altoSection = $(nombreDivAMoverse).offset().top;
$('html, body').animate({scrollTop: altoSection},700);
});
}
The javascript on your page scrolls to each section so it fills the screen. On mobile the screen is not tall enough, so it can't fit the whole section, and because there is no next section it stops the scrolling. A lazy fix would be to disable that functionality on mobile or to adjust the bottom position of .adios and bottom-arrow.
If you can reproduce the issue on here using a code snippet, you might get some better solutions.
EDIT:
Try changing the font size of the below selector to font-size:2.8em. The title seems to be breaking out of the DIV which seems to be causing the issue. I am not 100% sure but this could be causing the vh units calculation to be off slightly.
#media screen and (max-width: 768px)
#contact-info h1 {
margin: 0 auto;
padding-top: 100px;
width: 97%;
line-height: 70px;
font-size: 3.8em;
}
}
Using a background image for -webkit-scrollbar-thumb:vertical. Here's a jsFiddle: http://jsfiddle.net/6ESpj/2/
To simulate problem, increase the height in div.inner from 1500px to 2000px. You should see that the bottom get's cut off (I believe this is the equiv of the scrollbar 'shortening' in height as the page content grows).
Can anyone recommend a solution? Even a javascript one if necessary.
Thanks!
::-webkit-scrollbar-thumb:vertical
{
background:black url('http://i.minus.com/jbcOb9d7Bb1p6Y.png') no-repeat;
background-size:26px 63px;
background-position:;
display: block;
width: 30px;
height: 100px;
}
Try this, change height of this to whatever you want, if you wish you can with JS compute proper height, something like: height_of_::-webkit-scrollbar-thumb:vertical = height_of_div / SOME_CONSTANT... but I think that isn't necessary.
I found this awesome .js called kinetic. I've been messing with the html, css for sometime now and am unable to set the container to full screen.
http://designobvio.us/v4design/demo.html
I've set all the parents to 100% height and tried a fullscreen jQuery. Unfortunately still no luck.
I've paired down the code as much as possible for readability. As you can see I've set the height to just 400px because it just goes crazy otherwise. If there's any thing else i can offer as support, please don't hesitate to ask.
As a second request would anyone have any idea how to set the border to inside. Or make sure that the width fits nicely with borders as is?
You can position your #wrapper div absolutely and just stretch it in all directions with the top, right, bottom, left properties like so:
CSS
#wrapper {
border: 5px solid #000000;
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
top: 0;
}
With this method the borders play nicely with the positioning, but if you want to place them inside your container you can set the border style to inset instead of solid. Also, your control buttons will disappear so to make them pop in front of your image just set them to position:relative and give them a large z-index so they appear on top of everything else.