Change cursor opacity with css - css

For a touch screen application it may be nice to have the custom cursor fade to opacity = 0 after the screen has not been touched for a while and jump back to opacity = 1 if the screen is touched again.
Is there a way to achieve this with just some css styling?
update: whether or not the cursor is displayed depends on the handling of the underlying system (in particular desktop). As I'm using just a browser on top of a bare X-Server, the cursor is always displayed.

While cursor: none is the easiest way to simply hide a cursor, it is also possible to create a cursor with opacity using a .png or .svg.
Here is an example snippet:
.transparent_cursor {
/* div appearance */
width: 128px; height: 128px; background-color: #def; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWNgYGD4j4YxAB0UDICVKAoAQagf4Vf1Xw0AAAAASUVORK5CYII=");
/* custom cursor */
cursor: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20id%3D%22pointer_cursor%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20width%3D%2221px%22%20height%3D%2233px%22%20viewBox%3D%220%200%2021%2033%22%20enable-background%3D%22new%200%200%2021%2033%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20id%3D%22outer%22%20opacity%3D%220.5%22%20fill%3D%22%23FFFFFF%22%20points%3D%2220.2%2C20.2%2012.25%2C20.2%2016%2C29%209.667%2C31.75%205.75%2C22.5%200%2C28%200%2C0%20%22%2F%3E%3Cpolygon%20id%3D%22inner%22%20opacity%3D%220.5%22%20fill%3D%22%23231F20%22%20points%3D%226.373%2C19.482%201.75%2C23.904%201.75%2C4.225%2015.975%2C18.45%209.602%2C18.45%2013.708%2C28.087%2010.59%2C29.441%20%22%2F%3E%3C%2Fsvg%3E"), auto;
}
<div class="transparent_cursor"></div>
Keep in mind when designing:
The visible "pointer tip" of the image used should start in the upper
left corner.
If the image needs to be embedded within the CSS itself, you will need to base64 encode - or you can also URL encode for SVG. Using SVG without encoding did not work in my tests.
The resolution will be in CSS pixels, so it will look bad on Retina Display. This is true even if SVG is used, because browsers seems to want to want to rasterize in CSS pixels. Bummer.
A cursor fallback value such as , auto needs to be included after url(). Details here.
As for animating CSS URLs, I was able to find an example of how this can be achieved. Here's the gist of it:
#keyframes cursor_fade_out {
0% {cursor: url('cursor_opac100.svg'), auto}
25% {cursor: url('cursor_opac75.svg'), auto}
50% {cursor: url('cursor_opac50.svg'), auto}
75% {cursor: url('cursor_opac25.svg'), auto}
100% {cursor: url('cursor_opac0.svg'), auto}
}
So you will need to create an image for the cursor at each opacity level.

Related

Can divs below a css transform move along with divs above?

I am using css transitions to lay out a bunch of divs on top of each other. At any point, one of the divs may collapse. And all of the divs below it are supposed to move up to fill its spot.
Here is a codepen that describes the situation.
The css I am using is the following:
div {
height: 100px;
width: 100px;
margin: 15px;
}
.top {
background-color: red;
transform-origin: top;
animation: move 2s infinite;
}
.bottom {
background-color: blue;
}
#keyframes move {
0% {
transform: rotateX(0deg);
}
50% {
transform: rotateX(90deg);
}
}
With this, the top div will expand and contract. I want the divs below it to move up as the top one collapses.
If I switch transform for height, like this:
#keyframes move {
0% {
height 0;
}
50% {
height: 100px;
}
}
The bottom divs do move, but this is not a good solution for me because in the actual application, each div has a dynamically calculated size.
How can the bottom divs move smoothly with the top div?
With transform you won't be able to do that, as when an element is transformed, the surrounding elements won't see any change in the DOM, as DOM-wise nothing have happened.
What you can do to optimize it all, is to prepare the browser that the height will change, with the property will-change: height
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
This new CSS property aim's to do what transform does, make smoother and more optimized animations.
Do note though:
will-change is intended to be used as a last resort, in
order to try to deal with existing performance problems. It should not
be used to anticipate performance problems.
Another possible solution (read hack), is to trick the browser to use GPU instead of CPU, shown in this answer (see its p.1):
CSS `will-change` - how to use it, how it works
Updated
In case of the height is auto, or similar, this will work with the max-height trick, and here is a couple of answers of mine, showing how-to:
CSS Animation on max-height change
Can't use the same animation in reverse for class toggle
CSS transition auto width
And the last resort, if none of the above is applicable, is to use a small script and either create a styles dynamically (links below), or set them inline.
Dynamically styling pseudo-elements using jQuery or Javascript
How to prevent css from getting converted to inline css

JS-less responsive images with GIF shown on :hover

Goal: static images with animations shown on :hover that do not exceed container width.
Fixed code:
/* wrapper paragraph*/
.rimg {
text-align: center;
overflow: hidden;
}
/* rely on contents for vertical size, show backgrund centered */
.rimg-gif, .rimg-png {
display: block;
position: relative;
background-size: auto 100%;
background-position: center;
background-repeat: no-repeat;
line-height: 0;
}
/* containers need max-width in IE */
.rimg img, .rimg-gif, .rimg-png {
margin: 0;
max-width: 99.99999%; /* Opera Mini ignores anything above this % */
max-width: calc(100% - 0px); /* for proper browsers */
}
/* hide the GIF background unless hovered */
.rimg-gif:not(:hover) {
background-image: none !important;
}
/* hide the static image when hovered */
.rimg-gif:hover img {
opacity: 0;
}
<p class="rimg">
<span class="rimg-png" style="background-image:url(https://i.imgur.com/iwczbln.png)">
<a class="rimg-gif" target="_blank" href="https://i.imgur.com/TLxp2di.gif" style="background-image:url(https://i.imgur.com/TLxp2di.gif)">
<img src="https://i.imgur.com/iwczbln.png">
</a>
</span>
Description
</p>
Final structure:
.rimg is just a container element for center-aligning things.
img is the static image (for semantics, printing, and default display). It is hidden via opacity when hovering, which allows to use the context menu to both get URL of GIF ("link") and static PNG ("image address").
.rimg-gif is the animated background GIF that is displayed when hovering (while hiding the static image). It is not loaded until hover. Doubles as a link to the actual GIF (for mobile users)
.rimg-png has a static background and is there solely so that the reader doesn't see the image briefly flashing before the GIF finishes loading the first frame.
There were a few issues with this:
In IE<=11 (non-Edge) sizing to fit width just outright doesn't work - the elements overflow the container instead.
Adding "max-width: 100%" to nested blocks fixed this (by this explanation).
Opera Mini similarly doesn't resize the images to fit container width, but aforementioned fixes for IE have no effect.
I was not able to find any explanations of this, but turns out that Opera Mini simply ignores max-width values roughly equal to 100% (>99.99999%). So I added that for Opera, and max-width: calc(100% - 0px) for modern browsers.
On StackOverflow's snippet preview, calculated height is slightly higher than that of image, which can be seen by it briefly starting to repeat on the bottom. The issue disappears by giving line-height: 0 to .rgif-alt but I'm not sure if that's a hack or not.
Edit: apparently so? Other options include float'ing the elements and using position: absolute, so I guess line-height is pretty alright for elements
Additional details:
HTML is generated from a markdown[-ish] extension so it does not strictly matter if it looks nasty or not. I would like to avoid having image dimensions / aspect ratio hardcoded into generated HTML if possible, though.
Trying to not have the animated GIF load until requested (mouseover), therefore a two-image trick is not preferable.
The intent to avoid JS is due to fact that pages with such elements can be shown inside an embedded browser with JS disabled completely. As you can imagine, having a popup window (or a default browser' tab) open for each animation is undesirable.
If anything is unclear, do tell.
After a bit of trial and error I managed to resolve the issues by myself, so I added notes on solutions and the final (working) code to the question.
I'm not 100% happy with opening a new tab on Android (ideally should play when single-tapping), but all tested browsers close such popup-tabs when pressing Back so maybe it's not too bad. I added a "play" button, which also doubles as a first touch event absorber for mobile (initially covers the link completely, resized to 0% width after a short delay to allow clicking the link). This works both for modern browsers (which trigger :hover and animation playback on first tap and can open link on second tap) and for Opera Mini (which simply opens a popup tab with the GIF). You can see this in action here, for example.

making a:hover shrink the img

My button links are just links in the html with a background image in css. In the CSS I also have the dimensions of the image so that the whole thing is displayed.
I want the image to shrink to 95% whenever the mouse hovers over the image. I have the a:hover css but changing the dimensions to 95% there doesn't do it.
Is there an easy way to do this?
You can see the sample page at http://granthoneymoon.com/temp.html and the nav buttons are at the top inside the header.
This should work:
a { transition: transform 0.5s; }
a:hover { transform: scale(0.95); }
You can change 0.5 to whatever timing suits you best.
Also you would need to add specific -webkit-, -moz- and -o- prefix for older browser versions.

CSS Transform-origin Changing with font-size

I have created a simple SVG animation where it animates on click using a simple CSS transition and transform (see here: http://jsfiddle.net/T9hsW/1/).
I want the SVG to scale with the user's font-size so I sized it in ems. However, I noticed that if I increase the font-size of my browse using cmd-+ then when I click the SVG, the transform-origin appears to be the old transform origin, not the new one, even though I have used % to set the origin:
svg {
width: 4em;
height: 4em;
}
.arrow, .arrows {
transform-origin: 50% 50%;
...
}
This is the desired output after clicking:
This is what it looks like if you increase the browser font size. Note that it is clearly off-center, probably using the original coordinates:
Is there anything I can do about this?

how to make text change when you hover over it without it twitching?

As I understand it, CSS can be used to change the content of an element on :hover in a basic way. I am using this code
HTML:
<button><span>3 replies</span></button>
CSS:
button {width:6em}
button:hover span {display:none}
button:hover:before {content:"Reply!"}
but when I hover over the button, it twitches very badly
I want mine to be smooth like the music player at this link
When you hover over one of the buttons under lease, premium, or trackout price, they switch over to the +add text
here is part of my player http://djwckd.com/test
The important thing is to make sure that your layout does not change on hover. The easiest way to achieve this would be to allocate some space in your layout for all of the parts even when not hovering. I'm not sure what sort of layout you are trying to achieve but here is an example:
button { width: 6em }
button:hover span {display:none}
button:before { width: 100px; content: ""; }
button:hover:before {content: "Reply!"}
By giving the :before pseudo-element a size even when it's not hovered the layout shouldn't change when the content changes. You may need to adjust this for the specific layout you want but the general principle is to make sure all of the size-related properties are specified without :hover and then only adjust non-layout properties (that is, properties that don't affect any box sizes) in the :hover state.
As you provided the link is hovering the background images but in your test link you have given background images before to <a> elements, if you want exactly same as link use background-image: url('image1'); to a and background-image: url('image2'); to a:hover.
You can still use positioning the background-images, for this you should have like this.
+--------------+
| | position this background to a
+--------------+
| + Add | position this background to a:hover
+--------------+
Ok! for this make your background 64px width and 32 px height.
then position your background to
a{background-image: url('image') left top no-repeat; background-position: 0% 100%;}
now position your background to
a:hover{background-position: 0% 0%;}
I think I have a solution. The trick was one main thing: setting the width of the text's container. I also used onmouseenter instead of onmouseover for faster text change (my theory that onmouseenter is faster then onmouseover). Here is an example:
var videoplayer = {
text: "<b>Hello World</b>",
author: "(you)"
}
<div onmouseenter="this.innerHTML = videoplayer.text;" onmouseleave="this.innerHTML = '<b>(hover over me)</b>';" style="background-color: red; padding: 10px; width: 110px; text-align: center; color: white;">(hover over me)</div>
Just make sure you set the div's width to the width you need. (If you don't want a background, just change the part that says background-color: red to background-color: transparent). One more thing: you have to use a div or other container with display:block set as its default. I suggest using div. Hope this helps!

Resources