Could someone have a look at my code. what it's suppose to do is animate the img tags using fadeIn and fadeOut but it only fades out the first img and doesn't fade in the second img. I think my css could be wrong and that's why the second image isn't showing Im not getting any errors
its an image on top of another image
jQuery
$(document).ready(function() {
$('.social-media a').on('mouseenter', function(e) {
$(this).find("img:nth-child(2)").fadeIn();
$(this).find("img:nth-child(1)").fadeOut()
});
})
HTML
<div class="social-media">
<a title="Share On Twitter" href="#">
<img alt="" src="images/icon_twitter.png" />
<img class="test" alt="" src="images/icon_twitter_active.png" />
</a>
</div>
CSS
.social-media {
padding-top: 20px;
width: 166px;
margin: 0 auto 10px auto;
}
.social-media a {
position: relative;
width: 55px;
height: 51px;
}
.social-media a img:nth-child(1) {
opacity: 1;
}
.social-media a img:nth-child(2) {
position: absolute;
left: 0; top: -33px;
opacity: 0;
z-index: 2;
}
Instead of hiding the second <img> element with zero opacity, you should use display: none instead:
.social-media a img:nth-child(2) {
position: absolute;
left: 0; top: -33px;
display: none;
z-index: 2;
}
http://jsfiddle.net/8vH4E/
However, I would strongly recommend using a simple CSS image sprite to achieve this effect, which doesn't require JS.
Update: Since OP asked if it is possible to do with CSS, I have modified the Fiddle to exclude the use of JS and simply rely on the use of CSS and pseudo-elements: http://jsfiddle.net/8vH4E/2/
.social-media a {
display: block;
position: relative;
width: 100px;
height: 100px;
background-image: url(http://placehold.it/200x200);
background-size: cover;
}
.social-media a::before {
background-image: url(http://placehold.it/200x200/4a7298/eeeeee);
background-size: cover;
content: '';
display: block;
opacity: 0;
pointer-events: none;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
-webkit-transition: all .25s ease-in-out;
transition: all .25s ease-in-out;
}
.social-media a:hover::before {
opacity: 1;
}
My strategy is rather simple:
Use background images instead. For sizing, I have used cover but you are free to use any sizing (absolute pixel/point sizes, relative percentage sizes or dynamically-computed sizes like cover, contain)
For the hover state, use an absolutely-positioned pseudo element that covers the entire <a> (by positioning it absolutely and with zero offset from all four directions). We don't need pointer events on the pseudo element, so we set it to pointer-events: none
When the <a> element is hovered on (targeted with the :hover selector), we toggle the opacity of the pseudo-element from 0 to 1. We declare the transition property on the pseudo-element to allow for smooth, browser-computed and JS-agnostic transition.
the sprite is good but does not give smooth fading animation (think that was the main reason, KDM, wasn't it?).
So let's fix existing code:
as the fadeOut() turns the element to the display: none; state, as the fadeIn() starts working when the element is display: none;. So let's turn the 2nd image in display: none; first;
We can omit the opacity at all for both images (relying on 1.0 as default); $.fadeIn/Out() use the opacity from the CSS as the start/end point of the animation. Of course you can set the opacity explicitly for each image if it's designed in such way;
display: inlibe-block; for the <a> is a good point because it contains inline elements which possibly can disappear (display: none;); that causes the the whole <a> disappearing and the mouseleave event firing with unexpected UI bugs.
Enjoy http://jsfiddle.net/8vH4E/1/ and thanks to Terry for the fiddle :)
Related
I'm looking for a relatively simple and standard way of changing CSS pseudoelement property value by JS Scrollspy.
The parent element (section of a landpage) should change grayscale, while scrolled, and its child should have position:fixed.
As it turns out, it's impossible to make it in an easy way, because any filter is removing position:fixed by definition. More about this: CSS-Filter on parent breaks child positioning
Moving that background-image to a pseudoelement creates another problem: manipulation of the pseudoelement's properties by JS.
The expected result: I wanted to make a section of a landing page, having grayscale filter for background image. That's the easy part. But it should has less grayscale, while moving upward (the more picture user see, the more color it has), and centered content element shuffles up from previous section, and later hiding under next one.
So basically I need two things:
filter grayscaled background image, with dynamically changing value of a grayscale, relative to distance to the top of the window (JS scrollspy)
position:fixed central content element visible only in that section
Illustration (with background-picture in pseudoelement) is here: https://codepen.io/tdudkowski/pen/MLyMyG
HTML
<section class="one">
</section>
<section class="two">
<div><p>DIV with a position:fixed</p></div>
</section>
<section class="three"></section>
CSS
section {
position: relative;
max-width: 1000px;
height: 70vh;
background-color: #eee;
margin: 0 auto;
overflow: hidden;
}
.two {
background-color: transparent;
/* Try to uncomment rule below */
/* filter: grayscale(50%); */
}
.two div {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 30rem;
height: 10rem;
background-color: #f00;
z-index: 1;
}
.one,
.three {
z-index: 100;
}
/* background of section */
section.two::after {
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-image: url(https://picsum.photos/1000/200);
background-size: cover;
background-repeat: no-repeat;
z-index: -1;
/* filter: grayscale(50%); */
}
I'm trying to build a simple image slider with css and javascript, I have an UL with some LI inside. the images are LI's backgrounds so I just have to move two LI, the active one and the next one, to make the slider work.
When the "next" button is pressed I add classes to the two LI and what happen is that the already visible li perform his transition disappearing on the left but the second LI snaps in position without sliding in from the right. I can't understand where i go wrong and why the second LI doesn't trigger the transition.
Here is a pen with some code:
https://codepen.io/luzzuc/pen/xONywP
HTML
<ul>
<li class="active" style="background-image: url(http://static.giantbomb.com/uploads/original/0/26/9780-itsahim.JPG)"></li>
<li style="background-image: url(http://vignette3.wikia.nocookie.net/fantendo/images/5/5b/NSMBDIY_Mario_Jump.png/revision/latest?cb=20100405031309)"></li>
</ul>
<br><br>
<button id="next">Next</button>
CSS
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 20%;
padding-top: 12%;
position: relative;
background: #000;
overflow: hidden;
}
li {
position: absolute;
visibility: hidden;
width: 100%;
padding-top: 60%;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
top: 0;
left: 0;
}
.active {
visibility: visible;
transition: left 2s;
}
.active-slide {
left: -100%;
}
.next {
left: 100%;
visibility: visible;
transition: left 2s;
}
.next-slide {
left: 0;
}
Javascript
var b = document.getElementById('next');
b.addEventListener('click', animate);
function animate() {
var a = document.querySelector('.active');
var b = document.getElementsByTagName('li')[1];
b.classList.add('next');
a.classList.add('active-slide');
b.classList.add('next-slide');
}
Kindly try this version: https://jsfiddle.net/urhn8b6k/
First of all, the initial status of the 2nd li is left: 0; and the css indicated that from left: 0; to left: 100%; with transition: left 2s; in .next, so you have to move transition: left 2s; to .next-slide
While doing b.addClass... a.addClass... b.addClass... that's simply doing b.addClass("next next-slide"), try put the second addClass into a setTimeout with delay 1ms should solve the problem
obviously once posted the question I found the solution. It turns out that to trigger the second transition a browser redraw is necessary. in order to make the browser to redraw the page a simple operation in an element is enough so I simply ask for offsetHeight of the element ad so the code that was:
b.classList.add('next');
a.classList.add('active-slide');
b.classList.add('next-slide');
became:
b.classList.add('next');
a.classList.add('active-slide');
var f = b.offsetHeight;
b.classList.add('next-slide');
and everything works fine
I'm making a very unique progress bar that visually looks like a glass orb filling up with liquid. Unfortunately, because of the rounded shape, the traditional method of modifying the height doesn't work so well (as demonstrated with this fiddle https://jsfiddle.net/usuwvaq5/2/).
As you can see, having the div height "slide up" is not the desired visual. I have also tried playing a bit with css clip, but was unable to get it to work for me. How can I create the visual effect of the glass "filling" with the second image?
Simply add background-position:bottom; to #inner-progress:
#inner-progress {
background-image: url(https://www.novilar.com/img/battle/ui/purification_meter_bar.png);
background-color: transparent;
background-position:bottom;
width: 100%;
overflow: hidden;
position: absolute;
bottom: 0;
height: 0%;
}
JSFiddle Demo
Jacob Gray probably has the best answer, but here's an alternative:
Fiddle
This approach uses css for the animation, instead of javascript. JS is only used here to trigger the animation, the rest is css.
This uses the css transition property to "animate" the height as it changes from 100% to 0%. The only notable change in the html is that I swapped the background of the inner with the outer.
Perhaps this answer will be a better solution to a future reader of this thread - depending on their implementation and/or preferences.
$(document).ready(function() {
$('#inner-progress').addClass("load");
});
#outer-progress {
background-image: url(https://www.novilar.com/img/battle/ui/purification_meter_bar.png);
background-color: transparent;
border: 0;
height: 100px;
width: 100px;
position: relative;
}
#inner-progress {
background-image: url(https://www.novilar.com/img/battle/ui/purification_meter_background.png);
background-color: transparent;
width: 100%;
overflow: hidden;
position: relative;
bottom: 0;
height: 100%;
transition: height 3s;
-webkit-transition: height 3s;
}
.progress-value {
color: #FFF !important;
font-weight: bold;
position: absolute;
top: 40%;
left: 40%;
}
.load{
height: 0% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="outer-progress">
<div id="inner-progress" value="0" max="100"></div>
<span class="progress-value">0%</span>
</div>
I have a trouble with an effect I want to achieve.
When I put the mouse over this element :
<div class="process">
<h3 class="text-center">Process</h3>
<ul class="row text-center list-inline wowload bounceInUp animated" style="visibility: visible; animation-name: bounceInUp;">
<li data-id="Reflexion">
<span><i class="fa fa-flask"></i><b>Reflexion</b></span>
</li>
</ul>
</div>
I want to have an overlay over all the page and over this overlay my <ul>...</ul>
I have tried with z-index and position but it doesn't work, my overlay is always over all the page and over the <ul>...</ul>
Here is the style of <ul></ul> and .overlay
.process ul li{
width: 10em;
height: 10em;
border: 1px solid #CEEBF0;
padding: 0;
border-radius: 50%;
margin: 0 1.25em;
line-height: 13.5em;
color: #21ABCA;
-webkit-transition: border-color 0.5s ease-in; /* Safari */
-moz-transition: border-color 0.5s ease-in; /* Firefox */
transition: border-color 0.5s ease-in;
}
.process ul li span{line-height: 2em;display: inline-block;font-weight: 300;}
.process ul li span i{font-size: 3em;}
.process ul li span b{display: block;font-size: 1em;font-weight: 300;}
.process ul li:hover {
border-color:#3498db;
background-color: rgba(52, 152, 219,1.0);
}
.overlay {
position: fixed;
z-index: 50;
background-color: red;
height: 100vh;
width: 100vw;
}
Here is the script I'm using to listen mouse event :
$(".process ul li").on({
mouseenter : function() {
$('#overlay').addClass('overlay');
},
mouseleave : function() {
$('#overlay').removeClass('overlay');
},
});
Update
There is a Fiddle that show better than words my trouble
When I make overlays I usually use absolute positioning to get it right. Without knowing what effect you want specifically, here's a generic demo of how an overlay might work.
fiddle
By setting the overlay's position to absolute, and all of its positional attributes to 0, it covers the box it's bound to completely without having to worry about setting widths or heights.
Hope this helps!
EDIT
I know you've solved the issue, but for those who may look later, here's a link to a fiddle wherein the issue has been solved.
fiddle
The Z-index property only works when both elements are positioned manually. Make sure the list has position: relative or position: absolute too, not just the overlay. Then you need to give a higer value to the z-index of the list.
EDIT: try adding this to your code:
.process {
position: relative;
z-index: 100;
}
You'll have to actually play with Z-index to make sure only the hovered panel is in front of the overlay if that's what you want, but this proves that you need to set a position attribute on what you want to be manually z-positioned.
I'm using the background-blend-mode on this:
<a href="#" class="blend">
<h3>Title</h3>
<p>Content goes here</p>
</a>
It has a url set for the background-image. When .blend is hovered over, it changes the background to this:
.blend:hover {
background-blend-mode:multiply;
background-color: rgba(0,0,0,.6);
}
So it works, but not in IE (of course). What alternatives are there? Is there some sort of jQuery trick that I can use to get it to work in IE? Or is there a prefix I could use, say -ms- or something similar?
Not the best solution I know, but as IE and MS Edge can't use background-blend-mode (http://caniuse.com/#feat=css-backgroundblendmode).
I get around this by adding a :after class to the element and manipulating that via background-colour and playing with the opacity on the pseudo element.
DEMO
https://codepen.io/nicekiwi/pen/PmZdMK
HTML
<div class="blend"></div>
CSS
.blend {
background-image: url('http://placekitten.com.s3.amazonaws.com/homepage-samples/408/287.jpg');
background-repeat: no-repeat;
background-attachment: cover;
width: 200px;
height: 200px;
position: relative;
}
.blend:after {
width: 100%;
height: 100%;
content: '';
background-color: red;
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 0.3s; /* lets transition to be fancy ^_^ */
}
.blend:hover:after {
opacity: 0.3;
}