Fading between sprite images without calling out image url in CSS - html

Is it possible to fade between sprite images on hover without calling out the image URL in the CSS?
I have a ton of two-image sprite sheets. I want each one to switch on hover, but the CSS will be far too bloated if I have to create a new element for every one with a "background: url(x)".
.frame {
height: 500px;
width: 500px;
overflow: hidden;
}
.sprite {
background: url(image.png) 0px 0px no-repeat;
position: relative;
height: 500px;
width: 500px;
}
.sprite::after {
content: "";
background: url(image.png) -500px 0px no-repeat;
opacity: 0;
transition: opacity 0.35s;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.sprite:hover::after {
opacity: 1;
transition: opacity: 0.35s;
}
I'd rather call them out here:
<div class="sprite frame">
</div>
Here's a JSFiddle of the effect I want, but I want to call out the image URL in the HTML, so I don't have 100 different CSS elements calling out different images.

Hmm. If you are open to a jQuery solution this may help. You can use a "data alt-src" HTML attribute to store two image URLs within one tag, then call a jQuery .hover() function on that class.
HTML:
<img class="xyz" data-alt src="http://cdn1.iconfinder.com/data/icons/fatcow/32/accept.png" src="http://cdn1.iconfinder.com/data/icons/fatcow/32/cancel.png" />
jQuery:
var sourceSwap = function () {
var $this = $(this);
var newSource = $this.data('alt-src');
$this.data('alt-src', $this.attr('src'));
$this.attr('src', newSource);
}
$(function () {
$('img.xyz').hover(sourceSwap, sourceSwap);
});
http://jsfiddle.net/LmVRZ/2/
I realize this demo doesn't include the opacity transition but I think it could be built in.

Related

Toggle Div Style Between Opened (Display: Block) and Closed (Display: None) With jQuery

I have two divs that appear like this:
The idea is that when you close the bottom div (click on the 'X'), it should disappear.
And when you close the top div, it should disappear, and also the bottom div should slide up and take its place.
I'm very new to jQuery, but this is my first attempt:
function initAnnouncements() {
$(document)
// Closes announcement modules
.on('click', 'annoucements-close', function () {
$('announcement-div').hide();
})
}
#keyframes slideInFromRight {
0% {
transform: translateX(100%);
}
.1%{
opacity: 1;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
.announcements-container {
position: fixed;
top: 80px;
right: 20px;
z-index: 1001;
display: flex;
flex-direction: column;
width: 300px;
/* align-items: flex-end; */
}
.announcements-1 {
animation: slideInFromRight 0.4s ease;
opacity: 0;
animation-fill-mode: forwards;
}
.announcements-2 {
/* animation: 0.4s ease-out 0s 1 slideInFromRight; */
animation: slideInFromRight 0.4s ease;
opacity: 0;
animation-fill-mode: forwards;
animation-delay: .4s;
margin-top: 15px;
}
.annoucements-header {
background-color: #1481C3;
color: #ffffff;
font-family: "Proxima Nova Bold";
padding: 7px 10px;
}
.annoucements-close {
position: absolute;
right: 5px;
width: 24px;
height: 36px;
cursor: pointer;
opacity: .85;
}
.annoucements-close:hover {
opacity: 1;
}
.annoucements-close::before,
.annoucements-close::after {
content: '';
width: 24px;
height: 2px;
background: white;
position: absolute;
top: 7px;
left: 0;
}
.annoucements-close::before {
transform: rotate(-45deg);
}
.annoucements-close::after {
transform: rotate(45deg);
}
/*opened or closed*/
.announcement-div-opened {
display: none;
}
.announcement-div.opened .announcement-div-opened {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="announcements-container">
<div class="announcement-div announcements-1">
<div class="annoucements-header">
<span class="annoucement-type-quantity">2 School Announcements</span>
<i class="annoucements-close"></i>
</div>
</div>
<div class="announcement-div announcements-2">
<div class="annoucements-header">
<span class="annoucement-type-quantity">1 Admin Announcement</span>
<i class="annoucements-close"></i>
</div>
</div>
</div>
</body>
As you can see this isn't doing anything. I'm trying to toggle the class from 'open' (display:block) to 'closed' (display:none) when the annoucements-close <i> element is clicked on.
And ideally I would like for the second div to slide up when the top one is closed, but first I'd just like to get either one to disappear.
What's wrong with my code where that's not working as expected?
Link to JSFiddle
There are 2 issues with your code: the click() event is inside the function initAnnouncements that doesn't get called. You could move it outside of this function or call the function. Then you have issues with your selectors: It's
.on('click', '.annoucements-close', function () {
$('.announcement-div').hide();
})
instead of
.on('click', 'annoucements-close', function () {
$('announcement-div').hide();
})
for class selectors. Working Fiddle.
If you just want to hide the annoucement which was clicked upon, just change it to
.on('click', '.annoucements-close', function () {
$(this).closest('.announcement-div').hide();
})
I looked at your code and adjusted it a little to demonstrate:
Added your common class on the two announcements "announcement-div"
Attached the document click handler with the jQuery ready event
Used the delegated event selector to listen to clicks within the document that match that common selector
On click of one of the announcement-div's animate the height to 0 and then remove the element
Comments are included in the fiddle. Hope this is helpful!
// Fire this function when the document is ready
$(function() {
// Listen on the whole document for click events on the .announcement-div element
$(document).on('click', '.annoucements-close', function () {
// From the close button find the closest parent "announcement-div"
var annoucement = $(this).closest('.announcement-div');
// Function to run after animating the element (use .hide() to keep element but display:none)
function destroy() {
annoucement.remove();
}
// Animate the annoucement's height to 0 over 400ms and then call the destroy function
annoucement.animate({ height: "0px" }, 400, destroy);
});
});
Updated JS Fiddle

How can I retain img link functionality while using an overlay?

I have a series of round images that are part of an image gallery. I’ve added an overlay and positioned the text in the location that I want, but now the overlay is removing the URL link to the image, and I'm trying to get the overlay to retain the link.
I’m working with a SquareSpace template so I can’t move any of the blocks around as they are rendered by CMS.
The text is in this here: .image-slide-title, and the image is here: .thumb-image .loaded, and the link has these classes: image-slide-anchor .content-fit
This is the page I'm working on: https://cesare-asaro.squarespace.com/work
And this is the code that I have so far for this particular section:
#portfolio {
background-repeat: repeat;
background-color: rgba(239,93,85,1);
}
.margin-wrapper:hover { //for portfolio hovers
position: relative;
}
.margin-wrapper:hover a:after {
opacity:.8;
}
.margin-wrapper a:after {
border-radius: 50%;
content: '\A';
position: absolute;
width: 100%; height:100%;
top:0; left:0;
background:rgba(255,255,255,0.8);
opacity: 0;
transform: scale(1.002)
margin: 0 -50% 0 0;
transition: all .7s;
-webkit-transition: all .7s;
}
.sqs-gallery-container{
overflow: visible;
}
.margin-wrapper:hover .image-slide-title{
opacity:1;
color: rgba(239,93,85,1);
-webkit-transition: all .7s;
}
.image-slide-title{
font-size: 50px;
text-transform: uppercase;
line-height: 100%;
opacity:0;
position: absolute;
margin: -100% 0;
height:100%;
width: 100;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
white-space: normal;
}
I’m getting quite confused by the different approaches, some with JS some without, and the multiple uses of :after and :hover (I just tinker a bit with code).
Your overlay is probably blocking the click event to the thing below it, preventing it from triggering the link.
Just add pointer-events: none to the overlay. This will make it not capture the click, allowing it to fall to the element below it.

CSS Animation won't apply for the second time

I am currently having a problem with CSS animations. A random background is called from an array, shows up and changes and so on. I applied two animation for the image caption id, a slide in and a delayed slide out. The slide in and out runs well for the first time, but when the second background shows up, the caption just appears to the screen without any animation.
This is my test page and below is my code.
HTML code:
<script type="text/javascript">
function loadRandomImage(imgs) {
var index = Math.floor(Math.random() * imgs.length);
console.log("loadRandomImages(): index = "+ index);
$.backstretch(imgs[index].url, {duration: 30000, fade: 1200});
$("#caption").html(imgs[index].caption);
}
var images = new Array(); //array of imgs objects
images[0] = {url: "https://s-media-cache-ak0.pinimg.com/736x/a5/47/45/a5474577f4a4ae93c85db719d0cbafd4.jpg", caption: "Caption0"};
images[1] = {url: "https://s-media-cache-ak0.pinimg.com/736x/e6/41/74/e64174e355f78a0f07e951bcec62ca96.jpg", caption: "Caption1"};
images[2] = {url: "https://media.giphy.com/media/3o7abHrsGbV10rCeze/giphy.gif", caption:"Caption2"};
images[3] = {url: "https://media.giphy.com/media/Bbt5FxRiArl3a/giphy.gif", caption:"Caption3"};
// Preload
setTimeout(loadRandomImage, 1000, images);
// Change images every 3 seconds
setInterval(loadRandomImage, 30000, images);
</script>
<div id="pattern"></div>
<div id="pattern2"></div>
<div id="caption"></div>
CSS code:
#caption {
position: relative;
font: 1.5em Trebuchet, sans-serif;
text-align: center;
margin-left: 75%;
z-index: 56;
color: #ffffff;
background: rgba(0, 0, 0, 0.7);
padding: 8px;
animation: slidein 3s, slideout 3s 27s;
}
#caption:empty
{
display: none;
}
#keyframes slidein {
0% {
margin-left: 100%;
width:100%;
visibility:hidden;
opacity: 0;
}
100% {
margin-left: 75%;
width:100%;
opacity: 1;
visibility:visible;
}
}
#keyframes slideout {
0% {
margin-left: 75%;
width:100%;
opacity: 1;
visibility:visible;
}
100% {
margin-left: 100%;
width:100%;
opacity:0;
visibility:hidden;
}
}
CSS animations have iteration count (animation-iteration-count) as only 1 when no value is given for that property. Here since you've not specified any value, the animation executes only once (that is on page load). There is no pure CSS way to re-trigger an animation once it has completed its cycle. It has to be removed from the element and then re-attached for it to start all over again.
So, for your case here is what you have to do - (a) Set the animations on #caption using JS on page load as it makes it easier to remove and re-add them (b) Upon completion of the slideout animation, remove both the animations from the element (that is, set animation-name: none) and also set html of #caption to none because :empty selector would only then hide it. (c) As soon as the next image is set on the element (using loadRandomImage function), set the animations back on the element. This would re-trigger the animation and so during each image switch, the caption would slide-in and out.
Note: I've changed some parts in the HTML and JS that are not relevant to this answer (like removing the two div and replacing them with 1, avoiding the $.backstretch and loading image using css() etc. But these are only auxiliary items and will not affect the crux of this answer (which is, to remove and add the animations).
function loadRandomImage(imgs) {
var index = Math.floor(Math.random() * imgs.length);
$('#img').css('background-image', 'url(' + images[index].url + ')');
$('#caption').css({
'animation-name': 'slidein, slideout',
'animation-duration': '3s, 3s',
'animation-delay': '0s, 7s'
});
$("#caption").html(imgs[index].caption);
}
var images = new Array(); //array of imgs objects
images[0] = {
url: "http://lorempixel.com/100/100/nature/1",
caption: "Caption0"
};
images[1] = {
url: "http://lorempixel.com/100/100/nature/2",
caption: "Caption1"
};
images[2] = {
url: "http://lorempixel.com/100/100/nature/3",
caption: "Caption2"
};
images[3] = {
url: "http://lorempixel.com/100/100/nature/4",
caption: "Caption3"
};
// Preload
setTimeout(loadRandomImage, 1000, images);
$('#caption').on('animationend', function(e) {
if (e.originalEvent.animationName == 'slideout') {
$('#caption').css('animation-name', 'none');
$('#caption').html('');
setTimeout(function() { /* dummy timeout to make sure browser sees animation as none before adding it again */
loadRandomImage(images);
}, 0);
}
});
#caption {
position: relative;
font: 1.5em Trebuchet, sans-serif;
text-align: center;
margin-left: 75%;
z-index: 56;
color: #ffffff;
background: rgba(0, 0, 0, 0.7);
padding: 8px;
}
#caption:empty {
display: none;
}
#keyframes slidein {
0% {
margin-left: 100%;
width: 100%;
visibility: hidden;
opacity: 0;
}
100% {
margin-left: 75%;
width: 100%;
opacity: 1;
visibility: visible;
}
}
#keyframes slideout {
0% {
margin-left: 75%;
width: 100%;
opacity: 1;
visibility: visible;
}
100% {
margin-left: 100%;
width: 100%;
opacity: 0;
visibility: hidden;
}
}
/* Just for demo */
#img {
height: 100px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="img"></div>
<div id="caption"></div>
The animationend event still requires vendor prefixes in some browsers.
You need to use a callback, which is explained here:
How do create perpetual animation without freezing?
I think the animation direction needs to be altered.
These are the possibilities:
animation-direction: normal|reverse|alternate|alternate-reverse|initial|inherit;
I think you need to do one of these:
alternate
The animation will be played as normal every odd time (1,3,5,etc..) and in reverse direction every even time (2,4,6,etc...)
alternate-reverse
The animation will be played in reverse direction every odd time (1,3,5,etc..) and in a normal direction every even time (2,4,6,etc...)
At the moment it is set as
animation-direction: initial, initial;
Seen here: http://www.w3schools.com/cssref/css3_pr_animation-direction.asp
Rather than the Javascript suggestions already provided, you could do a straight CSS solution.
Just set animation-iteration-count to "infinite" (to continuously alternate the 2 elements, or an integer for a set number of repeats)
If you want staggered / alternating animations:
Use an animation-delay (matching the animation-duration) on the second element so it doesn't appear until the first element animation has completed
Build a delay onto the end of your animation (revert to original state # 50%) so that the first element stays hidden while the second animates.

CSS: Fade-in transition in input text?

Is there a way to write a CSS transition that would fade in an input text element while the user is typing?
Currently, text can fade in within a normal HTML text element because we can tell it to transition from 0 to 1 opacity; but input text doesn't exist before a user types it in.
So for example, if I type in my username, the letters that I type fade in, each one going from 0 to 1 opacity in .3 seconds.
I've tried using transition and animation, but want to keep it within CSS.
A possible way to achieve a similar effect: create a partially transparent overlay using linear-gradient and gradually reveal as you type by moving the mask position.
<div id='container'>
<input type='text'></input>
<div class='fader'></div>
</div>
$("input").on("keydown", function(e) {
var width = $("input").val().length + 1;
$(".fader").css("left", (width * 8) + 3);
});
#container {
position: relative;
height: 25px;
width: 400px;
}
input {
width: 100%;
}
input, .fader {
display: block;
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
font-family: monospace;
}
.fader {
top: 2px;
bottom: 4px;
pointer-events: none;
background: linear-gradient(90deg, transparent 0px, white, 15px, white 100%);
transition: left 1s ease;
}
Here's what it looks like as a fiddle:
http://jsfiddle.net/go7trwzx/1/
I don't believe there is any way to do this with an HTML input element, and certainly not without Javascript. Any solution would require you to create individual elements for each letter, then apply transitions to each element individually.
If you'd like a visual of what that would look like, check out the "type" example and accompanying source code here:
http://codyhouse.co/demo/animated-headlines/index.html

CSS3 transform on hover

I'm currently trying to do a transform (rotateY) on an A element, that have already been animated in CSS.
To sum up : the first animation happens when the user scroll to this block, I had a "show" class, which launch a css animation. This works nice. On a second time, when the .show element is hover, I make him rotate. That second animation, as you can see, is buggy. It flickers, and don't work as expected.
Here's the CSS (Sass / Compass) part :
li
width: 23%
float: left
background: top center url('../img/bgHexa.png') no-repeat
&+li
margin-left: 2.5%
& > a
background: url('../img/pictosHome.png') 65px 60px no-repeat
width: 100%
display: block
height: 220px
opacity: 0
position: relative
top: 90px
+transform(rotateY(135deg))
+transition(all 0.6s ease-in-out)
&.show
top: 0
opacity: 1
+transform(rotateY(0))
&.hover
+transform(rotateY(180deg))
The JS part :
if( app.toTop >= $('#prezComp ul').offset().top- app.height/2){
var nb = 0;
var int = setInterval( function(){
var el = $('#prezComp .picto').eq(nb);
el.addClass('show');
nb++;
if( nb > 4) {
clearInterval(int);
}
}, 300);
}
I tried many HTML hacks, I tried with JS, it doesn't work better...
What am I doing wrong ?
Mouse hover is not happing at the time ,Try this code:
CSS:
#prezComp li { //style.css:558
width: 23%;
float: left;
position: relative;
z-index: 100000;
background: top center url("../img/bgHexa.png") no-repeat;
}