I've come across a strange bug in Safari browser rendering.
When I hover over element (green .hover) which makes its child element (pink .pop) visible, the child stays visible even after the hover has ended. It's visible but not selectable - I can select text "behind" the child element as you can see in the screenshot below.
HTML:
<div class="hover">
Hover me! (display)
<div class="pop pop--display">
I will cover your content in Safari indefinitely
</div>
</div>
<div class="content">
Content
</div>
CSS:
.hover {
position: relative;
overflow: hidden;
}
.pop {
position: absolute;
top: 80%;
left: 10px;
}
.hover:hover {
overflow: visible;
}
.pop--display {
display: none;
}
.hover:hover .pop--display {
display: block;
}
It seems to be caused by changing overflow hidden/visible of the parent element together with changing of display none/block (or visibility hidden/visible) of the child element. I came across this bug using JavaScript but mere CSS :hover can reproduce it.
Tested on Safari 8.0.6 (10600.6.3) and 9.0.1 (11601.2.7.2).
/* basic styling and formating */
.hover {
padding: 10px 0;
width: 200px;
background: green;
}
.pop {
padding: 20px;
height: 90px;
width: 140px;
background: pink;
}
.content {
width: 200px;
padding-top: 20px;
height: 100px;
background: grey;
}
.test + .test {
margin-top: 30px;
}
/* overflows and positioning */
.hover {
position: relative;
overflow: hidden;
}
.pop {
position: absolute;
top: 80%;
left: 10px;
}
.hover:hover {
overflow: visible;
}
/* variations */
.pop--display {
display: none;
}
.hover:hover .pop--display {
display: block;
}
.pop--visibility {
visibility: hidden;
}
.hover:hover .pop--visibility {
visibility: visible;
}
<div class="test">
<div class="hover">
Hover me! (default)
<div class="pop">
I will cover your content in Safari indefinitely
</div>
</div>
<div class="content">
Content
</div>
</div>
<div class="test">
<div class="hover">
Hover me! (display)
<div class="pop pop--display">
I will cover your content in Safari indefinitely
</div>
</div>
<div class="content">
Content
</div>
</div>
<div class="test">
<div class="hover">
Hover me! (visibility)
<div class="pop pop--visibility">
I will cover your content in Safari indefinitely
</div>
</div>
<div class="content">
Content
</div>
</div>
The only solution I could came to is to use opacity with pointer-events. I expect opacity: 0; pointer-events: none to act the same way as visibility: hidden.
But I'm still not sure if this is a right approach...
The corresponding CSS is:
.pop--opacity {
opacity: 0;
pointer-events: none;
}
.hover:hover .pop--opacity {
opacity: 1;
pointer-events: auto;
}
/* basic styling and formating */
.hover {
padding: 10px 0;
width: 200px;
background: green;
}
.pop {
padding: 20px;
height: 90px;
width: 140px;
background: pink;
}
.content {
width: 200px;
padding-top: 20px;
height: 100px;
background: grey;
}
.test + .test {
margin-top: 30px;
}
/* overflows and positioning */
.hover {
position: relative;
overflow: hidden;
}
.pop {
position: absolute;
top: 80%;
left: 10px;
}
.hover:hover {
overflow: visible;
}
.pop--opacity {
opacity: 0;
pointer-events: none;
}
.hover:hover .pop--opacity {
opacity: 1;
pointer-events: auto;
}
<div class="test">
<div class="hover">
Hover me! (opacity)
<div class="pop pop--opacity">
I will cover your content in Safari indefinitely
</div>
</div>
<div class="content">
Content
</div>
</div>
Related
I'm trying to recreate the popup from the bottom of this page: https://www.redsquareagency.com/
I'm having trouble with my version. The hover property only activates on the top part of my hidden div because there is an unordered list positioned on top of it. This list blocks the cursor from activating the hover effect.
Also, when the hidden div partially shows itself on hover, it pushes the whole page up. Is there a more elegant solution than changing the div height on hover so it would look more like the one from the reference website?
/* Wrapper to partially hide bottom popup */
#hidden {
position: relative;
height: 45px;
overflow: hidden;
}
#popup {
position: absolute;
overflow: hidden;
margin: 0 50px 0;
}
#popup img {
max-width: 100%;
max-height: 100%;
border-radius: 5px;
filter: blur(3px);
}
#popup img:hover {
filter: blur(0);
transform: scale(1.1);
}
#hidden:hover {
height: 70px;
}
/* Bottom pop-up box text links */
#popup nav ul {
position: absolute;
top: 0;
width: 100%;
margin-top: 5px;
padding: 0;
display: flex;
justify-content: space-between;
font-size: 23px;
}
<div id="hidden">
<div id="popup">
<img src="https://via.placeholder.com/100" alt="popup box image" />
<nav>
<ul>
<li>All Projects</li>
<li>Work ></li>
</ul>
</nav>
</div>
</div>
You can change the properties of a child element by :hover or other action selectors on the parent element as in: #popup:hover img { ...
body,
html {
margin: 0
}
.contents{
line-height:2em;
}
/* Wrapper to partially hide bottom popup */
#hidden {
position: relative;
height: 100px;
overflow: hidden;
}
#popup {
position: absolute;
bottom: 0;
overflow: hidden;
transform: translateY(30px);
transition: transform .5s ease
}
#popup:hover {
transform: translateY(10px)
}
#popup img {
max-width: 100%;
max-height: 100%;
border-radius: 5px;
filter: blur(3px);
transition: all .5s ease
}
#popup:hover img {
filter: blur(0);
transform: scale(1.1);
}
/* Bottom pop-up box text links */
#popup nav ul {
position: absolute;
top: 0;
width: 100%;
margin-top: 5px;
padding: 0;
display: flex;
justify-content: space-between;
font-size: 23px;
}
<div class="contents">
contents<br />
contents<br />
contents<br />
contents<br />
contents Last Row<br />
</div>
<div id="hidden">
<div id="popup">
<img src="https://placekitten.com/g/600/100" alt="popup box image" />
<nav>
<ul>
<li>All Projects</li>
<li>Work ></li>
</ul>
</nav>
</div>
</div>
This is my solution, hope it can help you:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
}
body {
background-color: #111111;
display: grid;
grid-template-rows: 1fr auto;
min-height: 100%;
color: #fff;
}
main {
padding: 2rem;
}
footer {
height: 20vh;
padding: 15px 0 0;
overflow: hidden;
}
footer .box {
width: 80%;
background: crimson;
height: 500px;
margin-inline: auto;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.135, 0.805, 0.305, 0.905);
}
footer .box img {
width: 100%;
filter: blur(10px);
}
footer a:hover .box {
transform: translateY(-15px);
}
footer a:hover .box img {
filter: blur(0);
}
<main>
</main>
<footer>
<a href="">
<div class="box">
<img src="https://images.prismic.io/red-square-site/7ee825e0906b2918e50a9f963c50198b5c26b27d_flip-thumb.jpg" alt="">
</div>
</a>
</footer>
So I have an element that I want to show a tooltip for. But of course, to show this tooltip, I need to make it go above everyhing, no matter what (including overflow: hidden parents). Right now I'm making this happen with the :hover::after rule, but the element's been hidden beneath siblings with a backdrop-filter: blur(...) style.
Minimal reproducable example:
.nephew {
backdrop-filter: blur(10px);
background-color: #0005;
width: 100px;
height: 100px;
}
.nephew.tooltip {
position: relative;
}
.tooltip:hover::after {
content: 'This is a very long tooltip';
background-color: white;
z-index: 999999999;
position: absolute;
width: max-content;
}
.main {
display: flex;
}
<div class="main">
<div class="nephew"></div>
<div class="nephew tooltip"></div>
<div class="nephew"></div>
</div>
Please tell me how to fix this problem. I'm also open to new solutions, since I'm aware this is a bodgy way of implementing this feature.
You need to bring the container div forward too and not just the pseudo element.
Include this CSS and it should now work fine:
.nephew:hover {
z-index: 99999999;
}
Updated example:
.nephew {
backdrop-filter: blur(10px);
background-color: #0005;
width: 100px;
height: 100px;
}
.nephew:hover {
z-index: 99999999;
background-color: #0004; /* just added this to highlight the container */
}
.nephew.tooltip {
position: relative;
}
.tooltip:hover::after {
content: 'This is a very long tooltip';
background-color: white;
z-index: 999999999;
position: absolute;
width: max-content;
}
.main {
display: flex;
}
<div class="main">
<div class="nephew"></div>
<div class="nephew tooltip"></div>
<div class="nephew"></div>
</div>
One approach to solving this might be to apply to the ::after pseudo-element something like:
transform: translateY(-24px)
to raise the tooltip above the row of squares so that it isn't automatically truncated by the next square in the row.
Working Example:
.main {
display: flex;
width: 600px;
margin-top: 24px;
}
.nephew {
position: relative;
width: 100px;
height: 100px;
background-color: rgb(0, 0, 127);
}
.nephew.tooltip {
background-color: rgb(63, 63, 127);
}
.nephew::after {
content: '';
position: absolute;
top: 0;
left: 0;
background-color: white;
white-space: nowrap;
}
.nephew.tooltip:hover::after {
content: 'This is a very long tooltip';
transform: translateY(-20px);
}
<div class="main">
<div class="nephew tooltip"></div>
<div class="nephew"></div>
<div class="nephew tooltip"></div>
<div class="nephew"></div>
<div class="nephew tooltip"></div>
<div class="nephew"></div>
</div>
I've made a responsive image grid and am trying to add a hover effect to it so that the image gets a dark overlay and some text fades in on it. However, I've been having a tough time implementing it.
Here's my HTML structure.
<div class="tile">
<img src="some_image" class="animate">
<div class="overlay">
<p>Mahatma Gandhi</p>
</div>
And here's my CSS
.gallery .row .tile:hover ~ .tile img {
transform: scale(1.2);
}
However upon hovering over the image, it does not have the expected behaviour.
What's wrong?
EDIT
I got the hover effect to work and I can now fade in text.
Here's my code for that:
<div class="tile">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Tagore_Gandhi.jpg/220px-Tagore_Gandhi.jpg" class="animate">
<div class="overlay">
<div class="text">Mahatma Gandhi</div>
</div>
</div>
CSS
.tile {
position: relative;
width: 100%;
}
.image {
display: block;
width: 100%;
height: auto;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: rgba(0, 0, 0, 0.8);
}
.tile:hover .overlay {
opacity: 1;
}
This seems to work but I think it doesnt have a certain "feel" to it. So I need to add a scale effect to the image. How can I do that
Here is a jsFiddle that i think will help you to resolve your issue: https://jsfiddle.net/mcs3yn1x/
HTML
<div class="tile">
<img src="https://picsum.photos/200/300" class="animate">
<div class="overlay">
<p>Mahatma Gandhi</p>
</div>
CSS
.tile {
border: 2px solid black;
}
.tile:hover img {
transform: scale(1.2);
}
Edit
After hearing alittle more about your issue I have created the following jsFiddle: https://jsfiddle.net/f1gzonjr/4/
HTML
<div class="tile">
<div class="container">
<img src="https://picsum.photos/200/300" class="animate">
<div class="overlay">
<p>Mahatma Gandhi</p>
</div>
</div>
CSS
.tile {
position: relative;
top: 0px;
left: 0px;
height: 300px;
width: 200px;
overflow: hidden;
border: 2px solid black;
}
.container:hover img{
transform: scale(1.2);
}
.overlay{
position: absolute;
display: none;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
background-color: rgba(0,0,0,0.5);
}
.overlay p {
position: relative;
text-align: center;
color: #fff;
}
.tile:hover .overlay{
display: block;
}
Here is an alternate solution. Not sure if its what you wanted.
.tile:hover img, .tile.hover img {transform: scale(1.2);}
Here is the original answer that I adapted: Change background color of child div on hover of parent div?
-----EDIT-----
To stop it scaling and breaking responsiveness you will need to add a container around the image and then set overflow to none.
HTML:
<div class="tile">
<div class="img-container"><img src="https://ichef.bbci.co.uk/news/660/cpsprodpb/16C0E/production/_109089139_928b0174-4b3f-48ff-8366-d118afa1ed56.jpg" class="animate"></div>
<div class="overlay">
<p>Mahatma Gandhi</p>
CSS:
.img-container{
width: 500px;
height: 500px;
overflow: hidden;
}
.tile:hover img, .tile.hover img {
transform: scale(1.2);
}
See the codepen below for an example
https://codepen.io/jamesCyrius/pen/pooqwwv
Here is a code
.zoom {
padding: 50px;
background-color: green;
transition: transform .2s; /* Animation */
width: 15px;
height: 15px;
margin: 0 auto;
}
.zoom:hover {
transform: scale(1.5); /* (150% zoom - Note: if the zoom is too large, it will go outside of the viewport) */
}
<div class="zoom"></div>
Ive got a product page with a smaller image of the product.
Now I want to show a bigger version of this image with a colored background covering the whole page, while I hover the smaller image.
The problem is, that the bigger image flickers while I move the mouse around.
My CSS:
#zoomed-product-img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(162, 130, 192, 0.8);
z-index: 0;
visibility: hidden;
}
#zoomed-product-img img {
display: block;
margin: auto auto;
}
.productsdetail-image:hover~#zoomed-product-img {
visibility: visible;
}
My HTML:
<div class="productdetails">
<div class="productsdetail-image">
<img src="/assets/images/products/{{page.name}}.png" alt="Produktbild">
</div>
<div class="productsdetail-info">
</div>
<div id="zoomed-product-img">
<img src="/assets/images/products/{{page.name}}.png" alt="Produktbild">
</div>
Can you help me? Maybe my way of thinking is wrong.
I think it flickers because when I show the bigger image, it is above (z index) the small one and I am not hovering the image anymore so it disappears.
I would also love to solve this with javascript, if you can give me any advice.
You need to specify dimensions for the container of the image. This is why it is flickering. I also used display: none; and display:block to hide and show the images.
.productdetails {
position: relative;
}
#zoomed-product-img {
display: none;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}
/* This is the product detail image styles */
.productsdetail-image {
display: block;
height: 200px;
width: 200px;
}
.productsdetail-image:hover img {
display: none;
}
.productsdetail-image:hover + #zoomed-product-img {
display: block;
}
HTML
<div class="productdetails">
<div class="productsdetail-image">
<img src="https://placeimg.com/200/200/animals" alt="Produktbild">
</div>
<div id="zoomed-product-img">
<img src="https://placeimg.com/300/300/animals" alt="Produktbild">
</div>
<div class="productsdetail-info">
</div>
Demo:
http://jsfiddle.net/n07bt46y/
Please check this in full page
$(document).ready(function(){
$('.productsdetail-image img').hover(function() {
$(this).hide();
$('#zoomed-product-img ').show(500);
});
$('#zoomed-product-img .close').click(function(){
$(this).parent().hide();
$('.productsdetail-image img ').show();
});
});
.productsdetail-image img {
width: 150px;
height: auto;
transition: all 0.5s ease;
}
#zoomed-product-img {
display: none;
position: absolute;
width: 100%;
height: 100%;
background-color: red;
}
#zoomed-product-img span.close {
position: absolute;
color: #fff;
cursor: pointer;
top: 20px;
right: 20px;
}
#zoomed-product-img img {
position: absolute;
width: 300px;
height: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: aUto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="productdetails">
<div class="productsdetail-image">
<img src="https://placeimg.com/300/300/animals" alt="Produktbild">
</div>
<div id="zoomed-product-img">
<span class="close">close</span>
<img class="zoom-img" src="https://placeimg.com/300/300/animals" alt="Produktbild">
</div>
<div class="productsdetail-info">
</div>
Are you wanna build something like that? Hoppefully that fiddle can help you
I am trying to build a simple css slider that shows specific text when in the :target state. The text actually appears fine but what's happening is it's just appearing instead of sliding in. I have left:0 set on the parent and the idea being that when the slide id is selected the parent should move to left: -100%/-200%/-300% depending on the slide targeted. Hope this makes sense, markup is below.
Appreciate any advice where I have gone wrong.
.slider__wrapper {
width: 300px;
margin: 50px auto 0 auto;
}
.slider {
position: relative;
overflow: hidden;
}
.slider__inner {
position: relative;
width: 300%;
left: 0;
transition: all .6s;
}
.slider__slides {
float: left;
width: 33.333%;
font-size: 25px;
}
.slider__toggle {
display: inline-block;
margin-right: 10px;
margin-top: 20px;
font-size: 16px;
}
#slide--1 {
background: red;
}
#slide--2 {
background: yellow;
}
#slide--3 {
background: green;
}
#slide--1:target~.slider__inner {
left: 0;
transition: all .6s;
}
#slide--2:target~.slider__inner {
left: -100%;
transition: all .6s;
}
#slide--3:target~.slider__inner {
left: -200%;
transition: all .6s;
}
<div class="slider__wrapper">
<div class="slider">
<div class="slider__inner">
<div class="slider__slides" id="slide--1">
slide 1
</div>
<div class="slider__slides" id="slide--2">
slide 2
</div>
<div class="slider__slides" id="slide--3">
slide 3
</div>
</div>
</div>
<div class="slider__toggle">
01
02
03
</div>
</div>