Is `overflow: hidden` changing the positioning of absolute children? - css

I have an image gallery sliding images in an out only with css.
See http://codepen.io/anon/pen/xmhzE?editors=110 for the example or the attached code.
It works fine as long as the #images-div does not have overflow: hidden set. When overflow is set to hidden, the absolute positioning of the single images does not work anymore. When I use negative values for the left-property of the images it also works with overflow hidden.
Does overflow:hidden change the way how absolute children are layouted?
Does anyone has a solution to this problem?
Sources
index.html:
<div id="images">
<img id="image1" src="http://i.imgur.com/dL3io.jpg" />
<img id="image2" src="http://i.imgur.com/qASVX.jpg" />
<img id="image3" src="http://i.imgur.com/fLuHO.jpg" />
<img id="image4" src="http://i.imgur.com/5Sd3Q.jpg" />
</div>
<div id="slider">
1
2
3
4
</div>
base.css:
body {
text-align: center;
}
#images {
width: 400px;
height: 250px;
/*overflow: hidden; if this is set absolute positioning of images breaks*/
position: relative;
background-color: red;
margin: 20px auto;
}
#images img {
width: 400px;
height: 250px;
display: block;
position: absolute;
top: 0px;
left: 400px;
z-index: 1;
opacity: 0;
transition: all linear 500ms;
-o-transition: all linear 500ms;
-moz-transition: all linear 500ms;
-webkit-transition: all linear 500ms;
}
#images img:target {
top: 0px;
left: 0px;
z-index: 9;
opacity: 1;
}
#slider a {
text-decoration: none;
background: #E3F1FA;
border: 1px solid #C6E4F2;
padding: 4px 6px;
color: #222;
}
#slider a:hover {
background: #C6E4F2;
}

This puzzle kept me going. I just couldn't leave it be.
So last evening I was fiddling with it, but couldn't fix it (untill just yet :) ).
Testcase 1
While simplifying things I removed the opacity from the image-elements and left only 1 image and one link. I've set the image to 390px initially so that I can make sure that it is at that position (you can see just a little bit of the left of it).
http://codepen.io/anon/pen/tpCrc
Conclusion:
So what's important to notice is that fact that the image initially is there where it should be.
Then when clicking button 1 you can see it simply skips the transition.
So the browser doesn't change the position of the element, because of overflow:hidden (like the title of this post suggests). It goes to the position mentioned in the CSS (in the :target part), but without the transition.
Testcase 2
Then I got wondering why the browser would act that way and I kept thinking that maybe the focussing of the image element had something to do with it.
If you think about it: when clicking one of the buttons you add #target to the URL of the page and browser then tries to "scroll" to that element. To that, that element has to be visisble.
So I wondered: maybe the CSS has nothing to do with it. Let's try:
so I completely removed the :target-part and the transitions.
http://codepen.io/anon/pen/IvfBE
Conclusion:
Wow! What do we see there? When clicking one of the buttons the image still jumps to left:0 !!
I think we got a lead there.
Still though, I didn't know how to actually fix that. Still seems like a browser-bug to me.
The fix
Then - after a good night of sleep - I woke up with a fresh new idea.
What if we don't actually target the element we want to transition?
So I added a container to each image-element and target that instead.
<div id="images">
<div id="img1container"><img id="image1" src="http://i.imgur.com/dL3io.jpg" /></div>
<div id="img2container"><img id="image2" src="http://i.imgur.com/qASVX.jpg" /></div>
<div id="img3container"><img id="image3" src="http://i.imgur.com/fLuHO.jpg" /></div>
<div id="img4container"><img id="image4" src="http://i.imgur.com/5Sd3Q.jpg" /></div>
</div>
<div id="slider">
1
2
3
4
</div>
In the CSS the position of the image now has to be changed by "[parentElement]:target img" instead.
body {
text-align: center;
}
#images {
width: 400px;
height: 250px;
overflow: hidden; /* this did break it in the past ;) */
position: relative;
background-color: red;
margin: 20px auto;
}
#images img {
width: 400px;
height: 250px;
display: block;
position: absolute;
top: 0px;
left: 400px;
z-index: 1;
opacity: 0;
transition: all linear 500ms;
-o-transition: all linear 500ms;
-moz-transition: all linear 500ms;
-webkit-transition: all linear 500ms;
}
#images div:target img {
top: 0px;
left: 0px;
z-index: 9;
opacity: 1;
}
#slider a {
text-decoration: none;
background: #E3F1FA;
border: 1px solid #C6E4F2;
padding: 4px 6px;
color: #222;
}
#slider a:hover {
background: #C6E4F2;
}
And the working example:
http://codepen.io/anon/pen/lyzhi
Conclusion:
Yay!! Indeed, by not putting focus on the element you want to transition, it doesn't break.
So, you've got your fix there, but it still seems like a browser/engine-bug to me.
So I'd suggest you create a bugreport somewhere (if you've got time).
BTW: I've tested this in Chrome and IE - both the latest versions only. You might want to test this in Firefox and maybe some other browsers.

Related

CSS Hover Images [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm working on a site for some old guys who love cars. They're previous photo gallery is no longer in service and they asked me if I could make a new one. I wanted it as simple as I could make it. And so I made a table of images, that are small. Once you hover the mouse over an image it becomes larger, these guys told me they liked my idea. If you click on the image it will go straight to the image URL.
The problem is the transition from the original size to the larger one makes this glitchy look over the hover. I would like the transition to be smoother, any suggestions?
Here's the link to the site - http://tcrgv8club.org/photogallery.php
Here's my CSS code:
.model img{
width: 125px;
height: 100px;
border: 2px solid black;
z-index: 0;
}
img:hover {
width: 500px;
height: 450px;
z-index:1;
position: absolute;
}
.model td{
padding: 10px;
}
I would recommend using transform: scale as changing width/height will break your layout flow.
.model img {
width: 125px;
height: 100px;
border: 2px solid black;
position: relative;
transition: z-index 0s, transform 0.5s;
}
img:hover {
z-index: 1;
transform: scale(2.5);
}
<div class="model">
<img src="http://placehold.it/100x100" alt="">
<img src="http://placehold.it/100x100" alt="">
<img src="http://placehold.it/100x100" alt="">
</div>
img.thumbnail {
max-width:20%;
max-height:50%;
-webkit-transition: width 2s, height 2s, -webkit-transform 0.5s;
/* For Safari 3.1 to 6.0 */
transition: width 2s, height 2s, transform 0.5s;
}
img.thumbnail:hover {
-webkit-transform:scale(2);
/* Safari and Chrome */
-moz-transform:scale(2);
/* Firefox */
-ms-transform:scale(2);
/* IE 9 */
-o-transform:scale(2);
/* Opera */
transform:scale(2);
}
Fiddle
Changing the position to relative solved it for me, I'm sure the other answers would of worked as well. I'll see what the guys think. Thank you all!
.model img{
width: 125px;
height: 100px;
border: 2px solid black;
z-index: 0;
-webkit-transition: width 2s, height 2s;
transition: width 2s, height 2s;
}
img:hover {
width: 550px;
height: 450px;
z-index:1;
position: relative;
}
.model td{
padding: 10px;
}
Otherwise this answer doesnt change the layout of the table, which I preffered the best.
.model img {
width: 125px;
height: 100px;
border: 2px solid black;
position: relative;
transition: z-index 0s, transform 0.5s;
}
img:hover {
z-index: 1;
transform: scale(2.5);
}

CSS button not working in Google Chrome?

I'm working on a home page for a film company's website, and it has a CSS button with a hover effect that is going to open a lightbox once it's ready, at the moment I just have it set to href="#" as a placeholder until I'm ready to implement the lightbox. There is also a small image of a downward pointing arrow, with the link set to an anchor that isn't on the page yet. Both of these work in Firefox, but in Chrome the hover effect doesn't work on the button, and it behaves as if neither of these elements have anchor tags around them. I poked around with Chrome's dev tools and it seems as though the span around the button may be the culprit as Chrome seems to be resizing it, but I can't figure out any reason why the image link isn't working, and I'm not entirely sure why Chrome is disagreeing with the span.
The strange part is that there are three other CSS buttons with hover effects in a seperate div, and they all work just fine.
The website is currently uploaded at http://www.gruntwork.us/reelindi/test/
The style sheet can be found at http://www.gruntwork.us/reelindi/test/reelindi.css
CSS:
div.header {
position:absolute;
top: 0;
left: 0;
right: 0;
background-image:url("resources/images/bg.jpg");
background-size:cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
height:430px;
width:100%;
z-index: -1;
}
img.arrow {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 58px;
z-index: 999;
}
span.redBtn a {
text-align:center;
display:block;
margin: 0 auto;
width: 150px;
margin-top: -40px;
z-index: 999;
}
a.redBtn {
color: #fff;
background-color: #d94d4d;
font-size: 1.125em;
padding: 8px 18px;
text-decoration: none;
text-align: center;
-webkit-transition: all ease 1s;
-moz-transition: all ease 1s;
-o-transition: all ease 1s;
-ms-transition: all ease 1s;
transition: all ease 1s;
border-radius: 5px;
}
a.redBtn:hover {
background-color: #bf3030;
}
HTML:
<div class="header">
<h1 class="header">Reel Indi</h1>
<h2 class="header">"Storytelling in motion."</h2><br>
<span class="redBtn">Push the red button!</span>
<img class="arrow" src="resources/images/arrow.png">
</div>
I've searched around but can't find an answer for this. Help?
Seems like your header's z-index: -1 rule pushes everything "behind" the body content, causing you not to be able to receive mouse events on that layer. Changing it to zero or higher will let you have hover effects and other events just fine.

Jagged "border" showing due to background colour on wrapper element with border-radius: 50%;

As I was in the process of trying to make an animated figure (transitions on hover), I found out that the background of my <figure> is showing near the edges when I apply border-radius: 50% to it, even though my image should be taking up all available space.
For a quick demo that illustrates the problem, please look at http://codepen.io/anon/pen/KwMMKz
HTML
<figure>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
CSS
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover img {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}
Please note: I know that placing the background-color on figure:hover is a work-around, but I am more interested in the reason why this "jagged border"-like look is appearing.
My guess is that it has to do with AA rendering (or something related) of the browser and that it treats theĀ <figure> element differently than a media element such as <img>, but I can't find any proof of this online. Is this a bug, is it a "feature", or is it something I can actually fix?
Lastly, I also know that I could have used transform: translateY(); here for the animation, but that's not part of my question so please don't provide it as an answer.
UPDATE 17/12 14:03
It appears that this issue is not exclusive to border-radius: 50%. The issue can occur when any wrapping element uses border-radius in combination with overflow: hidden, when the wrapper contains content that is equal or bigger than the wrapper's dimensions.
UPDATE 17/12 14:14
Neither the usage of overflow: hidden on the wrapper element, nor the usage of border-radius on the contained image (or any other child element) seem to be the cause of this as they can be interchanged and the pixelated edge will still appear.
This seems to indicate that this issue is solely caused by 2 DOM elements being in exactly the same place, when any sort of border-radius is applied to the wrapper element and the visible area of the child is limited to that of the parent's.
I've been having same issue and ended up using pseudo element instead of background, kinda like that:
figure::before {
content: '';
display: block;
background-color: red;
width: 400px;
height: 400px;
transform: scale(0.997);
border-radius: 50%;
}
This allowed me to create 'pseudo background' which I later shrinked a little bit with transform: scale(0.997); so it will be just the same size but a bit below visible edge. Of course in your case you would also need to position image absolutely so it is not pushed below by this ::before.
It appears that it is indeed a "feature" of how the browser handles border-radius to give a smooth edge to the rounded corners of a container. The image background is anti-aliased in the same way (but as it is transparent has no effect) as can be seen by setting the img background color.
When the border is anti-aliased it "bleeds" into the background to soften the edges and so you are seeing that around the image as a "jaggy" ring in much the same way you would see a corona around the moon during a full solar eclipse.
the issue is always there, whether the anti-aliased object is covered or not, if you were to draw a circle then anti-alias it, you would see the circle is marginally narrower than the anti-aliased version. Most anti-aliasing algorithms aggregate the surrounding pixels of the object rather than those contained within it.
To overcome it, you'd either need to make your image large enough to cover the space taken up by the anti-aliased edge or reduce the container such that the anti-aliased area is smaller than the image.
You could add a new tag with an opacity of 0 then have that fade in with the image fading out.
figure {
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
background {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
opacity: 0;
position: fixed;
z-index: 5;
transition: opacity 1s ease-out;
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
position: relative;
z-index: 100;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
z-index: 10000;
}
figure:hover img {
opacity: 0;
}
figure:hover background {
opacity: 1;
}
figure:hover figcaption {
top: 50%;
}
<figure>
<background></background>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
Notice I added the background tag and removed background-color from figure
http://codepen.io/marczking/pen/KwMgaR
So after playing around (used background-image and pseudo-elements, changes nothing...) you notice that this light border is only visible if you apply round corners. So I am assuming here it has to do how the Browser renders the CSS, nothing wrong with the CSS-rules ^^)
<figure>
<figcaption>Demo</figcaption>
</figure>
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 100px;
position: relative; /* For caption */
}
figure::before {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: url("http://placehold.it/400x400") no-repeat;
border-radius: 100px; /* Forced on image for smooth transition */
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover::before {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}

rollover over image, different image appears below

I'm trying to make a grid of images that once you hover over one, it's webpage title appears below it, as well as the other images around it changing in opacity.
I have managed to create the opacity mouseover effect I want, but now I'm having trouble making the page heading images appear as you hover over the corresponding image. I hope that makes sense
Hope someone can help. Here is my code
HTML:
<div style="position: relative; left: 140px; top: 0px;">
<img src="window.jpg" style="position: relative; top: 0; left: 0;"/>
<div id="windowimages">
<a class="image-one"></a><a href="https://example-site.com/music/">
<img src="pic1.jpg/>
<a class="image-two"></a><a href="https://example-site.com/dance/">
<img
src="pic2.jgp"/>
<a class="image-three"></a><a href="https://example-site.com/art/">
<img
src="pic3.jpg" />
<a class="image-four"></a><a href="https://example-site.com/aboutus/">
<img
src="pic4.jpg"/>
</div>
CSS:
body {
}
#windowimages {
position: absolute;
left: 3px;
top: 4px;
font-size: 0;
width: 198px;
margin: 0 auto;
padding:1px;
overflow:hidden
}
#windowimages img {
width:90px;
height:90px;
margin: 3px;
cursor:pointer;
-webkit-transition:opacity 0.26s ease-out;
-moz-transition:opacity 0.26s ease-out;
-ms-transition:opacity 0.26s ease-out;
-o-transition:opacity 0.26s ease-out;
transition:opacity 2s ease-in-out;
}
#windowimages:hover img {
opacity:0.55;
}
#windowimages:hover img:hover {
opacity:1;
}
If I understood you correctly, it seems like what you want to do is add a title to each image on hover.
Check out this example I wrote: http://jsfiddle.net/arthurcamara/chbsL3pq/
The key part to adding the title was .image:hover:after as you can see above and in the code below:
.grid:hover .image:hover:after {
display: block;
position: absolute;
top: 5px;
width: 90px;
padding: 5px;
content: attr(data-title);
text-align: center;
background-color: #333;
color: #fff;
}
I changed your markup a bit as well to make it more semantic. Check out the example and let me know if that helped :)

Animation stop with css3

At the moment i am working on a header with a slider animation (css3 only):
http://jimmytenbrink.nl/slider/
Everything is working fine except sometimes the slider is bugging if you go from the center to the right. It seems that i need to stop the animation for a few miliseconds to complete. However i searched everywhere on the internet but i cant seem to get it to work.
Anyone here has experience with it who can help me out?
HTML
<header>
<div><span>slide 1</span></div>
<div><span>slide 2</span></div>
<div><span>slide 3</span></div>
<div><span>slide 4</span></div>
<div><span>slide 5</span></div>
<div><span>slide 6</span></div>
<div><span>slide 7</span></div>
<div><span>slide 8</span></div>
</header>
CSS
header {
margin-top: 10px;
width: 800px;
overflow: hidden;
height: 500px;
}
header div {
background-color: #000;
width: 43.8px;
height: 200px;
position: relative;
float: left;
-webkit-transition: width .3s;
transition: width .3s;
overflow: hidden;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
margin-right: 2px;
}
header div:first-child {
margin-left: 0px;
}
header div:last-child {
margin-right: 0px;
}
header div:hover span {
left: 50px;
opacity: 1;
}
header div img {
position: relative;
left: -240px;
-webkit-transition: all .3s;
transition: all .3s;
-webkit-filter: grayscale(1);
overflow:hidden;
}
header div span {
-webkit-transition: left .3s;
transition: left .3s;
position: absolute;
bottom: 30px;
color: white;
left: -350px;
opacity: 0;
width: 450px;
font-family:'Fugaz One', cursive;
text-transform: uppercase;
font-size: 24px;
color: #fff;
text-shadow: 0px 0px 10px #f1f1f1;
filter: dropshadow(color=#f1f1f1, offx=0, offy=0);
}
header:hover > div {
width: 43.8px;
}
header:hover > div:hover {
width: 150px;
}
Here is a JSFiddle
So the question is, how can i set a stop on the animation for a few miliseconds so the animation can finish before it gets triggered again?
Hope my question is clear!
(thanks for the edit)
One might call my answer a workaround. Maybe it is but according to my comment on ExtPro's answer - it is still completely pure CSS.
I decided to use display: table-cell since the table cell's width is distributed equally.
So, the CSS might look like this:
HINT: This is only a bunch of necessary CSS. All the code is in the jsFiddle
header {
width: 368px;
display: table;
overflow: hidden;
}
header > div {
width: 44px;
height: 200px;
position: relative;
-webkit-transition: width .3s;
transition: width .3s;
display: table-cell;
overflow: hidden;
}
header > div:hover {
width: 151px;
}
Fiddle
As you can see, we don't have to determine the width of all not-hovered divs. Actually, the problem came from that very CSS rule:
/* DON'T USE THIS RULE - IT'S THE RULE WHICH WAS BAD */
header:hover > div {
width: 43.8px;
}
You were changing the width of the divs on header:hover, so when the transition didn't manage to do its job in time, you came out with mouse pointing to the header but to non of the divs.
If I understand what you mean by 'bugging', what is happening is if you move the mouse quickly to the right, it traverses the currently open div and is left in an area which when that div collapses, does not contain (e.g. the mouse is not hovered over) the next one in order to expand it- namely the hover event of the following div(s) is/are not firing thus they do not expand. There wont be a CSS fix for this Im afraid as its browser related, you may want to replace with jQuery/JS.

Resources