CSS rotate transform messes up hover on sibling element - javascript

Im trying to implement an overlay on an image element, with a button inside that lets you rotate the image 180 degrees. This works fine until you rotate the image the first time, then the overlay will not show up again or is for some reason behind the image tag, i have tried setting the z-index of the image to -999 but that did not do anything. I need the solution to work on mobile to, so working with onmouseover event listeners wasnt an option for me.
Code Sandbox here
Code:
<div class="relative">
<div class="absolute overlay">
<button id="rotate">Click to Rotate this Image 180 Degrees</button>
</div>
<div>
<img id="image-to-rotate" src="https://picsum.photos/200/300" />
</div>
</div>
import "./styles.css";
document.getElementById("rotate").addEventListener("click", () => {
document.getElementById("image-to-rotate").classList.toggle("rotate");
});
.relative {
position: relative;
height: 300px;
width: 200px;
}
.absolute {
color: white;
position: absolute;
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
width: 100%;
/*invisible by default*/
opacity: 0;
}
.absolute:hover,
.absolute:active {
/*show on hover, also on activate to work on mobile*/
opacity: 1;
}
.rotate {
transform: rotate(180deg);
}

.absolute:hover,
.absolute:active,
.absolute:visited {
/*show on hover*/
opacity: 1;
z-index: 999;
}
I added the visited to your css and the z-index and it stays after you click.

Related

How can I implement JS so that when I hover an image in a gallery it affects every other image except the hovered image?

I am creating an image thumbnail gallery where each thumbnail will be a link to a full size image on another page. So far when a user hovers over an image a red box covers the image using a CSS ::before pseudo class.
.overlay {
position: relative;
display: inline-block;
}
.overlay>img {
vertical-align: middle;
}
.overlay::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: red;
transition: 0.2s ease;
opacity: 0;
}
.overlay:hover::before {
opacity: 1;
}
<div class="overlay"><img src="https://via.placeholder.com/280x280"></div>
<div class="overlay"><img src="https://via.placeholder.com/333x111"></div>
<div class="overlay"><img src="https://via.placeholder.com/111x333"></div>
<div class="overlay"><img src="https://via.placeholder.com/222x222"></div>
<div class="overlay"><img src="https://via.placeholder.com/111x172"></div>
I would like to change the interaction so that when a user hovers on an image, every other image in the gallery (with an 'overlay' class) will be covered by the red box, except for the image being hovered over. This would create a focus on the image being hovered over by covering the other images with red.
It seems Javascript would be the best way to make this work, how can I implement js with what I've already written?
I was also trying out CSS :not pseudo but having trouble making it work.
$('.overlay').hover(fnOver, fnOut)
function fnOver() {
$('.overlay').not(this).addClass('active')
}
function fnOut() {
$('.overlay').not(this).removeClass('active')
}
.overlay {
position: relative;
display: inline-block;
}
.overlay>img {
vertical-align: middle;
}
.overlay::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: red;
transition: 0.5s ease;
opacity: 0;
}
.active::before {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="overlay"><img src="https://via.placeholder.com/280x280"></div>
<div class="overlay"><img src="https://via.placeholder.com/333x111"></div>
<div class="overlay"><img src="https://via.placeholder.com/111x333"></div>
<div class="overlay"><img src="https://via.placeholder.com/222x222"></div>
<div class="overlay"><img src="https://via.placeholder.com/111x172"></div>

Could background-color have different z-index than img?

I need to one image overlap an another. But the second image have background color and I need the first image between the second and second's background-color. It is possible? Already tried to made a new "div class" instead of style="background-color". Now i am stuck with this:
.mainRunner {
position: relative;
}
.firstimage {
position: relative;
z-index: 2;
}
.secondimage {
position: relative;
z-index: 3;
top: -75px;
}
.background {
position: relative;
z-index: 1
}
<div class="firstimage" style="max-width: 1170px;"><img src="" alt="" title="" style="width: 100%;" max-width="1168" height="399" caption="false" /></div>
<div class="background" style="background-color: #f2e5df;">
<div class="secondimage">
<img src="" alt="" title="" />
</div></div>
You can't give certain properties of an element different z-index values. However for certain elements like a div you can use ::before and ::after pseudo elements. And you can set a z-index on those, effectively creating three layers. More information here.
In this case you can create a div with the middle img inside. Then add a ::before and ::after to that div. Giving one a background color and a z-index of -1. And the other a background image and a z-index of 1.
In the example below I also added some margin and a border around the inital div so you can better see what is going on.
.image {
margin: 20px 0 0 20px;
position: relative;
border: 3px solid coral;
width: 200px;
height: 300px;
}
.image::before,
.image::after {
content: '';
display: block;
width: 200px;
height: 300px;
position: absolute;
}
.image::before {
z-index: -1;
background: cornflowerblue;
top: 20px;
left: 20px;
}
.image::after {
z-index: 1;
background: url("https://www.fillmurray.com/200/300");
top: -20px;
left: -20px;
}
<div class="image"><img src="https://www.fillmurray.com/200/300" /></div>
If I understand right what you're trying to achieve, you probably should be placing the images within background div and placing the second image with position: absolute:
<style>
.mainRunner {
position: relative;
}
.firstimage {
position: relative;
z-index: 2;
}
.secondimage {
position: absolute;
z-index: 3;
top: 20px; /* use top and left values to place the image exactly where you want it over the first image */
left: 20px
}
.background {
position: relative;
z-index: 1;
background-color: #f2e5df;
}
</style>
<div class="mainRunner">
<div class="background">
<img src="image1.png" class="firstimage" />
<img src="image2.png" class="secondimage " />
</div>
</div>
It sets the background color as the back-most element, then on top of it the secondimage and the firstimage.
Thank everyone for their ideas. In the end the solution was simple. In the style was the double definition of second image. And the first of them was just partly commented. So my first post working right like this:
.secondimage img{
max-width: 100%;
height: auto;
position: relative;
top: -75px;
margin: 5px;
margin-bottom: 10px;
}
Now just need to find out how to close this question...
Thank you :)
The answer is simply no... there is no way to address a z-index to specifically a background of an element, z-index and all the other CSS properties work on the entire element, not on only its background.
You're going to have to find another way to do this, have you thought of using a div with not content, and the same size of the image, and then just setting a background color to that specific div?

Position absolute turned into position fixed on scroll

In the snippet below, you will see that I have two sections. One green and one blue. Then in the green section, there is a circle icon. Essentially what I am looking for is for the circle icon to be placed where it is currently on page load, but then as the user scrolls, for the icon to change to a fixed position until the blue section is at the top of the screen. Then when the user scrolls back up for the circle icon to do a reverse action and stay fixed until it gets back into its original position.
How can I do this?
#slantWrap {
height: 80vh;
width: 100%;
position: relative;
background: green;
}
#redIcon {
position: absolute;
bottom: 0;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
z-index: 2;
margin: 0;
}
#redIcon img {
height: 90px;
width: auto;
}
#sec {
width: 100%;
height: 400px;
background: blue;
}
<div id="slantWrap">
<div id="redIcon">
<img src="http://www.iconhot.com/icon/png/devine/256/circle.png" alt="icon">
</div>
</div>
<section id="sec"></section>
$(window).scroll(function (e) {
if($(this).scrollTop() >= $('#sec').offset().top - 90){
$('#redIcon').addClass('fixed');
} else {
$('#redIcon').removeClass('fixed');
}
});
So this function fires every time a user scrolls. What the if statement is looking for is, if the second div (Blue background) is 90px from the top of the window, (note that this - 90 is the same height as the image) the add class of fixed if the the #sec div is NOT 90px from the top of the screen then remove the class of fixed. Lastly you will need to add this to your CSS to have a position fixed with the class is added.
#redIcon.fixed{
position:fixed;
top:0px;
}
Working CodePen: https://codepen.io/ben456789/pen/OZPEpG
Hope this helps!

jquery: Remove a <div> stacked above another <div> on mouseenter and restore that <div> on mouseleave

Here's the challenge:
I have two divs layered on top of one another in an HTML file. The top div is mostly transparent using CSS the bottom div has an image as its background. On mouseenter, I want the top div to disappear and on mouseleave I want the top div to come back.
$(document).ready(function() {
$('.dimmer').on('mouseenter', event => {
$(this).hide();
}).on('mouseleave', event => {
$(this).show();
});
});
.experience {
background: url("cmu-110.png") no-repeat center;
height: 110px;
width: 110px;
z-index: 2;
}
.dimmer {
background: rgba(238, 238, 238, .25);
position: relative;
top: -128px;
z-index: 3;
}
<div>
<div class="experience"></div>
<div class="dimmer"></div>
</div>
The jquery code snippet above is in a separate file and called in the html's head.
<head>
<!--- Some head stuff like title, meta, calling css in separate file, etc --->
<!--jquery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="interaction.js"></script>
</head>
Full transparency: I am new to jquery and trying to use it for the first time. Despite working through the full codecademy jquery tutorial, reading w3C school tutorial, searching other stackoverflow posts, and spending more than a reasonable amount of time, I can't seem to get this to work--probably due to a dumb mistake.
Thank you for your help!
I believe a jquery '.on( "mouseout", handler )' on the bottom div should be sufficient to make the top div visible/fade in.
This post should help you: jquery .mouseover() and .mouseout() with fade
If not (if that does not work) what I would do/suggest is:
When mouse enters the top div activate a setTimeout polling functiion or .mouseMove that runs every 1 second or so which checks the mouse position and hide the top div.
If the mouse is not on the bottom div (mousemove) , then display the top div and disable the polling.
You can seach this forum for how to write a setTimeout polling function, etc. If I have some time over the weekend I will give it a whirl...
Trust this helps.
You can set the css visibility property to hidden and visible on mouseenter and mouseleave. I put some space between two divs to make the effect visible clearly.
$(document).ready(function() {
$('.dimmer').on('mouseenter', () => {
$('.dimmer').css("visibility","hidden");
}).on('mouseleave', () => {
$('.dimmer').css("visibility","visible");
});
});
.experience {
background: red;
height: 110px;
width: 110px;
z-index: 0;
}
.dimmer {
background: blue;
position: absolute;
top: -10px;
height: 110px;
width: 110px;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="experience"></div>
<div class="dimmer"></div>
</div>
jQuery(document).ready(function(){
jQuery(".dimmer").on({
mouseenter: function () {
jQuery(this).css('opacity', '0');
},
mouseleave: function () {
jQuery(this).css('opacity', '1');
}
});
});
.experience {
background: url("http://lorempixel.com/400/200/") no-repeat center;
height: 110px;
width: 110px;
z-index: 2;
}
.imparant{
position:relative;
height: 110px;
width: 110px;
}
.dimmer {
background: rgba(238, 238, 238, .25);
position: absolute;
top: 0;
left:0;
right:0;
bottom:0;
z-index: 3;
transition:opacity 320ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="imparant">
<div class="experience"></div>
<div class="dimmer"></div>
</div>
You don't really need to use jQuery or javascript at all for this. You can do it with a single div, a pseudo-element, and a hover style:
.container{
position:relative;
height: 110px;
width: 110px;
background-image: url("https://randomuser.me/api/portraits/men/41.jpg");
}
.container::before{
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.5);
transition: opacity 0.4s;
}
.container:hover::before{
opacity: 0;
}
<div class="container"></div>
If for some reason you wanted to keep the extra divs you could still do it but you'd want to change the CSS hover rule slightly. If you were ok moving the .dimmer before .experience you could just do the hover directly on the .dimmer element:
.dimmer:hover { opacity: 0 }
Otherwise you'd need to use a descendant selector:
.outerDiv:hover .dimmer { opacity: 0 }

Highlighting images on mouse enter

I have 4 images which will be thumbnails for news articles. When the user moves their mouse over one of the images I want it to highlight. I have done this by placing a div of the same size over the image. I then tried to use JQuery to add a class to that div on mouse enter which would make it a slightly see through blue box as shown here.
HTML:
<div class="col-5 parent-center">
<div id="news1" class="news-highlight"></div>
<img src="images/news.jpg" class="news-image"/>
</div>
I know that in the JQuery I use .content as a reference to find the IDs of the news images faster. That does exist I just didn't copy in that far up the code because it would have resulted in a lot of code unrelated to my problem being pasted in.
CSS:
.news-image
{
height: 100%;
width: 90%;
border: solid 2px #14a0dc;
}
.news-highlight
{
height: 100%;
width: 90%;
position: absolute;
background-color: #14a0dc;
opacity: 0.6;
}
JQuery:
function highlightNews(newsDiv)
{
newsDiv.addClass('news-highlight');
}
function unhighlightNews(newsDiv)
{
newsDiv.removeClass('news-highlight');
}
$(document).ready(function()
{
var $content = $('.content');
var $news1 = $content.find('#news-1');
var $news2 = $content.find('#news-2');
var $news3 = $content.find('#news-3');
var $news4 = $content.find('#news-4');
function newsMouse(newsDiv)
{
newsDiv.on('mouseenter', highlightNews(newsDiv)).on('mouseleave', unhighlightNews(newsDiv));
}
newsMouse($news1);
newsMouse($news2);
newsMouse($news3);
newsMouse($news4);
});
Now you're probably crying after seeing my JQuery, I'm trying to learn it on the fly so I don't really know what I'm doing.
Thanks in advance :)
Why don't you make it with pure css without nothing of js?
.news-image
{
height: 100%;
width: 90%;
border: solid 2px #14a0dc;
}
.news-image:hover
{
height: 100%;
width: 90%;
position: absolute;
background-color: #14a0dc;
opacity: 0.6;
}
<div class="col-5 parent-center">
<div id="news1" class="news-highlight"></div>
<img src="images/news.jpg" class="news-image"/>
</div>
you can do this using pure CSS. basically highlighting is nothing but box-shadow or border on the hover.
.news-image:hover{
border:solid 1px red;
}
If you want to use JQuery to do something like this, one option is to use hover and toggleClass
$('.news-image img').hover(function() {
$(this).toggleClass('news-highlight');
});
.news-image {
float: left;
width: 33.3%;
padding: 5px;
box-sizing: border-box;
}
.news-image img{
transition: all 0.3s ease-in;
width: 100%;
}
.news-highlight {
opacity: 0.6;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="news-image">
<img src="http://placehold.it/350x150">
</div>
<div class="news-image">
<img src="http://placehold.it/350x150">
</div>
<div class="news-image">
<img src="http://placehold.it/350x150">
</div>
If I understand what you want correctly, you should just need to change the colour of the div on top of your images when they are hovered on. This can easily be done with CSS. This should work:
.news-highlight
{
background: rgba(51, 153, 255, 0);
}
.news-highlight:hover
{
background: rgba(51, 153, 255, 0.5);
}
This will give the div a semi-transparent blue colour when the user hovers the cursor over it, and the image will show through.
You could also change the images to a greyscale at the same time, which may improve the effect.
EDIT: I should have also stated that you need to change the order of your html to this:
<div class="col-5 parent-center">
<img src="images/news.jpg" class="news-image"/>
<div id="news1" class="news-highlight"></div>
</div>
now the .news-highlight div will appear on top of your img.
Here is jsFiddle how does hover effect work. Practice is the answer! jQuery not required for something this simple
.news-image
{
height: 100%;
width: 90%;
border: solid 2px #14a0dc;
}
.news-image:hover
{
height: 100%;
width: 90%;
position: absolute;
background-color: #14a0dc;
opacity: 0.6;
}

Categories