I am using the method outlined here to fade in a background image on hover of an element.
My codepen example:
http://codepen.io/anon/pen/vqtjf
HTML:
<div><span></span></div>
CSS:
div {
position: relative;
width: 219px;
height: 218px;
background: url(https://dl.dropboxusercontent.com/u/3454522/home-option-icon-off.png) no-repeat;
}
span {
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
background: url(https://dl.dropboxusercontent.com/u/3454522/home-option-icon-energy.png) no-repeat;
opacity: 0;
-webkit-transition: opacity 0.5s;
-moz-transition: opacity 0.5s;
-o-transition: opacity 0.5s;
}
div:hover span {
opacity: 1;
}
The problem I'm having is that in Firefox (Mac) the background image of the span is not quite aligned with the background image of the span so when it fades in you can see a small movement (In the codepen the shift is vertical but in my project where the code is amongst a whole lot of other junk I actually had a horizontal shift). If you resize the Firefox window the problem is fixed.
A screencast of the effect can be seen here:
https://dl.dropboxusercontent.com/u/3454522/firefox-fadebg-problem.mp4
(View at 100% to see the problem which is subtle).
Any idea on whats causing this or how to fix?
I think it's a regression in how Firefox renders images with opacity animation, especially when the images has been resized with HTML width/height attributes (usually by more than half).
The effect can be very subtle like a slight off-setting (~1 px) or a kind of antialiasing.
STR:
1. Open the testcase I joined
2. Move the mouse over the images to animate the opacity
3. Try at different zoom levels to observe the off-setting/antialiasing
WORKAROUND: adding "box-shadow: #000 0em 0em 0em;" to images fixes the bad rendering.
source: https://bugzilla.mozilla.org/show_bug.cgi?id=745549
I had the same problem. Solved it by adding the following to the images css.
transform: translate3d(0,0,0);
Related
I've got this code...
<img class="logo" src="img/logo.jpg"> <!-- Logo size is 96x96 -->
...and this
.logo {
transition: .5s;
}
.logo:hover {
transition: .5s;
width: 128px;
height: 128px;
}
It resizes on hovering, but not with transitioning. I just hover it and it instantly resizes, and I have no idea why does transition not work.
There are several things wrong with the CSS causing it not to transition.
First, as #WaisKamal said, you need to set initial states to transition from. Images size automatically in HTML but that's not a valid starting point for CSS.
Second, you need to define WHAT properties are being transitioned.
So you would need to add width and height. Or you can use the all identifier:
.logo {
display:block; //make sure the image is a block element
width: 96px;
height: 96px;
transition: all 0.5s linear;
}
.logo:hover {
width: 128px;
height: 128px;
}
Now that will work but it's going to be kind of janky since animating height/width cause page repaints.
Instead, I would suggest using a transform on the image.
.logo {
display:block; //make sure the image is a block element
// initial size is fine here because we're using a transform
transition: transform 0.5s ease-in-out;
}
.logo:hover {
transform: scale(2) // decimal notation 2 = 200% = 128x128px
}
There is no need to define the same transition property for the image and the hover pseudoclass. If you don't define transition in .logo:hover, it will take the previously set value of half a second.
The problem here is that you must specify an initial width and height for the image in order to have it resize smoothly.
I'm trying to create a transition for both an image and a pseudo element of its container, but for some reason, these transitions appear to be out of sync with each other, resulting in the pseudo element reaching a opacity: 0 state before the image does.
I've tried various combinations of style rules, but I never managed to accomplish an ease-in-out transition to work correctly.
Here's some context for the current code: the image is padded on purpose, to provide a better visual (centered) of its content. The images that'll be used are always guaranteed to have a white background. That's why I'm using a pseudo-element with a white background color to fill the vertical spaces that the image does not cover.
The background-image should take the full width/height of the container and there are not guarantees of its background being white.
The desired effect is for both the pseudo-element and image to reach opacity: 0 at the same making it look like its a single element.
I'm also considering using an ::after pseudo element to provide a "loading skeleton" while the image is not retrieved from the server, but that's not a concern for now.
Here's the code, and the respective fiddle: https://jsfiddle.net/rjk2z31d/1/
*,
*::before,
*::after {
box-sizing: border-box;
}
.box {
width: 248px;
height: 320px;
}
.image-box {
position: relative;
display: block;
background-repeat: no-repeat;
background-size: cover;
line-height: 0;
background-color: #FFFFFF;
&::before {
display: block;
content: "";
width: 100%;
padding-top: (100% + (100% / 3));
}
img {
z-index: 1;
position: absolute;
top: 50%;
left: 0;
width: 100%;
transform: translate3d(0, -50%, 0);
padding: 16px 16px;
}
&::before, img {
background-color: #FFFFFF;
opacity: 1;
transition: all 1.5s ease-in-out;
}
&:hover {
&::before, img {
opacity: 0;
}
}
}
<div class="box">
<div class="image-box" style="background-image: url('https://via.placeholder.com/248x320/FF0000/000000?text=Background')">
<img src="https://via.placeholder.com/248x320/FFFFFF/000000?text=Image">
</div>
</div>
Actually, they both fade at the same speed.
The out-of-sync effect you're talking about is an illusion due to the opacities overlapping.
If you set the initial opacity of both elements, it's easier to understand what's going on.
The image's faded white added to the pseudo element's faded white looks less transparent than the pseudo element's faded white alone.
See it in effect with the below image:
If you need to be convinced of their synchronization, add a transform rule to the :hover handler. the result is synced as it is supposed to be.
As a workaround, I would suggest you to try figuring out a better approach than fading overlapping elements.
You could use the <picture> tag with css object-fit property to get rid of those blank spaces.
picture doc
object-fit doc
I have an image near the top of a webpage. I've made it so that when I hover on the image, it zooms in slightly. However, in doing so, I've messed something up that causes the image to only display one portion whether hover is activated or not. I've tried removing portions of the code I added, but can't seem to fix it without completely removing the hover animation. I've also tried changing margin, padding, and position. I'm using Bootstrap 4 if that makes a difference. I'm sure it's something simple, I just can't seem to figure out what needs to be changed.
Here's a link to the Codepen: https://codepen.io/amandathedev/pen/zyEyze
Here's the relevant portion of the CSS:
.imgBox {
float: left;
position: relative;
width: 640px;
height: 360px;
margin: 0 auto;
/* justify-content: center;
display: inline-block; */
overflow: hidden;
}
.imgCard {
position: absolute;
top: 0;
left: 0;
}
.imgCard img {
-webkit-transition: 0.4s ease;
transition: 0.4s ease;
}
.imgBox:hover .imgCard img {
transform: scale(1.05);
-webkit-transform: scale(1.05);
}
You need to set transform-origin to center so that it will scale from center on, so your css must look like this:
..other css
.imgBox:hover .imgCard img {
transform: scale(1.05);
transform-origin: center;
-webkit-transform: scale(1.05);
}
Looking at your code example on codepen, the solution looks to be making the width of the img 100%. So in your example you would do something like:
.photo {
width:100%
}
However, this cuts off the bottom of the image. You're going to need to adjust the height of the imgBox that contains the imgCard. It's currently set to 360px. Because of the way your example is written, it will probably be best for you to just choose a number so that the resulting image will have the same aspect ratio as the original image (playing around with it, 478px looks like the magic number to show the entire image).
on my website I have a background button that is "hidden" (it blends in with the background, but is secretly a button) and it was working fine until I edited my page with text on it.
On some monitors the text covers the image, but not completely - there is space below and beside it where the image peeks through.
However, this makes the image overlap the text, breaking the illusion. Setting the z-index to -1 makes it go behind the text, but makes it unable to be clicked.
Is there any way to make something behind text clickable while staying behind text?
The "eye" between the columns is the hidden image.
Current code for image:
<a href= "/aboutme/vision.html">
<img style="position:absolute; top:354px; left:975px; width:108px; height:32px; z-index:-1" src="eye.png">
</a>
I rearranged the website layout to use a clickable div instead of an image, and now it works on click even if text is over it. I then put it in a nested div which is the size of the entire window, so the links never get misaligned based on window size:
HTML:
<div id="bodyDiv">
<div class="secret" style="position:relative; top:770px; left:1168px; width:108px; height:32px; background-color:black;" onclick="location.href='/aboutme/vision.html'"></div>
</div>
CSS:
#bodyDiv {
background-image: url("homebackgroundsmall.png");
background-repeat: no-repeat;
background-position: center;
height: 1200px;
width: 1684px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -842px;
}
The downside to this is that there is no mouse change on hover, making the secrets overly hidden. To personally fix this to make it more obvious, I made the .secret class so on hover the background portion of the div fades out by increasing the background opacity to 1 (which is black):
CSS:
.secret {
opacity: 0;
transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
}
.secret:hover {
opacity: 1;
}
I have designed a navigation bar with 5 page 'links' that have equal width. When hovered over these reveal a drop-down with more links relevant to that page. See the navigation jsFiddle. This works perfectly.
The problem
When I placed the navigation bar into my site it doesn't work as intended. The drop-down animations lag quite a lot and there are white bars that randomly appear at the sides of the page (Windows 7 Ultimate, Chrome 24, other OS's and browsers untested). See the site here.
The white bars
Example markup
<nav id="nav">
<ul id="nav1">
<li>
<span>Games</span>
<div>
<span>All Games</span>
<span>Free Games</span>
...
</div>
</li>
...
</ul>
</nav>
Animation CSS
#nav1 > li > div {
position: absolute;
margin: 5px 0 5px -45px;
top: 0;
left: 50%;
max-height: 30px;
width: 90px;
opacity: 0;
overflow: hidden;
-webkit-transition:
width 500ms,
max-height 500ms,
opacity 200ms ease 400ms,
margin-left 500ms;
}
#nav1 > li:hover > div {
max-height: 200px;
width: 200px;
opacity: 1;
margin-left: -100px;
-webkit-transition:
width 500ms,
max-height 1s ease 500ms,
opacity 200ms,
margin-left 500ms;
}
What I tried
After unsuccessfully spending an hour looking for the problem, I decided to make a jsFiddle of my entire site to see if that would identify the problem. To my surprise it works fine in the jsFiddle.
Edit: After more testing I have determined that the problem occurs when a transition on the width or height of #nav1 > li > div completes. It is also definitely related to the transitions. Not sure if this helps.
My question
If anyone could provide some insight into the problem, it would be much appreciated. I have absolutely no clue what the cause of the problem is or how to fix it.
Note: The navigation is currently only animated in Chrome.
The problem is:
#mainbar
Get rid of that and see if your problems don't go away. But it's more than that. This encompasses the entire width of the DOM:
width:100%;
And it has a higher z-index than the #wapper el, which is only taking up a part of the page. The #mainbar el is overlaying the areas on the side where #wrapper isn't. But because there isn't anything there (style-wise) you get the default white of the browser bg; hence, the white bars on the side.
If you think I'm wrong, set
#mainbar{width:700px;}
You'll see your white bars have expanded to new uncovered regions. :P
Simple solution:
#wrapper{z-index:0;}
That should solve it.